diff options
Diffstat (limited to 'arch/riscv/include/asm')
28 files changed, 486 insertions, 145 deletions
diff --git a/arch/riscv/include/asm/asm-offsets.h b/arch/riscv/include/asm/asm-offsets.h index d370ee36a1..33db5a47e5 100644 --- a/arch/riscv/include/asm/asm-offsets.h +++ b/arch/riscv/include/asm/asm-offsets.h @@ -1 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #include <generated/asm-offsets.h> diff --git a/arch/riscv/include/asm/barebox-riscv-head.h b/arch/riscv/include/asm/barebox-riscv-head.h index a4c33472cd..4d62c20d1b 100644 --- a/arch/riscv/include/asm/barebox-riscv-head.h +++ b/arch/riscv/include/asm/barebox-riscv-head.h @@ -23,6 +23,7 @@ ".ascii \"" magic2 "\"\n" /* magic 2 */ \ ".word 0\n" /* reserved (PE-COFF offset) */ \ "1:\n" \ + "li fp, 0\n" \ ) #define __barebox_riscv_header(instr, load_offset, version, magic1, magic2) \ diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h index abb3202427..db6ff0ea71 100644 --- a/arch/riscv/include/asm/barebox-riscv.h +++ b/arch/riscv/include/asm/barebox-riscv.h @@ -20,14 +20,8 @@ #include <asm/sections.h> #include <asm/barebox-riscv-head.h> #include <asm/system.h> - -unsigned long get_runtime_offset(void); - -void setup_c(void); -void relocate_to_current_adr(void); -void relocate_to_adr(unsigned long target); - -void sync_caches_for_execution(void); +#include <asm/cache.h> +#include <asm/reloc.h> void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long memsize, void *boarddata, unsigned int flags); diff --git a/arch/riscv/include/asm/barebox.lds.h b/arch/riscv/include/asm/barebox.lds.h new file mode 100644 index 0000000000..0fa05df6ff --- /dev/null +++ b/arch/riscv/include/asm/barebox.lds.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define BAREBOX_OUTPUT_ARCH "riscv" +#ifdef CONFIG_64BIT +#define BAREBOX_OUTPUT_FORMAT "elf64-littleriscv" +#else +#define BAREBOX_OUTPUT_FORMAT "elf32-littleriscv" +#endif + +#include <asm-generic/barebox.lds.h> diff --git a/arch/riscv/include/asm/bitsperlong.h b/arch/riscv/include/asm/bitsperlong.h index 6dc0bb0c13..bf000a04cc 100644 --- a/arch/riscv/include/asm/bitsperlong.h +++ b/arch/riscv/include/asm/bitsperlong.h @@ -1 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #include <asm-generic/bitsperlong.h> diff --git a/arch/riscv/include/asm/byteorder.h b/arch/riscv/include/asm/byteorder.h index 0be826927b..36dfd37524 100644 --- a/arch/riscv/include/asm/byteorder.h +++ b/arch/riscv/include/asm/byteorder.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #ifndef _ASM_RISCV_BYTEORDER_H #define _ASM_RISCV_BYTEORDER_H diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h new file mode 100644 index 0000000000..c787f89001 --- /dev/null +++ b/arch/riscv/include/asm/cache.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2015 Regents of the University of California + */ + +#ifndef _ASM_RISCV_CACHE_H +#define _ASM_RISCV_CACHE_H + +#include <asm/vendorid_list.h> + +static inline void thead_local_flush_icache_all(void) +{ + /* + * According [1] "13.3 Example of cache settings" + * [1]: https://github.com/T-head-Semi/openc906/blob/main/ \ + * doc/openc906%20datasheet.pd + */ + __asm__ volatile (".long 0x0100000b" ::: "memory"); /* th.icache.iall */ + __asm__ volatile (".long 0x01b0000b" ::: "memory"); /* th.sync.is */ +} + +static inline void local_flush_icache_all(void) +{ +#ifdef CONFIG_HAS_CACHE + switch(riscv_vendor_id()) { + case THEAD_VENDOR_ID: + thead_local_flush_icache_all(); + break; + default: + __asm__ volatile ("fence.i" ::: "memory"); + } +#endif +} + +#define sync_caches_for_execution sync_caches_for_execution +void sync_caches_for_execution(void); + +#include <asm-generic/cache.h> + +#endif /* _ASM_RISCV_CACHEFLUSH_H */ diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h deleted file mode 100644 index 9ff25740c6..0000000000 --- a/arch/riscv/include/asm/cacheflush.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2015 Regents of the University of California - */ - -#ifndef _ASM_RISCV_CACHEFLUSH_H -#define _ASM_RISCV_CACHEFLUSH_H - -static inline void local_flush_icache_all(void) -{ -#ifdef HAS_CACHE - asm volatile ("fence.i" ::: "memory"); -#endif -} - -#endif /* _ASM_RISCV_CACHEFLUSH_H */ diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 1a15089cae..8bba809e45 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -13,13 +13,12 @@ /* Status register flags */ #define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */ +#define SR_MIE _AC(0x00000008, UL) /* Machine Interrupt Enable */ #define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */ +#define SR_MPIE _AC(0x00000080, UL) /* Previous Machine IE */ #define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */ -#ifdef CONFIG_RISCV_PRIV_1_9 -#define SR_PUM _AC(0x00040000, UL) /* Protect User Memory Access */ -#else +#define SR_MPP _AC(0x00001800, UL) /* Previously Machine */ #define SR_SUM _AC(0x00040000, UL) /* Supervisor User Memory Access */ -#endif #define SR_FS _AC(0x00006000, UL) /* Floating-point Status */ #define SR_FS_OFF _AC(0x00000000, UL) @@ -33,22 +32,6 @@ #define SR_XS_CLEAN _AC(0x00010000, UL) #define SR_XS_DIRTY _AC(0x00018000, UL) -#ifdef CONFIG_RISCV_PRIV_1_9 -#define SR_VM _AC(0x1F000000, UL) /* Virtualization Management */ -#define SR_VM_MODE_BARE _AC(0x00000000, UL) /* No translation or protection */ -#define SR_VM_MODE_BB _AC(0x01000000, UL) /* Single base-and-bound */ -/* Separate instruction and data base-and-bound */ -#define SR_VM_MODE_BBID _AC(0x02000000, UL) -#ifndef CONFIG_64BIT -#define SR_VM_MODE_32 _AC(0x08000000, UL) -#define SR_VM_MODE SR_VM_MODE_32 -#else -#define SR_VM_MODE_39 _AC(0x09000000, UL) -#define SR_VM_MODE_48 _AC(0x0A000000, UL) -#define SR_VM_MODE SR_VM_MODE_39 -#endif -#endif - #ifndef CONFIG_64BIT #define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */ #else @@ -56,51 +39,127 @@ #endif /* SATP flags */ -#ifndef CONFIG_RISCV_PRIV_1_9 #ifndef CONFIG_64BIT #define SATP_PPN _AC(0x003FFFFF, UL) #define SATP_MODE_32 _AC(0x80000000, UL) #define SATP_MODE SATP_MODE_32 +#define SATP_ASID_BITS 9 +#define SATP_ASID_SHIFT 22 +#define SATP_ASID_MASK _AC(0x1FF, UL) #else #define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL) #define SATP_MODE_39 _AC(0x8000000000000000, UL) #define SATP_MODE SATP_MODE_39 -#endif +#define SATP_ASID_BITS 16 +#define SATP_ASID_SHIFT 44 +#define SATP_ASID_MASK _AC(0xFFFF, UL) #endif -/* SCAUSE */ -#define SCAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1)) +/* Exception cause high bit - is an interrupt if set */ +#define CAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1)) #define IRQ_U_SOFT 0 +/* Interrupt causes (minus the high bit) */ #define IRQ_S_SOFT 1 +#define IRQ_VS_SOFT 2 #define IRQ_M_SOFT 3 #define IRQ_U_TIMER 4 #define IRQ_S_TIMER 5 +#define IRQ_VS_TIMER 6 #define IRQ_M_TIMER 7 #define IRQ_U_EXT 8 #define IRQ_S_EXT 9 +#define IRQ_VS_EXT 10 #define IRQ_M_EXT 11 +/* Exception causes */ #define EXC_INST_MISALIGNED 0 #define EXC_INST_ACCESS 1 +#define EXC_INST_ILLEGAL 2 #define EXC_BREAKPOINT 3 #define EXC_LOAD_ACCESS 5 #define EXC_STORE_ACCESS 7 #define EXC_SYSCALL 8 +#define EXC_HYPERVISOR_SYSCALL 9 +#define EXC_SUPERVISOR_SYSCALL 10 #define EXC_INST_PAGE_FAULT 12 #define EXC_LOAD_PAGE_FAULT 13 #define EXC_STORE_PAGE_FAULT 15 +#define EXC_INST_GUEST_PAGE_FAULT 20 +#define EXC_LOAD_GUEST_PAGE_FAULT 21 +#define EXC_VIRTUAL_INST_FAULT 22 +#define EXC_STORE_GUEST_PAGE_FAULT 23 + +/* PMP configuration */ +#define PMP_R 0x01 +#define PMP_W 0x02 +#define PMP_X 0x04 +#define PMP_A 0x18 +#define PMP_A_TOR 0x08 +#define PMP_A_NA4 0x10 +#define PMP_A_NAPOT 0x18 +#define PMP_L 0x80 + +/* HSTATUS flags */ +#ifdef CONFIG_64BIT +#define HSTATUS_VSXL _AC(0x300000000, UL) +#define HSTATUS_VSXL_SHIFT 32 +#endif +#define HSTATUS_VTSR _AC(0x00400000, UL) +#define HSTATUS_VTW _AC(0x00200000, UL) +#define HSTATUS_VTVM _AC(0x00100000, UL) +#define HSTATUS_VGEIN _AC(0x0003f000, UL) +#define HSTATUS_VGEIN_SHIFT 12 +#define HSTATUS_HU _AC(0x00000200, UL) +#define HSTATUS_SPVP _AC(0x00000100, UL) +#define HSTATUS_SPV _AC(0x00000080, UL) +#define HSTATUS_GVA _AC(0x00000040, UL) +#define HSTATUS_VSBE _AC(0x00000020, UL) + +/* HGATP flags */ +#define HGATP_MODE_OFF _AC(0, UL) +#define HGATP_MODE_SV32X4 _AC(1, UL) +#define HGATP_MODE_SV39X4 _AC(8, UL) +#define HGATP_MODE_SV48X4 _AC(9, UL) + +#define HGATP32_MODE_SHIFT 31 +#define HGATP32_VMID_SHIFT 22 +#define HGATP32_VMID_MASK _AC(0x1FC00000, UL) +#define HGATP32_PPN _AC(0x003FFFFF, UL) + +#define HGATP64_MODE_SHIFT 60 +#define HGATP64_VMID_SHIFT 44 +#define HGATP64_VMID_MASK _AC(0x03FFF00000000000, UL) +#define HGATP64_PPN _AC(0x00000FFFFFFFFFFF, UL) + +#define HGATP_PAGE_SHIFT 12 -/* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */ -#define MIE_MSIE (_AC(0x1, UL) << IRQ_M_SOFT) -#define SIE_SSIE (_AC(0x1, UL) << IRQ_S_SOFT) -#define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER) -#define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT) +#ifdef CONFIG_64BIT +#define HGATP_PPN HGATP64_PPN +#define HGATP_VMID_SHIFT HGATP64_VMID_SHIFT +#define HGATP_VMID_MASK HGATP64_VMID_MASK +#define HGATP_MODE_SHIFT HGATP64_MODE_SHIFT +#else +#define HGATP_PPN HGATP32_PPN +#define HGATP_VMID_SHIFT HGATP32_VMID_SHIFT +#define HGATP_VMID_MASK HGATP32_VMID_MASK +#define HGATP_MODE_SHIFT HGATP32_MODE_SHIFT +#endif + +/* VSIP & HVIP relation */ +#define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT) +#define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \ + (_AC(1, UL) << IRQ_S_TIMER) | \ + (_AC(1, UL) << IRQ_S_EXT)) -#define CSR_FCSR 0x003 +/* symbolic CSR names: */ #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 #define CSR_INSTRET 0xc02 +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 + #define CSR_SSTATUS 0x100 #define CSR_SIE 0x104 #define CSR_STVEC 0x105 @@ -110,40 +169,90 @@ #define CSR_SCAUSE 0x142 #define CSR_STVAL 0x143 #define CSR_SIP 0x144 -#ifdef CONFIG_RISCV_PRIV_1_9 -#define CSR_SPTBR 0x180 -#else #define CSR_SATP 0x180 -#endif + +#define CSR_VSSTATUS 0x200 +#define CSR_VSIE 0x204 +#define CSR_VSTVEC 0x205 +#define CSR_VSSCRATCH 0x240 +#define CSR_VSEPC 0x241 +#define CSR_VSCAUSE 0x242 +#define CSR_VSTVAL 0x243 +#define CSR_VSIP 0x244 +#define CSR_VSATP 0x280 + +#define CSR_HSTATUS 0x600 +#define CSR_HEDELEG 0x602 +#define CSR_HIDELEG 0x603 +#define CSR_HIE 0x604 +#define CSR_HTIMEDELTA 0x605 +#define CSR_HCOUNTEREN 0x606 +#define CSR_HGEIE 0x607 +#define CSR_HTIMEDELTAH 0x615 +#define CSR_HTVAL 0x643 +#define CSR_HIP 0x644 +#define CSR_HVIP 0x645 +#define CSR_HTINST 0x64a +#define CSR_HGATP 0x680 +#define CSR_HGEIP 0xe12 + #define CSR_MSTATUS 0x300 #define CSR_MISA 0x301 #define CSR_MIE 0x304 #define CSR_MTVEC 0x305 -#ifdef CONFIG_RISCV_PRIV_1_9 -#define CSR_MUCOUNTEREN 0x320 -#define CSR_MSCOUNTEREN 0x321 -#define CSR_MHCOUNTEREN 0x322 -#else -#define CSR_MCOUNTEREN 0x306 -#endif #define CSR_MSCRATCH 0x340 #define CSR_MEPC 0x341 #define CSR_MCAUSE 0x342 #define CSR_MTVAL 0x343 #define CSR_MIP 0x344 -#ifdef CONFIG_RISCV_PRIV_1_9 -#define CSR_MBASE 0x380 -#define CSR_MBOUND 0x381 -#define CSR_MIBASE 0x382 -#define CSR_MIBOUND 0x383 -#define CSR_MDBASE 0x384 -#define CSR_MDBOUND 0x385 -#endif -#define CSR_CYCLEH 0xc80 -#define CSR_TIMEH 0xc81 -#define CSR_INSTRETH 0xc82 +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPADDR0 0x3b0 +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 #define CSR_MHARTID 0xf14 +#ifdef CONFIG_RISCV_M_MODE +# define CSR_STATUS CSR_MSTATUS +# define CSR_IE CSR_MIE +# define CSR_TVEC CSR_MTVEC +# define CSR_SCRATCH CSR_MSCRATCH +# define CSR_EPC CSR_MEPC +# define CSR_CAUSE CSR_MCAUSE +# define CSR_TVAL CSR_MTVAL +# define CSR_IP CSR_MIP + +# define SR_IE SR_MIE +# define SR_PIE SR_MPIE +# define SR_PP SR_MPP + +# define RV_IRQ_SOFT IRQ_M_SOFT +# define RV_IRQ_TIMER IRQ_M_TIMER +# define RV_IRQ_EXT IRQ_M_EXT +#else /* CONFIG_RISCV_M_MODE */ +# define CSR_STATUS CSR_SSTATUS +# define CSR_IE CSR_SIE +# define CSR_TVEC CSR_STVEC +# define CSR_SCRATCH CSR_SSCRATCH +# define CSR_EPC CSR_SEPC +# define CSR_CAUSE CSR_SCAUSE +# define CSR_TVAL CSR_STVAL +# define CSR_IP CSR_SIP + +# define SR_IE SR_SIE +# define SR_PIE SR_SPIE +# define SR_PP SR_SPP + +# define RV_IRQ_SOFT IRQ_S_SOFT +# define RV_IRQ_TIMER IRQ_S_TIMER +# define RV_IRQ_EXT IRQ_S_EXT +#endif /* CONFIG_RISCV_M_MODE */ + +/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */ +#define IE_SIE (_AC(0x1, UL) << RV_IRQ_SOFT) +#define IE_TIE (_AC(0x1, UL) << RV_IRQ_TIMER) +#define IE_EIE (_AC(0x1, UL) << RV_IRQ_EXT) + #ifndef __ASSEMBLY__ #define csr_swap(csr, val) \ diff --git a/arch/riscv/include/asm/debug_ll.h b/arch/riscv/include/asm/debug_ll.h index a3b9c1c4bc..34294b09dd 100644 --- a/arch/riscv/include/asm/debug_ll.h +++ b/arch/riscv/include/asm/debug_ll.h @@ -17,20 +17,31 @@ #if defined CONFIG_DEBUG_ERIZO #define DEBUG_LL_UART_ADDR 0x90000000 #define DEBUG_LL_UART_CLK (24000000 / 16) +#define DEBUG_LL_UART_SHIFT 2 +#define DEBUG_LL_UART_IOSIZE32 #elif defined CONFIG_DEBUG_STARFIVE #define DEBUG_LL_UART_ADDR 0x12440000 #define DEBUG_LL_UART_CLK (100000000 / 16) -#endif - #define DEBUG_LL_UART_SHIFT 2 #define DEBUG_LL_UART_IOSIZE32 +#elif defined CONFIG_DEBUG_RISCV_VIRT +#define DEBUG_LL_UART_ADDR 0x10000000 +#define DEBUG_LL_UART_CLK (58982400 / 16) +#define DEBUG_LL_UART_SHIFT 0 +#define DEBUG_LL_UART_IOSIZE8 +#elif defined CONFIG_DEBUG_SUN20I +#define DEBUG_LL_UART_ADDR 0x2500000 +#define DEBUG_LL_UART_CLK (24000000 / 16) +#define DEBUG_LL_UART_SHIFT 2 +#define DEBUG_LL_UART_IOSIZE32 +#endif #define DEBUG_LL_UART_BPS CONFIG_BAUDRATE #define DEBUG_LL_UART_DIVISOR (DEBUG_LL_UART_CLK / DEBUG_LL_UART_BPS) #include <asm/debug_ll_ns16550.h> -#elif defined CONFIG_DEBUG_SIFIVE +#elif defined CONFIG_DEBUG_SIFIVE && !defined __ASSEMBLY__ #include <io.h> @@ -47,6 +58,17 @@ static inline void PUTC_LL(char ch) #include <asm/debug_ll_litex.h> +#elif defined CONFIG_DEBUG_RISCVEMU_HTIF + +#include <asm/htif.h> + +#ifndef __ASSEMBLY__ +static inline void PUTC_LL(char ch) +{ + htif_putc(IOMEM(HTIF_DEFAULT_BASE_ADDR), ch); +} +#endif + #endif #ifndef debug_ll_init diff --git a/arch/riscv/include/asm/debug_ll_litex.h b/arch/riscv/include/asm/debug_ll_litex.h index 2fcdd9b0ec..295477fc10 100644 --- a/arch/riscv/include/asm/debug_ll_litex.h +++ b/arch/riscv/include/asm/debug_ll_litex.h @@ -90,11 +90,11 @@ static inline void PUTC_LL(char ch) li t0, DEBUG_LL_UART_ADDR /* get line status and check for data present */ - lbu s0, UART_RXEMPTY(t0) - bnez s0, 243f - li s0, 1 + lbu s1, UART_RXEMPTY(t0) + bnez s1, 243f + li s1, 1 j 244f -243: li s0, 0 +243: li s1, 0 244: nop #endif /* CONFIG_DEBUG_LL */ .endm @@ -109,10 +109,10 @@ static inline void PUTC_LL(char ch) debug_ll_tstc /* try again */ - beqz s0, 204b + beqz s1, 204b /* read a character */ - lb s0, UART_RXTX(t0) + lb s1, UART_RXTX(t0) li t1, UART_EV_RX sb t1, UART_EV_PENDING(t0) diff --git a/arch/riscv/include/asm/debug_ll_ns16550.h b/arch/riscv/include/asm/debug_ll_ns16550.h index e208ef4fb1..47f0be328c 100644 --- a/arch/riscv/include/asm/debug_ll_ns16550.h +++ b/arch/riscv/include/asm/debug_ll_ns16550.h @@ -143,8 +143,8 @@ static inline void debug_ll_ns16550_init(void) li t0, DEBUG_LL_UART_ADDR /* get line status and check for data present */ - UART_REG_L s0, UART_LSR(DEBUG_LL_UART_SHIFT)(t0) - andi s0, s0, UART_LSR_DR + UART_REG_L s1, UART_LSR(DEBUG_LL_UART_SHIFT)(t0) + andi s1, s1, UART_LSR_DR #endif /* CONFIG_DEBUG_LL */ .endm @@ -159,10 +159,10 @@ static inline void debug_ll_ns16550_init(void) debug_ll_tstc /* try again */ - beqz s0, 204b + beqz s1, 204b /* read a character */ - UART_REG_L s0, UART_RBR(DEBUG_LL_UART_SHIFT)(t0) + UART_REG_L s1, UART_RBR(DEBUG_LL_UART_SHIFT)(t0) #endif /* CONFIG_DEBUG_LL */ .endm diff --git a/arch/riscv/include/asm/htif.h b/arch/riscv/include/asm/htif.h new file mode 100644 index 0000000000..b35afdd98e --- /dev/null +++ b/arch/riscv/include/asm/htif.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2021 Ahmad Fatoum, Pengutronix + */ + +#ifndef __ASM_HTIF_LL__ +#define __ASM_HTIF_LL__ + +#define HTIF_DEFAULT_BASE_ADDR 0x40008000 + +#define HTIF_DEV_SYSCALL 0 +#define HTIF_CMD_SYSCALL 0 + +#define HTIF_DEV_CONSOLE 1 /* blocking character device */ +#define HTIF_CMD_GETCHAR 0 +#define HTIF_CMD_PUTCHAR 1 + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> +#include <io-64-nonatomic-lo-hi.h> + +static inline void __htif_tohost(void __iomem *htif, u8 device, u8 command, u64 arg) +{ + writeq(((u64)device << 56) | ((u64)command << 48) | arg, htif); +} + +static inline void htif_tohost(u8 device, u8 command, u64 arg) +{ + __htif_tohost(IOMEM(HTIF_DEFAULT_BASE_ADDR), device, command, arg); +} + +static inline void htif_putc(void __iomem *base, int c) +{ + __htif_tohost(base, HTIF_DEV_CONSOLE, HTIF_CMD_PUTCHAR, c); +} + +#endif + +#endif diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index 795e670e3b..76d66c0a3b 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #ifndef __ASM_RISCV_IO_H #define __ASM_RISCV_IO_H @@ -5,14 +7,4 @@ #include <asm-generic/io.h> -static inline void *phys_to_virt(unsigned long phys) -{ - return (void *)phys; -} - -static inline unsigned long virt_to_phys(volatile void *mem) -{ - return (unsigned long)mem; -} - #endif /* __ASM_RISCV_IO_H */ diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h index 95af871420..1c2646ebb3 100644 --- a/arch/riscv/include/asm/mmu.h +++ b/arch/riscv/include/asm/mmu.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #ifndef __ASM_MMU_H #define __ASM_MMU_H diff --git a/arch/riscv/include/asm/pci.h b/arch/riscv/include/asm/pci.h new file mode 100644 index 0000000000..dd18499a37 --- /dev/null +++ b/arch/riscv/include/asm/pci.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ASM_PCI_H +#define __ASM_PCI_H + +#define pcibios_assign_all_busses() 1 + +#endif diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h index 22cae6230c..feaed42471 100644 --- a/arch/riscv/include/asm/posix_types.h +++ b/arch/riscv/include/asm/posix_types.h @@ -1 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #include <asm-generic/posix_types.h> diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h index b5e792f666..319c50f946 100644 --- a/arch/riscv/include/asm/ptrace.h +++ b/arch/riscv/include/asm/ptrace.h @@ -61,7 +61,7 @@ struct pt_regs { #define MAX_REG_OFFSET offsetof(struct pt_regs, cause) /* Helpers for working with the instruction pointer */ -static inline unsigned long instruction_pointer(struct pt_regs *regs) +static inline unsigned long instruction_pointer(const struct pt_regs *regs) { return regs->epc; } @@ -74,7 +74,7 @@ static inline void instruction_pointer_set(struct pt_regs *regs, #define profile_pc(regs) instruction_pointer(regs) /* Helpers for working with the user stack pointer */ -static inline unsigned long user_stack_pointer(struct pt_regs *regs) +static inline unsigned long user_stack_pointer(const struct pt_regs *regs) { return regs->sp; } @@ -85,13 +85,13 @@ static inline void user_stack_pointer_set(struct pt_regs *regs, } /* Valid only for Kernel mode traps. */ -static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +static inline unsigned long kernel_stack_pointer(const struct pt_regs *regs) { return regs->sp; } /* Helpers for working with the frame pointer */ -static inline unsigned long frame_pointer(struct pt_regs *regs) +static inline unsigned long frame_pointer(const struct pt_regs *regs) { return regs->s0; } @@ -101,7 +101,7 @@ static inline void frame_pointer_set(struct pt_regs *regs, regs->s0 = val; } -static inline unsigned long regs_return_value(struct pt_regs *regs) +static inline unsigned long regs_return_value(const struct pt_regs *regs) { return regs->a0; } diff --git a/arch/riscv/include/asm/reloc.h b/arch/riscv/include/asm/reloc.h new file mode 100644 index 0000000000..9a59326cad --- /dev/null +++ b/arch/riscv/include/asm/reloc.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _ASM_RELOC_H_ +#define _ASM_RELOC_H_ + +unsigned long get_runtime_offset(void); + +void relocate_to_current_adr(void); +void relocate_to_adr(unsigned long target); + +void setup_c(void); + +#include <asm-generic/reloc.h> + +#endif /* _BAREBOX_RISCV_H_ */ diff --git a/arch/riscv/include/asm/riscv_nmon.h b/arch/riscv/include/asm/riscv_nmon.h index 8a44e216d7..3e349025fe 100644 --- a/arch/riscv/include/asm/riscv_nmon.h +++ b/arch/riscv/include/asm/riscv_nmon.h @@ -84,7 +84,7 @@ nmon_main: debug_ll_getc li a0, 'q' - bne s0, a0, 3f + bne s1, a0, 3f jal a2, _nmon_outc_a0 @@ -92,13 +92,13 @@ nmon_main: 3: li a0, 'd' - beq s0, a0, nmon_cmd_d + beq s1, a0, nmon_cmd_d li a0, 'w' - beq s0, a0, nmon_cmd_w + beq s1, a0, nmon_cmd_w li a0, 'g' - beq s0, a0, nmon_cmd_g + beq s1, a0, nmon_cmd_g j nmon_main_help @@ -112,7 +112,7 @@ nmon_cmd_d: nmon_outs msg_nl - lw a0, (s0) + lw a0, (s1) debug_ll_outhexw j nmon_main @@ -124,13 +124,13 @@ nmon_cmd_w: jal a2, _nmon_outc_a0 jal a2, _nmon_gethexw - move s2, s0 + move s3, s1 li a0, ' ' jal a2, _nmon_outc_a0 jal a2, _nmon_gethexw - sw s0, 0(s2) + sw s1, 0(s3) j nmon_main nmon_cmd_g: @@ -140,11 +140,11 @@ nmon_cmd_g: jal a2, _nmon_outc_a0 jal a2, _nmon_gethexw - move s2, s0 + move s3, s1 nmon_outs msg_nl - jalr s2 + jalr s3 j nmon_main _nmon_outc_a0: @@ -169,37 +169,37 @@ _nmon_gethexw: _get_hex_digit: debug_ll_getc - li s1, CODE_ESC - beq s0, s1, nmon_main + li s2, CODE_ESC + beq s1, s2, nmon_main - li s1, '0' - bge s0, s1, 0f + li s2, '0' + bge s1, s2, 0f j _get_hex_digit 0: - li s1, '9' - ble s0, s1, 9f + li s2, '9' + ble s1, s2, 9f - li s1, 'f' - ble s0, s1, 1f + li s2, 'f' + ble s1, s2, 1f j _get_hex_digit 1: - li s1, 'a' - bge s0, s1, 8f + li s2, 'a' + bge s1, s2, 8f j _get_hex_digit -8: /* s0 \in {'a', 'b' ... 'f'} */ - sub a3, s0, s1 +8: /* s1 \in {'a', 'b' ... 'f'} */ + sub a3, s1, s2 addi a3, a3, 0xa j 0f -9: /* s0 \in {'0', '1' ... '9'} */ +9: /* s1 \in {'0', '1' ... '9'} */ li a3, '0' - sub a3, s0, a3 + sub a3, s1, a3 -0: move a0, s0 +0: move a0, s1 debug_ll_outc_a0 sll t2, t2, 4 @@ -212,7 +212,7 @@ _get_hex_digit: j _get_hex_digit 0: - move s0, t2 + move s1, t2 _nmon_jr_ra_exit: jr a2 diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h index 6673648bcd..cea039cc5e 100644 --- a/arch/riscv/include/asm/sections.h +++ b/arch/riscv/include/asm/sections.h @@ -6,6 +6,7 @@ #include <asm-generic/sections.h> #include <linux/types.h> #include <asm/unaligned.h> +#include <asm/reloc.h> extern char __rel_dyn_start[]; extern char __rel_dyn_end[]; @@ -19,7 +20,7 @@ unsigned long get_runtime_offset(void); static inline unsigned int input_data_len(void) { - return get_unaligned((const u32 *)(input_data_end + get_runtime_offset() - 4)); + return get_unaligned((const u32 *)runtime_address(input_data_end) - 1); } #endif diff --git a/arch/riscv/include/asm/swab.h b/arch/riscv/include/asm/swab.h index 60a90120b6..0ca746f0f1 100644 --- a/arch/riscv/include/asm/swab.h +++ b/arch/riscv/include/asm/swab.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #ifndef _ASM_SWAB_H #define _ASM_SWAB_H diff --git a/arch/riscv/include/asm/system.h b/arch/riscv/include/asm/system.h index adf856f9e9..f0b6bf2945 100644 --- a/arch/riscv/include/asm/system.h +++ b/arch/riscv/include/asm/system.h @@ -5,6 +5,8 @@ #ifndef __ASSEMBLY__ +#include <asm/sbi.h> + #define RISCV_MODE_MASK 0x3 enum riscv_mode { RISCV_U_MODE = 0, @@ -13,7 +15,39 @@ enum riscv_mode { RISCV_M_MODE = 3, }; -static inline enum riscv_mode __riscv_mode(u32 flags) +static inline void riscv_set_flags(unsigned flags) +{ + switch (flags & RISCV_MODE_MASK) { + case RISCV_S_MODE: + __asm__ volatile("csrw sscratch, %0" : : "r"(flags)); + break; + case RISCV_M_MODE: + __asm__ volatile("csrw mscratch, %0" : : "r"(flags)); + break; + default: + /* Other modes are not implemented yet */ + break; + } +} + +static inline u32 riscv_get_flags(void) +{ + u32 flags = 0; + + if (IS_ENABLED(CONFIG_RISCV_S_MODE)) + __asm__ volatile("csrr %0, sscratch" : "=r"(flags)); + + /* + * Since we always set the scratch register on the very beginning, a + * empty flags indicates that we are running in M-mode. + */ + if (!flags) + __asm__ volatile("csrr %0, mscratch" : "=r"(flags)); + + return flags; +} + +static inline enum riscv_mode riscv_mode(void) { /* allow non-LTO builds to discard code for unused modes */ if (!IS_ENABLED(CONFIG_RISCV_MULTI_MODE)) { @@ -23,14 +57,14 @@ static inline enum riscv_mode __riscv_mode(u32 flags) return RISCV_S_MODE; } - return flags & RISCV_MODE_MASK; + return riscv_get_flags() & RISCV_MODE_MASK; } -static inline long __riscv_hartid(u32 flags) +static inline long riscv_hartid(void) { long hartid = -1; - switch (__riscv_mode(flags)) { + switch (riscv_mode()) { case RISCV_S_MODE: __asm__ volatile("mv %0, tp\n" : "=r"(hartid) :); break; @@ -42,19 +76,29 @@ static inline long __riscv_hartid(u32 flags) return hartid; } -#ifndef __PBL__ -extern unsigned barebox_riscv_pbl_flags; - -static inline enum riscv_mode riscv_mode(void) +static inline long riscv_vendor_id(void) { - return __riscv_mode(barebox_riscv_pbl_flags); -} + struct sbiret ret; + long id; -static inline long riscv_hartid(void) -{ - return __riscv_hartid(barebox_riscv_pbl_flags); + switch (riscv_mode()) { + case RISCV_M_MODE: + __asm__ volatile("csrr %0, mvendorid\n" : "=r"(id)); + return id; + case RISCV_S_MODE: + /* + * We need to use the sbi_ecall() since it can be that we got + * called without a working stack + */ + ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_GET_MVENDORID, + 0, 0, 0, 0, 0, 0); + if (!ret.error) + return ret.value; + return -1; + default: + return -1; + } } -#endif #endif diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h index 1ad5904f91..add1c94fc7 100644 --- a/arch/riscv/include/asm/types.h +++ b/arch/riscv/include/asm/types.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #ifndef __ASM_RISCV_TYPES_H #define __ASM_RISCV_TYPES_H diff --git a/arch/riscv/include/asm/unaligned.h b/arch/riscv/include/asm/unaligned.h index c37b71c21e..3bc2930989 100644 --- a/arch/riscv/include/asm/unaligned.h +++ b/arch/riscv/include/asm/unaligned.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + #ifndef _ASM_RISCV_UNALIGNED_H #define _ASM_RISCV_UNALIGNED_H diff --git a/arch/riscv/include/asm/unwind.h b/arch/riscv/include/asm/unwind.h index 9e5c8b5420..00f7845147 100644 --- a/arch/riscv/include/asm/unwind.h +++ b/arch/riscv/include/asm/unwind.h @@ -4,6 +4,12 @@ struct pt_regs; -void unwind_backtrace(struct pt_regs *regs); +#if defined CONFIG_RISCV_UNWIND && !defined __PBL__ +void unwind_backtrace(const struct pt_regs *regs); +#else +static inline void unwind_backtrace(const struct pt_regs *regs) +{ +} +#endif #endif diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h new file mode 100644 index 0000000000..cb89af3f07 --- /dev/null +++ b/arch/riscv/include/asm/vendorid_list.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2021 SiFive + */ +#ifndef ASM_VENDOR_LIST_H +#define ASM_VENDOR_LIST_H + +#define SIFIVE_VENDOR_ID 0x489 +#define THEAD_VENDOR_ID 0x5b7 + +#endif diff --git a/arch/riscv/include/asm/word-at-a-time.h b/arch/riscv/include/asm/word-at-a-time.h new file mode 100644 index 0000000000..74f077d38f --- /dev/null +++ b/arch/riscv/include/asm/word-at-a-time.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2012 Regents of the University of California + * + * Derived from arch/x86/include/asm/word-at-a-time.h + */ + +#ifndef _ASM_RISCV_WORD_AT_A_TIME_H +#define _ASM_RISCV_WORD_AT_A_TIME_H + + +#include <linux/kernel.h> +#include <linux/bitops.h> + +struct word_at_a_time { + const unsigned long one_bits, high_bits; +}; + +#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } + +static inline unsigned long has_zero(unsigned long val, + unsigned long *bits, const struct word_at_a_time *c) +{ + unsigned long mask = ((val - c->one_bits) & ~val) & c->high_bits; + *bits = mask; + return mask; +} + +static inline unsigned long prep_zero_mask(unsigned long val, + unsigned long bits, const struct word_at_a_time *c) +{ + return bits; +} + +static inline unsigned long create_zero_mask(unsigned long bits) +{ + bits = (bits - 1) & ~bits; + return bits >> 7; +} + +static inline unsigned long find_zero(unsigned long mask) +{ + return fls64(mask) >> 3; +} + +/* The mask we created is directly usable as a bytemask */ +#define zero_bytemask(mask) (mask) + +#endif /* _ASM_RISCV_WORD_AT_A_TIME_H */ |