[RFC v4 01/10] Add initial RISC-V architecture support
Daniel Schultz
d.schultz at phytec.de
Mon Oct 2 03:08:58 PDT 2017
Hi,
On 09/29/2017 02:07 PM, Oleksij Rempel wrote:
> Hi,
>
> hm... mostly looks identical with existing arch
>
> Am 29.09.2017 um 01:12 schrieb Antony Pavlov:
>> Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
>> --
>> TODOs:
>>
>> * split patch;
>> ---
>> arch/riscv/Kconfig | 73 +++++++++++++++++++++++++++++
>> arch/riscv/Makefile | 68 +++++++++++++++++++++++++++
>> arch/riscv/boot/Makefile | 2 +
>> arch/riscv/boot/main_entry.c | 40 ++++++++++++++++
>> arch/riscv/boot/start.S | 74 ++++++++++++++++++++++++++++++
>> arch/riscv/dts/.gitignore | > arch/riscv/dts/Makefile | 9 ++++
>> arch/riscv/dts/skeleton.dtsi | 13 ++++++
>> arch/riscv/include/asm/barebox.h | 1 +
>> arch/riscv/include/asm/bitops.h | 35 ++++++++++++++
>> arch/riscv/include/asm/bitsperlong.h | 10 ++++
>> arch/riscv/include/asm/byteorder.h | 10 ++++
>> arch/riscv/include/asm/common.h | 6 +++
>> arch/riscv/include/asm/elf.h | 11 +++++
>> arch/riscv/include/asm/io.h | 8 ++++
>> arch/riscv/include/asm/mmu.h | 6 +++
>> arch/riscv/include/asm/posix_types.h | 1 +
>> arch/riscv/include/asm/sections.h | 1 +
>> arch/riscv/include/asm/string.h | 1 +
>> arch/riscv/include/asm/swab.h | 6 +++
>> arch/riscv/include/asm/types.h | 60 ++++++++++++++++++++++++
>> arch/riscv/include/asm/unaligned.h | 19 ++++++++
>> arch/riscv/lib/.gitignore | 1 +
>> arch/riscv/lib/Makefile | 9 ++++
>> arch/riscv/lib/ashldi3.c | 28 ++++++++++++
>> arch/riscv/lib/ashrdi3.c | 30 ++++++++++++
>> arch/riscv/lib/asm-offsets.c | 12 +++++
>> arch/riscv/lib/barebox.lds.S | 89 ++++++++++++++++++++++++++++++++++++
>> arch/riscv/lib/dtb.c | 41 +++++++++++++++++
>> arch/riscv/lib/libgcc.h | 29 ++++++++++++
>> arch/riscv/lib/lshrdi3.c | 28 ++++++++++++
>> arch/riscv/lib/riscv_timer.c | 68 +++++++++++++++++++++++++++
>> drivers/of/Kconfig | 2 +-
>> 33 files changed, 791 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
>> new file mode 100644
>> index 000000000..b2f0817ef
>> --- /dev/null
>> +++ b/arch/riscv/Kconfig
>> @@ -0,0 +1,73 @@
>> +config RISCV
>> + bool
>> + select GENERIC_FIND_NEXT_BIT
>> + select HAVE_CONFIGURABLE_MEMORY_LAYOUT
>> + select HAVE_CONFIGURABLE_TEXT_BASE
>> + select GPIOLIB
>> + select OFTREE
>> + select COMMON_CLK
>> + select COMMON_CLK_OF_PROVIDER
>> + select CLKDEV_LOOKUP
>> + default y
>> +
>> +config ARCH_TEXT_BASE
>> + hex
>> + default 0x0
>> +
>> +config GENERIC_LINKER_SCRIPT
>> + bool
>> + default y
>> +
>> +menu "Machine selection"
>> +
>> +choice
>> + prompt "CPU selection"
>> + default CPU_RV_GENERIC
>> +
>> +config CPU_RV_GENERIC
>> + bool "Generic RISC-V"
>> + select CPU_SUPPORTS_32BIT_KERNEL
>> + select CPU_SUPPORTS_64BIT_KERNEL
>> +
>> +endchoice
>> +
>> +config CPU_SUPPORTS_32BIT_KERNEL
>> + bool
>> +config CPU_SUPPORTS_64BIT_KERNEL
>> + bool
>> +
>> +choice
>> + prompt "barebox code model"
>> + default 64BIT
>> +
>> +config 32BIT
>> + bool "32-bit barebox"
>> + depends on CPU_SUPPORTS_32BIT_KERNEL
>> + help
>> + Select this option to build a 32-bit barebox.
>> +
>> +config 64BIT
>> + bool "64-bit barebox"
>> + depends on CPU_SUPPORTS_64BIT_KERNEL
>> + help
>> + Select this option to build a 64-bit barebox.
>> +
>> +endchoice
>> +
>> +config BUILTIN_DTB
>> + bool "link a DTB into the barebox image"
>> + depends on OFTREE
>> +
>> +config BUILTIN_DTB_NAME
>> + string "DTB to build into the barebox image"
>> + depends on BUILTIN_DTB
>> +
>> +endmenu
>> +
>> +source common/Kconfig
>> +source commands/Kconfig
>> +source net/Kconfig
>> +source drivers/Kconfig
>> +source fs/Kconfig
>> +source lib/Kconfig
>> +source crypto/Kconfig
>> diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
>> new file mode 100644
>> index 000000000..4e3318cf1
>> --- /dev/null
>> +++ b/arch/riscv/Makefile
>> @@ -0,0 +1,68 @@
>> +CPPFLAGS += -fno-strict-aliasing
>> +
>> +cflags-y += -fno-pic -pipe
>> +cflags-y += -Wall -Wmissing-prototypes -Wstrict-prototypes \
>> + -Wno-uninitialized -Wno-format -Wno-main -mcmodel=medany
>> +
>> +LDFLAGS += $(ldflags-y)
>> +LDFLAGS_barebox += -nostdlib
>> +
>> +TEXT_BASE = $(CONFIG_TEXT_BASE)
>> +CPPFLAGS += -DTEXT_BASE=$(CONFIG_TEXT_BASE)
>> +
>> +ifndef CONFIG_MODULES
>> +# Add cleanup flags
>> +CPPFLAGS += -fdata-sections -ffunction-sections
>> +LDFLAGS_barebox += -static --gc-sections
>> +endif
>> +
>> +KBUILD_BINARY := barebox.bin
>> +
>> +machdirs := $(patsubst %,arch/riscv/mach-%/,$(machine-y))
>> +
>> +ifneq ($(board-y),)
>> +BOARD := arch/riscv/boards/$(board-y)/
>> +else
>> +BOARD :=
>> +endif
>> +
>> +ifeq ($(KBUILD_SRC),)
>> +CPPFLAGS += -I$(BOARD)/include
>> +else
>> +CPPFLAGS += -I$(srctree)/$(BOARD)/include
>> +endif
>> +
>> +ifeq ($(KBUILD_SRC),)
>> +CPPFLAGS += $(patsubst %,-I%include,$(machdirs))
>> +else
>> +CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs))
>> +endif
>> +
>> +archprepare: maketools
>> +
>> +PHONY += maketools
>> +
>> +ifneq ($(machine-y),)
>> +MACH := arch/riscv/mach-$(machine-y)/
>> +else
>> +MACH :=
>> +endif
>> +
>> +ifneq ($(board-y),)
>> +BOARD := arch/riscv/boards/$(board-y)/
>> +else
>> +BOARD :=
>> +endif
>> +
>> +common-y += $(BOARD) $(MACH)
>> +common-y += arch/riscv/lib/
>> +common-y += arch/riscv/boot/
>> +
>> +common-$(CONFIG_OFTREE) += arch/riscv/dts/
>> +
>> +CPPFLAGS += $(cflags-y)
>> +CFLAGS += $(cflags-y)
>> +
>> +lds-y := arch/riscv/lib/barebox.lds
>> +
>> +CLEAN_FILES += arch/riscv/lib/barebox.lds
>> diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
>> new file mode 100644
>> index 000000000..d6d28ce65
>> --- /dev/null
>> +++ b/arch/riscv/boot/Makefile
>> @@ -0,0 +1,2 @@
>> +obj-y += start.o
>> +obj-y += main_entry.o
>> diff --git a/arch/riscv/boot/main_entry.c b/arch/riscv/boot/main_entry.c
>> new file mode 100644
>> index 000000000..18db86da5
>> --- /dev/null
>> +++ b/arch/riscv/boot/main_entry.c
>> @@ -0,0 +1,40 @@
>> +/*
>> + * Copyright (C) 2016 Antony Pavlov <antonynpavlov at gmail.com>
>> + *
>> + * This file is part of barebox.
>> + * See file CREDITS for list of people who contributed to this project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +
>> +#include <common.h>
>> +#include <memory.h>
>> +#include <asm-generic/memory_layout.h>
>> +#include <asm/sections.h>
>> +
>> +void main_entry(void);
>> +
>> +/**
>> + * Called plainly from assembler code
>> + *
>> + * @note The C environment isn't initialized yet
>> + */
>> +void main_entry(void)
>> +{
>> + /* clear the BSS first */
>> + memset(__bss_start, 0x00, __bss_stop - __bss_start);
>> +
>> + mem_malloc_init((void *)MALLOC_BASE,
>> + (void *)(MALLOC_BASE + MALLOC_SIZE - 1));
>> +
>> + start_barebox();
>> +}
>> diff --git a/arch/riscv/boot/start.S b/arch/riscv/boot/start.S
>> new file mode 100644
>> index 000000000..2fd00f63d
>> --- /dev/null
>> +++ b/arch/riscv/boot/start.S
>> @@ -0,0 +1,74 @@
>> +/*
>> + * Startup Code for MIPS CPU
>> + *
>> + * based on coreboot/src/arch/riscv/bootblock.S
>> + *
>> + * Copyright (C) 2016 Antony Pavlov <antonynpavlov at gmail.com>
>> + *
>> + * This file is part of barebox.
>> + * See file CREDITS for list of people who contributed to this project.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2
>> + * as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +
>> +#include <asm-generic/memory_layout.h>
>> +
>> + .text
>> + .section ".text_entry"
>> + .align 2
>> +
>> +.globl _start
>> +_start:
>> + li sp, STACK_BASE + STACK_SIZE
>> +
>> + # make room for HLS and initialize it
>> + addi sp, sp, -64 /* MENTRY_FRAME_SIZE */
>> +
>> + # poison the stack
>> + li t1, STACK_BASE
>> + li t0, 0xdeadbeef
>> + sw t0, 0(t1)
>> +
>> + # clear any pending interrupts
>> + //csrwi mip, 0
> should be removed.
>
>> + /* copy barebox to link location */
>> +
>> + la a0, _start /* a0 <- _start actual address */
>> + li a1, CONFIG_TEXT_BASE /* a1 <- _start link address */
>> +
>> + beq a0, a1, main_entry
>> +
>> + la a2, __bss_start
>> +
>> +#define LONGSIZE 4
>> +
>> +copy_loop:
>> + /* copy from source address [a0] */
>> + lw t0, LONGSIZE * 0(a0)
>> + lw t1, LONGSIZE * 1(a0)
>> + lw t2, LONGSIZE * 2(a0)
>> + lw t3, LONGSIZE * 3(a0)
>> + /* copy to target address [a1] */
>> + sw t0, LONGSIZE * 0(a1)
>> + sw t1, LONGSIZE * 1(a1)
>> + sw t2, LONGSIZE * 2(a1)
>> + sw t3, LONGSIZE * 3(a1)
>> + addi a0, a0, LONGSIZE * 2
>> + addi a1, a1, LONGSIZE * 2
>> + bgeu a2, a0, copy_loop
>> +
>> + /* Alas! At the moment I can't load main_entry __link__ address
>> + into a0 with la. Use CONFIG_TEXT_BASE instead. This solution
>> + leads to extra cycles for repeat sp initialization. */
>> +
>> + li a0, CONFIG_TEXT_BASE
>> + jalr a0
>> diff --git a/arch/riscv/dts/.gitignore b/arch/riscv/dts/.gitignore
>> new file mode 100644
>> index 000000000..077903c50
>> --- /dev/null
>> +++ b/arch/riscv/dts/.gitignore
>> @@ -0,0 +1 @@
>> +*dtb*
>> diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
>> new file mode 100644
>> index 000000000..f8380b11c
>> --- /dev/null
>> +++ b/arch/riscv/dts/Makefile
>> @@ -0,0 +1,9 @@
>> +BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME))
>> +obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o
>> +
>> +# just to build a built-in.o. Otherwise compilation fails when no devicetree is
>> +# created.
>> +obj- += dummy.o
>> +
>> +always := $(dtb-y)
>> +clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts
>> diff --git a/arch/riscv/dts/skeleton.dtsi b/arch/riscv/dts/skeleton.dtsi
>> new file mode 100644
>> index 000000000..38ead821b
>> --- /dev/null
>> +++ b/arch/riscv/dts/skeleton.dtsi
>> @@ -0,0 +1,13 @@
>> +/*
>> + * Skeleton device tree; the bare minimum needed to boot; just include and
>> + * add a compatible value. The bootloader will typically populate the memory
>> + * node.
>> + */
>> +
>> +/ {
>> + #address-cells = <2>;
>> + #size-cells = <1>;
>> + chosen { };
>> + aliases { };
>> + memory { device_type = "memory"; reg = <0 0 0>; };
> "reg = <0 0>" instead?
>
>> +};
>> diff --git a/arch/riscv/include/asm/barebox.h b/arch/riscv/include/asm/barebox.h
>> new file mode 100644
>> index 000000000..2997587d8
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/barebox.h
>> @@ -0,0 +1 @@
>> +/* dummy */
>> diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
>> new file mode 100644
>> index 000000000..e77ab8320
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/bitops.h
>> @@ -0,0 +1,35 @@
>> +/*
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + *
>> + */
>> +
>> +#ifndef _ASM_BITOPS_H_
>> +#define _ASM_BITOPS_H_
>> +
>> +#include <asm-generic/bitops/__ffs.h>
>> +#include <asm-generic/bitops/__fls.h>
>> +#include <asm-generic/bitops/ffs.h>
>> +#include <asm-generic/bitops/fls.h>
>> +#include <asm-generic/bitops/ffz.h>
>> +#include <asm-generic/bitops/hweight.h>
>> +#include <asm-generic/bitops/fls64.h>
>> +#include <asm-generic/bitops/find.h>
>> +#include <asm-generic/bitops/ops.h>
>> +
>> +#define set_bit(x, y) __set_bit(x, y)
>> +#define clear_bit(x, y) __clear_bit(x, y)
>> +#define change_bit(x, y) __change_bit(x, y)
>> +#define test_and_set_bit(x, y) __test_and_set_bit(x, y)
>> +#define test_and_clear_bit(x, y) __test_and_clear_bit(x, y)
>> +#define test_and_change_bit(x, y) __test_and_change_bit(x, y)
>> +
>> +#endif /* _ASM_BITOPS_H_ */
>> diff --git a/arch/riscv/include/asm/bitsperlong.h b/arch/riscv/include/asm/bitsperlong.h
>> new file mode 100644
>> index 000000000..4641e7e48
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/bitsperlong.h
>> @@ -0,0 +1,10 @@
>> +#ifndef __ASM_BITSPERLONG_H
>> +#define __ASM_BITSPERLONG_H
>> +
>> +#ifdef __riscv64
>> +#define BITS_PER_LONG 64
>> +#else
>> +#define BITS_PER_LONG 32
>> +#endif
>> +
>> +#endif /* __ASM_BITSPERLONG_H */
>> diff --git a/arch/riscv/include/asm/byteorder.h b/arch/riscv/include/asm/byteorder.h
>> new file mode 100644
>> index 000000000..778bb7224
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/byteorder.h
>> @@ -0,0 +1,10 @@
>> +#ifndef _ASM_RISCV_BYTEORDER_H
>> +#define _ASM_RISCV_BYTEORDER_H
>> +
>> +#if defined(__RISCVEB__)
>> +#include <linux/byteorder/big_endian.h>
>> +#else
>> +#include <linux/byteorder/little_endian.h>
>> +#endif
>> +
>> +#endif /* _ASM_RISCV_BYTEORDER_H */
>> diff --git a/arch/riscv/include/asm/common.h b/arch/riscv/include/asm/common.h
>> new file mode 100644
>> index 000000000..bc8a17e30
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/common.h
>> @@ -0,0 +1,6 @@
>> +#ifndef ASM_RISCV_COMMON_H
>> +#define ASM_RISCV_COMMON_H
>> +
>> +/* nothing special yet */
>> +
>> +#endif /* ASM_RISCV_COMMON_H */
>> diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
>> new file mode 100644
>> index 000000000..7134fa058
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/elf.h
>> @@ -0,0 +1,11 @@
>> +#ifndef __ASM_RISCV_ELF_H__
>> +#define __ASM_RISCV_ELF_H__
>> +
>> +#if __SIZEOF_POINTER__ == 8
>> +#define ELF_CLASS ELFCLASS64
>> +#define CONFIG_PHYS_ADDR_T_64BIT
>> +#else
>> +#define ELF_CLASS ELFCLASS32
>> +#endif
>> +
>> +#endif /* __ASM_RISCV_ELF_H__ */
>> diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
>> new file mode 100644
>> index 000000000..3cdea7fca
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/io.h
>> @@ -0,0 +1,8 @@
>> +#ifndef __ASM_RISCV_IO_H
>> +#define __ASM_RISCV_IO_H
>> +
>> +#define IO_SPACE_LIMIT 0
>> +
>> +#include <asm-generic/io.h>
>> +
>> +#endif /* __ASM_RISCV_IO_H */
>> diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
>> new file mode 100644
>> index 000000000..95af87142
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/mmu.h
>> @@ -0,0 +1,6 @@
>> +#ifndef __ASM_MMU_H
>> +#define __ASM_MMU_H
>> +
>> +#define MAP_ARCH_DEFAULT MAP_UNCACHED
>> +
>> +#endif /* __ASM_MMU_H */
>> diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h
>> new file mode 100644
>> index 000000000..22cae6230
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/posix_types.h
>> @@ -0,0 +1 @@
>> +#include <asm-generic/posix_types.h>
>> diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
>> new file mode 100644
>> index 000000000..2b8c51603
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/sections.h
>> @@ -0,0 +1 @@
>> +#include <asm-generic/sections.h>
>> diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
>> new file mode 100644
>> index 000000000..2997587d8
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/string.h
>> @@ -0,0 +1 @@
>> +/* dummy */
>> diff --git a/arch/riscv/include/asm/swab.h b/arch/riscv/include/asm/swab.h
>> new file mode 100644
>> index 000000000..60a90120b
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/swab.h
>> @@ -0,0 +1,6 @@
>> +#ifndef _ASM_SWAB_H
>> +#define _ASM_SWAB_H
>> +
>> +/* nothing. use generic functions */
>> +
>> +#endif /* _ASM_SWAB_H */
>> diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h
>> new file mode 100644
>> index 000000000..ba386ab4c
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/types.h
>> @@ -0,0 +1,60 @@
>> +#ifndef __ASM_RISCV_TYPES_H
>> +#define __ASM_RISCV_TYPES_H
>> +
>> +#ifdef __riscv64
>> +/*
>> + * This is used in dlmalloc. On RISCV64 we need it to be 64 bit
>> + */
>> +#define INTERNAL_SIZE_T unsigned long
>> +
>> +/*
>> + * This is a Kconfig variable in the Kernel, but we want to detect
>> + * this during compile time, so we set it here.
>> + */
>> +#define CONFIG_PHYS_ADDR_T_64BIT
>> +
>> +#endif
>> +
>> +typedef unsigned short umode_t;
>> +
>> +/*
>> + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
>> + * header files exported to user space
>> + */
>> +
>> +typedef __signed__ char __s8;
>> +typedef unsigned char __u8;
>> +
>> +typedef __signed__ short __s16;
>> +typedef unsigned short __u16;
>> +
>> +typedef __signed__ int __s32;
>> +typedef unsigned int __u32;
>> +
>> +#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
>> +typedef __signed__ long long __s64;
>> +typedef unsigned long long __u64;
>> +#endif
>> +
>> +/*
>> + * These aren't exported outside the kernel to avoid name space clashes
>> + */
>> +#ifdef __KERNEL__
>> +
>> +typedef signed char s8;
>> +typedef unsigned char u8;
>> +
>> +typedef signed short s16;
>> +typedef unsigned short u16;
>> +
>> +typedef signed int s32;
>> +typedef unsigned int u32;
>> +
>> +typedef signed long long s64;
>> +typedef unsigned long long u64;
>> +
>> +#include <asm/bitsperlong.h>
>> +
>> +#endif /* __KERNEL__ */
>> +
>> +#endif /* __ASM_RISCV_TYPES_H */
>> diff --git a/arch/riscv/include/asm/unaligned.h b/arch/riscv/include/asm/unaligned.h
>> new file mode 100644
>> index 000000000..aaebc0641
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/unaligned.h
>> @@ -0,0 +1,19 @@
>> +#ifndef _ASM_RISCV_UNALIGNED_H
>> +#define _ASM_RISCV_UNALIGNED_H
>> +
>> +/*
>> + * FIXME: this file is copy-n-pasted from sandbox's unaligned.h
>> + */
>> +
>> +#include <linux/unaligned/access_ok.h>
>> +#include <linux/unaligned/generic.h>
>> +
>> +#if __BYTE_ORDER == __LITTLE_ENDIAN
>> +#define get_unaligned __get_unaligned_le
>> +#define put_unaligned __put_unaligned_le
>> +#else
>> +#define get_unaligned __get_unaligned_be
>> +#define put_unaligned __put_unaligned_be
>> +#endif
>> +
>> +#endif /* _ASM_RISCV_UNALIGNED_H */
>> diff --git a/arch/riscv/lib/.gitignore b/arch/riscv/lib/.gitignore
>> new file mode 100644
>> index 000000000..d1165788c
>> --- /dev/null
>> +++ b/arch/riscv/lib/.gitignore
>> @@ -0,0 +1 @@
>> +barebox.lds
>> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
>> new file mode 100644
>> index 000000000..313363c1a
>> --- /dev/null
>> +++ b/arch/riscv/lib/Makefile
>> @@ -0,0 +1,9 @@
>> +extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += barebox.lds
>> +
>> +obj-y += riscv_timer.o
>> +
>> +obj-$(CONFIG_32BIT) += lshrdi3.o
>> +obj-$(CONFIG_32BIT) += ashldi3.o
>> +obj-$(CONFIG_32BIT) += ashrdi3.o
>> +
>> +obj-$(CONFIG_BUILTIN_DTB) += dtb.o
>> diff --git a/arch/riscv/lib/ashldi3.c b/arch/riscv/lib/ashldi3.c
>> new file mode 100644
>> index 000000000..cbdbcbb6a
>> --- /dev/null
>> +++ b/arch/riscv/lib/ashldi3.c
>> @@ -0,0 +1,28 @@
>> +#include <module.h>
>> +
>> +#include "libgcc.h"
>> +
>> +long long __ashldi3(long long u, word_type b)
>> +{
>> + DWunion uu, w;
>> + word_type bm;
>> +
>> + if (b == 0)
>> + return u;
>> +
>> + uu.ll = u;
>> + bm = 32 - b;
>> +
>> + if (bm <= 0) {
>> + w.s.low = 0;
>> + w.s.high = (unsigned int) uu.s.low << -bm;
>> + } else {
>> + const unsigned int carries = (unsigned int) uu.s.low >> bm;
>> +
>> + w.s.low = (unsigned int) uu.s.low << b;
>> + w.s.high = ((unsigned int) uu.s.high << b) | carries;
>> + }
>> +
>> + return w.ll;
>> +}
>> +EXPORT_SYMBOL(__ashldi3);
>> diff --git a/arch/riscv/lib/ashrdi3.c b/arch/riscv/lib/ashrdi3.c
>> new file mode 100644
>> index 000000000..928d6d97c
>> --- /dev/null
>> +++ b/arch/riscv/lib/ashrdi3.c
>> @@ -0,0 +1,30 @@
>> +#include <module.h>
>> +
>> +#include "libgcc.h"
>> +
>> +long long __ashrdi3(long long u, word_type b)
>> +{
>> + DWunion uu, w> + word_type bm;
>> +
>> + if (b == 0)
>> + return u;
>> +
>> + uu.ll = u;
>> + bm = 32 - b;
>> +
>> + if (bm <= 0) {
>> + /* w.s.high = 1..1 or 0..0 */
>> + w.s.high =
>> + uu.s.high >> 31;
>> + w.s.low = uu.s.high >> -bm;
>> + } else {
>> + const unsigned int carries = (unsigned int) uu.s.high << bm;
>> +
>> + w.s.high = uu.s.high >> b;
>> + w.s.low = ((unsigned int) uu.s.low >> b) | carries;
>> + }
>> +
>> + return w.ll;
>> +}
>> +EXPORT_SYMBOL(__ashrdi3);
>> diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c
>> new file mode 100644
>> index 000000000..22f382b71
>> --- /dev/null
>> +++ b/arch/riscv/lib/asm-offsets.c
>> @@ -0,0 +1,12 @@
>> +/*
>> + * Generate definitions needed by assembly language modules.
>> + * This code generates raw asm output which is post-processed to extract
>> + * and format the required data.
>> + */
>> +
>> +#include <linux/kbuild.h>
>> +
>> +int main(void)
>> +{
>> + return 0;
>> +}
>> diff --git a/arch/riscv/lib/barebox.lds.S b/arch/riscv/lib/barebox.lds.S
>> new file mode 100644
>> index 000000000..9468fb8b5
>> --- /dev/null
>> +++ b/arch/riscv/lib/barebox.lds.S
>> @@ -0,0 +1,89 @@
>> +/*
>> + * Copyright (C) 2016 Antony Pavlov <antonynpavlov at gmail.com>
>> + *
>> + * This file is part of barebox.
>> + * See file CREDITS for list of people who contributed to this project.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2
>> + * as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +
>> +#include <asm-generic/barebox.lds.h>
>> +
>> +OUTPUT_ARCH(riscv)
>> +ENTRY(_start)
>> +SECTIONS
>> +{
>> + . = TEXT_BASE;
>> +
>> + . = ALIGN(8);
>> + .text :
>> + {
>> + _stext = .;
>> + _start = .;
>> + KEEP(*(.text_entry*))
>> + _text = .;
>> + __bare_init_start = .;
>> + *(.text_bare_init*)
>> + __bare_init_end = .;
>> + *(.text*)
>> + }
>> + BAREBOX_BARE_INIT_SIZE
>> +
>> + PRE_IMAGE
>> +
>> + . = ALIGN(8);
>> + .rodata : { *(.rodata*) }
>> +
>> + _etext = .; /* End of text and rodata section */
>> + _sdata = .;
>> +
>> + . = ALIGN(8);
>> + .data : { *(.data*) }
>> +
>> + .barebox_imd : { BAREBOX_IMD }
>> +
>> + . = ALIGN(8);
>> + .got : { *(.got*) }
>> +
>> + . = .;
>> + __barebox_cmd_start = .;
>> + .barebox_cmd : { BAREBOX_CMDS }
>> + __barebox_cmd_end = .;
>> +
>> + __barebox_magicvar_start = .;
>> + .barebox_magicvar : { BAREBOX_MAGICVARS }
>> + __barebox_magicvar_end = .;
>> +
>> + __barebox_initcalls_start = .;
>> + .barebox_initcalls : { INITCALLS }
>> + __barebox_initcalls_end = .;
>> +
>> + __barebox_exitcalls_start = .;
>> + .barebox_exitcalls : { EXITCALLS }
>> + __barebox_exitcalls_end = .;
>> +
>> + __usymtab_start = .;
>> + __usymtab : { BAREBOX_SYMS }
>> + __usymtab_end = .;
>> +
>> + .rela.dyn : { *(.rela*) }
>> +
>> + .oftables : { BAREBOX_CLK_TABLE() }
>> +
>> + .dtb : { BAREBOX_DTB() }
>> +
>> + _edata = .;
>> + . = ALIGN(8);
>> + __bss_start = .;
>> + .bss : { *(.bss*) *(.sbss*) }
>> + __bss_stop = .;
>> + _end = .;
>> +}
>> diff --git a/arch/riscv/lib/dtb.c b/arch/riscv/lib/dtb.c
>> new file mode 100644
>> index 000000000..09f519dcc
>> --- /dev/null
>> +++ b/arch/riscv/lib/dtb.c
>> @@ -0,0 +1,41 @@
>> +/*
>> + * Copyright (C) 2016 Antony Pavlov <antonynpavlov at gmail.com>
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2
>> + * as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +#include <common.h>
>> +#include <init.h>
>> +#include <of.h>
>> +
>> +extern char __dtb_start[];
>> +
>> +static int of_riscv_init(void)
>> +{
>> + struct device_node *root;
>> +
>> + root = of_get_root_node();
>> + if (root)
>> + return 0;
>> +
>> + root = of_unflatten_dtb(__dtb_start);
>> + if (!IS_ERR(root)) {
>> + pr_debug("using internal DTB\n");
>> + of_set_root_node(root);
>> + if (IS_ENABLED(CONFIG_OFDEVICE))
>> + of_probe();
>> + }
>> +
>> + return 0;
>> +}
>> +core_initcall(of_riscv_init);
>> diff --git a/arch/riscv/lib/libgcc.h b/arch/riscv/lib/libgcc.h
>> new file mode 100644
>> index 000000000..593e59802
>> --- /dev/null
>> +++ b/arch/riscv/lib/libgcc.h
>> @@ -0,0 +1,29 @@
>> +#ifndef __ASM_LIBGCC_H
>> +#define __ASM_LIBGCC_H
>> +
>> +#include <asm/byteorder.h>
>> +
>> +typedef int word_type __attribute__ ((mode (__word__)));
>> +#ifdef __BIG_ENDIAN
>> +struct DWstruct {
>> + int high, low;
>> +};
>> +#elif defined(__LITTLE_ENDIAN)
>> +struct DWstruct {
>> + int low, high;
>> +};
>> +#else
>> +#error I feel sick.
>> +#endif
>> +
>> +typedef union {
>> + struct DWstruct s;
>> + long long ll;
>> +} DWunion;
>> +
>> +long long __lshrdi3(long long u, word_type b);
>> +long long __ashldi3(long long u, word_type b);
>> +long long __ashrdi3(long long u, word_type b);
>> +
>> +#endif /* __ASM_LIBGCC_H */
>> diff --git a/arch/riscv/lib/lshrdi3.c b/arch/riscv/lib/lshrdi3.c
>> new file mode 100644
>> index 000000000..74a4846e9
>> --- /dev/null
>> +++ b/arch/riscv/lib/lshrdi3.c
>> @@ -0,0 +1,28 @@
>> +#include <module.h>
>> +
>> +#include "libgcc.h"
>> +
>> +long long __lshrdi3(long long u, word_type b)
>> +{
>> + DWunion uu, w;
>> + word_type bm;
>> +
>> + if (b == 0)
>> + return u;
>> +
>> + uu.ll = u;
>> + bm = 32 - b;
>> +
>> + if (bm <= 0) {
>> + w.s.high = 0;
>> + w.s.low = (unsigned int) uu.s.high >> -bm;
>> + } else {
>> + const unsigned int carries = (unsigned int) uu.s.high << bm;
>> +
>> + w.s.high = (unsigned int) uu.s.high >> b;
>> + w.s.low = ((unsigned int) uu.s.low >> b) | carries;
>> + }
>> +
>> + return w.ll;
>> +}
>> +EXPORT_SYMBOL(__lshrdi3);
>> diff --git a/arch/riscv/lib/riscv_timer.c b/arch/riscv/lib/riscv_timer.c
>> new file mode 100644
>> index 000000000..46181f877
>> --- /dev/null
>> +++ b/arch/riscv/lib/riscv_timer.c
>> @@ -0,0 +1,68 @@
>> +/*
>> + * Copyright (C) 2017 Antony Pavlov <antonynpavlov at gmail.com>
>> + *
>> + * This file is part of barebox.
>> + * See file CREDITS for list of people who contributed to this project.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2
>> + * as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +
>> +/**
>> + * @file
>> + * @brief Clocksource based on RISCV cycle CSR timer
>> + */
>> +
>> +#include <init.h>
>> +#include <of.h>
>> +#include <linux/clk.h>
>> +#include <clock.h>
>> +#include <io.h>
>> +
>> +static uint64_t rdcycle_read(void)
>> +{
>> + register unsigned long __v;
>> +
>> + __asm__ __volatile__ ("rdcycle %0" : "=r" (__v));
>> +
Maybe you should also add support for 32-bit cores.
>> + return __v;
>> +}
>> +
>> +static struct clocksource rdcycle_cs = {
>> + .read = rdcycle_read,
>> + .mask = CLOCKSOURCE_MASK(32),
>> +};
>> +
--
Mit freundlichen Grüßen,
With best regards,
Daniel Schultz
More information about the barebox
mailing list