[PATCH v2 2/3] RISC-V: Add basic support for SBI v0.2
The SBI v0.2 introduces a base extension which is backward compatible with v0.1. Implement all helper functions and minimum required SBI calls from v0.2 for now. All other base extension function will be added later as per need. As v0.2 calling convention is backward compatible with v0.1, remove the v0.1 helper functions and just use v0.2 calling convention. Signed-off-by: Atish Patra --- arch/riscv/include/asm/sbi.h | 139 ++-- arch/riscv/kernel/Makefile | 1 + arch/riscv/kernel/sbi.c | 241 +++ arch/riscv/kernel/setup.c| 2 + 4 files changed, 311 insertions(+), 72 deletions(-) create mode 100644 arch/riscv/kernel/sbi.c diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 2147f384fad0..279b7f10b3c2 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -8,93 +8,88 @@ #include -#define SBI_EXT_0_1_SET_TIMER 0x0 -#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 -#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2 -#define SBI_EXT_0_1_CLEAR_IPI 0x3 -#define SBI_EXT_0_1_SEND_IPI 0x4 -#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5 -#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6 -#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7 -#define SBI_EXT_0_1_SHUTDOWN 0x8 +enum sbi_ext_id { + SBI_EXT_0_1_SET_TIMER = 0x0, + SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, + SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, + SBI_EXT_0_1_CLEAR_IPI = 0x3, + SBI_EXT_0_1_SEND_IPI = 0x4, + SBI_EXT_0_1_REMOTE_FENCE_I = 0x5, + SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, + SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, + SBI_EXT_0_1_SHUTDOWN = 0x8, + SBI_EXT_BASE = 0x10, +}; -#define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \ - register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ - register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ - register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ - register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \ - register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ - asm volatile ("ecall" \ - : "+r" (a0) \ - : "r" (a1), "r" (a2), "r" (a3), "r" (a7) \ - : "memory"); \ - a0; \ -}) +enum sbi_ext_base_fid { + SBI_BASE_GET_SPEC_VERSION = 0, + SBI_BASE_GET_IMP_ID, + SBI_BASE_GET_IMP_VERSION, + SBI_BASE_PROBE_EXT, + SBI_BASE_GET_MVENDORID, + SBI_BASE_GET_MARCHID, + SBI_BASE_GET_MIMPID, +}; -/* Lazy implementations until SBI is finalized */ -#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0) -#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0) -#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0) -#define SBI_CALL_3(which, arg0, arg1, arg2) \ - SBI_CALL(which, arg0, arg1, arg2, 0) -#define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \ - SBI_CALL(which, arg0, arg1, arg2, arg3) +#define SBI_SPEC_VERSION_DEFAULT 0x1 +#define SBI_SPEC_VERSION_MAJOR_OFFSET 24 +#define SBI_SPEC_VERSION_MAJOR_MASK0x7f +#define SBI_SPEC_VERSION_MINOR_MASK0xff -static inline void sbi_console_putchar(int ch) -{ - SBI_CALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, ch); -} +/* SBI return error codes */ +#define SBI_SUCCESS0 +#define SBI_ERR_FAILURE-1 +#define SBI_ERR_NOT_SUPPORTED -2 +#define SBI_ERR_INVALID_PARAM -3 +#define SBI_ERR_DENIED -4 +#define SBI_ERR_INVALID_ADDRESS -5 -static inline int sbi_console_getchar(void) -{ - return SBI_CALL_0(SBI_EXT_0_1_CONSOLE_GETCHAR); -} - -static inline void sbi_set_timer(uint64_t stime_value) -{ -#if __riscv_xlen == 32 - SBI_CALL_2(SBI_EXT_0_1_SET_TIMER, stime_value, - stime_value >> 32); -#else - SBI_CALL_1(SBI_EXT_0_1_SET_TIMER, stime_value); -#endif -} +extern unsigned long sbi_spec_version; +struct sbiret { + long error; + long value; +}; -static inline void sbi_shutdown(void) -{ - SBI_CALL_0(SBI_EXT_0_1_SHUTDOWN); -} +void sbi_init(void); +struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, + unsigned long arg1, unsigned long arg2, + unsigned long arg3); +int sbi_err_map_linux_errorno(int err); -static inline void sbi_clear_ipi(void) -{ - SBI_CALL_0(SBI_EXT_0_1_CLEAR_IPI); -} +void sbi_console_putchar(int ch); +int sbi_console_getchar(void); +void sbi_set_timer(uint64_t stime_value); +void sbi_shutdown(void); +void sbi_clear_ipi(void); +void sbi_send_ipi(const unsigned long *hart_mask); +void sbi_remote_fence_i(const unsigned long *hart_mask); +void sbi_remote_sfence_vma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size); -static inl
Re: [PATCH v2 2/3] RISC-V: Add basic support for SBI v0.2
On Fri, Sep 27, 2019 at 5:39 AM Atish Patra wrote: > > The SBI v0.2 introduces a base extension which is backward compatible > with v0.1. Implement all helper functions and minimum required SBI > calls from v0.2 for now. All other base extension function will be > added later as per need. > As v0.2 calling convention is backward compatible with v0.1, remove > the v0.1 helper functions and just use v0.2 calling convention. > > Signed-off-by: Atish Patra > --- > arch/riscv/include/asm/sbi.h | 139 ++-- > arch/riscv/kernel/Makefile | 1 + > arch/riscv/kernel/sbi.c | 241 +++ > arch/riscv/kernel/setup.c| 2 + > 4 files changed, 311 insertions(+), 72 deletions(-) > create mode 100644 arch/riscv/kernel/sbi.c > > diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h > index 2147f384fad0..279b7f10b3c2 100644 > --- a/arch/riscv/include/asm/sbi.h > +++ b/arch/riscv/include/asm/sbi.h > @@ -8,93 +8,88 @@ > > #include > > -#define SBI_EXT_0_1_SET_TIMER 0x0 > -#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 > -#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2 > -#define SBI_EXT_0_1_CLEAR_IPI 0x3 > -#define SBI_EXT_0_1_SEND_IPI 0x4 > -#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5 > -#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6 > -#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7 > -#define SBI_EXT_0_1_SHUTDOWN 0x8 > +enum sbi_ext_id { > + SBI_EXT_0_1_SET_TIMER = 0x0, > + SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, > + SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, > + SBI_EXT_0_1_CLEAR_IPI = 0x3, > + SBI_EXT_0_1_SEND_IPI = 0x4, > + SBI_EXT_0_1_REMOTE_FENCE_I = 0x5, > + SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, > + SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, > + SBI_EXT_0_1_SHUTDOWN = 0x8, > + SBI_EXT_BASE = 0x10, > +}; > > -#define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \ > - register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ > - register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ > - register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ > - register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \ > - register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ > - asm volatile ("ecall" \ > - : "+r" (a0) \ > - : "r" (a1), "r" (a2), "r" (a3), "r" (a7) \ > - : "memory"); \ > - a0; \ > -}) > +enum sbi_ext_base_fid { > + SBI_BASE_GET_SPEC_VERSION = 0, > + SBI_BASE_GET_IMP_ID, > + SBI_BASE_GET_IMP_VERSION, > + SBI_BASE_PROBE_EXT, > + SBI_BASE_GET_MVENDORID, > + SBI_BASE_GET_MARCHID, > + SBI_BASE_GET_MIMPID, > +}; > > -/* Lazy implementations until SBI is finalized */ > -#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0) > -#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0) > -#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0) > -#define SBI_CALL_3(which, arg0, arg1, arg2) \ > - SBI_CALL(which, arg0, arg1, arg2, 0) > -#define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \ > - SBI_CALL(which, arg0, arg1, arg2, arg3) > +#define SBI_SPEC_VERSION_DEFAULT 0x1 > +#define SBI_SPEC_VERSION_MAJOR_OFFSET 24 > +#define SBI_SPEC_VERSION_MAJOR_MASK0x7f > +#define SBI_SPEC_VERSION_MINOR_MASK0xff > > -static inline void sbi_console_putchar(int ch) > -{ > - SBI_CALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, ch); > -} > +/* SBI return error codes */ > +#define SBI_SUCCESS0 > +#define SBI_ERR_FAILURE-1 > +#define SBI_ERR_NOT_SUPPORTED -2 > +#define SBI_ERR_INVALID_PARAM -3 > +#define SBI_ERR_DENIED -4 > +#define SBI_ERR_INVALID_ADDRESS -5 > > -static inline int sbi_console_getchar(void) > -{ > - return SBI_CALL_0(SBI_EXT_0_1_CONSOLE_GETCHAR); > -} > - > -static inline void sbi_set_timer(uint64_t stime_value) > -{ > -#if __riscv_xlen == 32 > - SBI_CALL_2(SBI_EXT_0_1_SET_TIMER, stime_value, > - stime_value >> 32); > -#else > - SBI_CALL_1(SBI_EXT_0_1_SET_TIMER, stime_value); > -#endif > -} > +extern unsigned long sbi_spec_version; > +struct sbiret { > + long error; > + long value; > +}; > > -static inline void sbi_shutdown(void) > -{ > - SBI_CALL_0(SBI_EXT_0_1_SHUTDOWN); > -} > +void sbi_init(void); > +struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, > + unsigned long arg1, unsigned long arg2, > + unsigned long arg3); > +int sbi_err_map_linux_errorno(int err); > > -static inline void sbi_clear_ipi(void) > -{ > - SBI_CALL_0(SBI_EXT_0_1_CLEAR_IPI); > -} > +void sbi_console_putchar(int ch); > +int sbi_console_getchar(void); > +void sbi_set_timer(uint64_t stime_value); > +void sbi_shutdown(void); > +void
Re: [PATCH v2 2/3] RISC-V: Add basic support for SBI v0.2
On Fri, Sep 27, 2019 at 5:39 AM Atish Patra wrote: > > The SBI v0.2 introduces a base extension which is backward compatible > with v0.1. Implement all helper functions and minimum required SBI > calls from v0.2 for now. All other base extension function will be > added later as per need. > As v0.2 calling convention is backward compatible with v0.1, remove > the v0.1 helper functions and just use v0.2 calling convention. > > Signed-off-by: Atish Patra > --- > arch/riscv/include/asm/sbi.h | 139 ++-- > arch/riscv/kernel/Makefile | 1 + > arch/riscv/kernel/sbi.c | 241 +++ > arch/riscv/kernel/setup.c| 2 + > 4 files changed, 311 insertions(+), 72 deletions(-) > create mode 100644 arch/riscv/kernel/sbi.c > > diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h > index 2147f384fad0..279b7f10b3c2 100644 > --- a/arch/riscv/include/asm/sbi.h > +++ b/arch/riscv/include/asm/sbi.h > @@ -8,93 +8,88 @@ > > #include > > -#define SBI_EXT_0_1_SET_TIMER 0x0 > -#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 > -#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2 > -#define SBI_EXT_0_1_CLEAR_IPI 0x3 > -#define SBI_EXT_0_1_SEND_IPI 0x4 > -#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5 > -#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6 > -#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7 > -#define SBI_EXT_0_1_SHUTDOWN 0x8 > +enum sbi_ext_id { > + SBI_EXT_0_1_SET_TIMER = 0x0, > + SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, > + SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, > + SBI_EXT_0_1_CLEAR_IPI = 0x3, > + SBI_EXT_0_1_SEND_IPI = 0x4, > + SBI_EXT_0_1_REMOTE_FENCE_I = 0x5, > + SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, > + SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, > + SBI_EXT_0_1_SHUTDOWN = 0x8, > + SBI_EXT_BASE = 0x10, > +}; > > -#define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \ > - register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ > - register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ > - register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ > - register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \ > - register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ > - asm volatile ("ecall" \ > - : "+r" (a0) \ > - : "r" (a1), "r" (a2), "r" (a3), "r" (a7) \ > - : "memory"); \ > - a0; \ > -}) > +enum sbi_ext_base_fid { > + SBI_BASE_GET_SPEC_VERSION = 0, > + SBI_BASE_GET_IMP_ID, > + SBI_BASE_GET_IMP_VERSION, > + SBI_BASE_PROBE_EXT, > + SBI_BASE_GET_MVENDORID, > + SBI_BASE_GET_MARCHID, > + SBI_BASE_GET_MIMPID, > +}; > > -/* Lazy implementations until SBI is finalized */ > -#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0) > -#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0) > -#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0) > -#define SBI_CALL_3(which, arg0, arg1, arg2) \ > - SBI_CALL(which, arg0, arg1, arg2, 0) > -#define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \ > - SBI_CALL(which, arg0, arg1, arg2, arg3) > +#define SBI_SPEC_VERSION_DEFAULT 0x1 > +#define SBI_SPEC_VERSION_MAJOR_OFFSET 24 > +#define SBI_SPEC_VERSION_MAJOR_MASK0x7f > +#define SBI_SPEC_VERSION_MINOR_MASK0xff > > -static inline void sbi_console_putchar(int ch) > -{ > - SBI_CALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, ch); > -} > +/* SBI return error codes */ > +#define SBI_SUCCESS0 > +#define SBI_ERR_FAILURE-1 > +#define SBI_ERR_NOT_SUPPORTED -2 > +#define SBI_ERR_INVALID_PARAM -3 > +#define SBI_ERR_DENIED -4 > +#define SBI_ERR_INVALID_ADDRESS -5 > > -static inline int sbi_console_getchar(void) > -{ > - return SBI_CALL_0(SBI_EXT_0_1_CONSOLE_GETCHAR); > -} > - > -static inline void sbi_set_timer(uint64_t stime_value) > -{ > -#if __riscv_xlen == 32 > - SBI_CALL_2(SBI_EXT_0_1_SET_TIMER, stime_value, > - stime_value >> 32); > -#else > - SBI_CALL_1(SBI_EXT_0_1_SET_TIMER, stime_value); > -#endif > -} > +extern unsigned long sbi_spec_version; > +struct sbiret { > + long error; > + long value; > +}; > > -static inline void sbi_shutdown(void) > -{ > - SBI_CALL_0(SBI_EXT_0_1_SHUTDOWN); > -} > +void sbi_init(void); > +struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, > + unsigned long arg1, unsigned long arg2, > + unsigned long arg3); > +int sbi_err_map_linux_errorno(int err); > > -static inline void sbi_clear_ipi(void) > -{ > - SBI_CALL_0(SBI_EXT_0_1_CLEAR_IPI); > -} > +void sbi_console_putchar(int ch); > +int sbi_console_getchar(void); > +void sbi_set_timer(uint64_t stime_value); > +void sbi_shutdown(void); > +void