|
10 | 10 | #include <linux/types.h>
|
11 | 11 |
|
12 | 12 | #ifdef CONFIG_RISCV_SBI
|
13 |
| -#define SBI_EXT_0_1_SET_TIMER 0x0 |
14 |
| -#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 |
15 |
| -#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2 |
16 |
| -#define SBI_EXT_0_1_CLEAR_IPI 0x3 |
17 |
| -#define SBI_EXT_0_1_SEND_IPI 0x4 |
18 |
| -#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5 |
19 |
| -#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6 |
20 |
| -#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7 |
21 |
| -#define SBI_EXT_0_1_SHUTDOWN 0x8 |
| 13 | +enum sbi_ext_id { |
| 14 | + SBI_EXT_0_1_SET_TIMER = 0x0, |
| 15 | + SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, |
| 16 | + SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, |
| 17 | + SBI_EXT_0_1_CLEAR_IPI = 0x3, |
| 18 | + SBI_EXT_0_1_SEND_IPI = 0x4, |
| 19 | + SBI_EXT_0_1_REMOTE_FENCE_I = 0x5, |
| 20 | + SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, |
| 21 | + SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, |
| 22 | + SBI_EXT_0_1_SHUTDOWN = 0x8, |
| 23 | + SBI_EXT_BASE = 0x10, |
| 24 | +}; |
22 | 25 |
|
23 |
| -#define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \ |
24 |
| - register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ |
25 |
| - register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ |
26 |
| - register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ |
27 |
| - register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \ |
28 |
| - register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ |
29 |
| - asm volatile ("ecall" \ |
30 |
| - : "+r" (a0) \ |
31 |
| - : "r" (a1), "r" (a2), "r" (a3), "r" (a7) \ |
32 |
| - : "memory"); \ |
33 |
| - a0; \ |
34 |
| -}) |
| 26 | +enum sbi_ext_base_fid { |
| 27 | + SBI_EXT_BASE_GET_SPEC_VERSION = 0, |
| 28 | + SBI_EXT_BASE_GET_IMP_ID, |
| 29 | + SBI_EXT_BASE_GET_IMP_VERSION, |
| 30 | + SBI_EXT_BASE_PROBE_EXT, |
| 31 | + SBI_EXT_BASE_GET_MVENDORID, |
| 32 | + SBI_EXT_BASE_GET_MARCHID, |
| 33 | + SBI_EXT_BASE_GET_MIMPID, |
| 34 | +}; |
35 | 35 |
|
36 |
| -/* Lazy implementations until SBI is finalized */ |
37 |
| -#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0) |
38 |
| -#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0) |
39 |
| -#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0) |
40 |
| -#define SBI_CALL_3(which, arg0, arg1, arg2) \ |
41 |
| - SBI_CALL(which, arg0, arg1, arg2, 0) |
42 |
| -#define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \ |
43 |
| - SBI_CALL(which, arg0, arg1, arg2, arg3) |
| 36 | +#define SBI_SPEC_VERSION_DEFAULT 0x1 |
| 37 | +#define SBI_SPEC_VERSION_MAJOR_SHIFT 24 |
| 38 | +#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f |
| 39 | +#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff |
44 | 40 |
|
45 |
| -static inline void sbi_console_putchar(int ch) |
46 |
| -{ |
47 |
| - SBI_CALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, ch); |
48 |
| -} |
| 41 | +/* SBI return error codes */ |
| 42 | +#define SBI_SUCCESS 0 |
| 43 | +#define SBI_ERR_FAILURE -1 |
| 44 | +#define SBI_ERR_NOT_SUPPORTED -2 |
| 45 | +#define SBI_ERR_INVALID_PARAM -3 |
| 46 | +#define SBI_ERR_DENIED -4 |
| 47 | +#define SBI_ERR_INVALID_ADDRESS -5 |
49 | 48 |
|
50 |
| -static inline int sbi_console_getchar(void) |
51 |
| -{ |
52 |
| - return SBI_CALL_0(SBI_EXT_0_1_CONSOLE_GETCHAR); |
53 |
| -} |
| 49 | +extern unsigned long sbi_spec_version; |
| 50 | +struct sbiret { |
| 51 | + long error; |
| 52 | + long value; |
| 53 | +}; |
54 | 54 |
|
55 |
| -static inline void sbi_set_timer(uint64_t stime_value) |
56 |
| -{ |
57 |
| -#if __riscv_xlen == 32 |
58 |
| - SBI_CALL_2(SBI_EXT_0_1_SET_TIMER, stime_value, |
59 |
| - stime_value >> 32); |
60 |
| -#else |
61 |
| - SBI_CALL_1(SBI_EXT_0_1_SET_TIMER, stime_value); |
62 |
| -#endif |
63 |
| -} |
64 |
| - |
65 |
| -static inline void sbi_shutdown(void) |
66 |
| -{ |
67 |
| - SBI_CALL_0(SBI_EXT_0_1_SHUTDOWN); |
68 |
| -} |
| 55 | +int sbi_init(void); |
| 56 | +struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, |
| 57 | + unsigned long arg1, unsigned long arg2, |
| 58 | + unsigned long arg3, unsigned long arg4, |
| 59 | + unsigned long arg5); |
69 | 60 |
|
70 |
| -static inline void sbi_clear_ipi(void) |
71 |
| -{ |
72 |
| - SBI_CALL_0(SBI_EXT_0_1_CLEAR_IPI); |
73 |
| -} |
| 61 | +void sbi_console_putchar(int ch); |
| 62 | +int sbi_console_getchar(void); |
| 63 | +void sbi_set_timer(uint64_t stime_value); |
| 64 | +void sbi_shutdown(void); |
| 65 | +void sbi_clear_ipi(void); |
| 66 | +void sbi_send_ipi(const unsigned long *hart_mask); |
| 67 | +void sbi_remote_fence_i(const unsigned long *hart_mask); |
| 68 | +void sbi_remote_sfence_vma(const unsigned long *hart_mask, |
| 69 | + unsigned long start, |
| 70 | + unsigned long size); |
74 | 71 |
|
75 |
| -static inline void sbi_send_ipi(const unsigned long *hart_mask) |
76 |
| -{ |
77 |
| - SBI_CALL_1(SBI_EXT_0_1_SEND_IPI, hart_mask); |
78 |
| -} |
| 72 | +void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, |
| 73 | + unsigned long start, |
| 74 | + unsigned long size, |
| 75 | + unsigned long asid); |
| 76 | +int sbi_probe_extension(int ext); |
79 | 77 |
|
80 |
| -static inline void sbi_remote_fence_i(const unsigned long *hart_mask) |
| 78 | +/* Check if current SBI specification version is 0.1 or not */ |
| 79 | +static inline int sbi_spec_is_0_1(void) |
81 | 80 | {
|
82 |
| - SBI_CALL_1(SBI_EXT_0_1_REMOTE_FENCE_I, hart_mask); |
| 81 | + return (sbi_spec_version == SBI_SPEC_VERSION_DEFAULT) ? 1 : 0; |
83 | 82 | }
|
84 | 83 |
|
85 |
| -static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask, |
86 |
| - unsigned long start, |
87 |
| - unsigned long size) |
| 84 | +/* Get the major version of SBI */ |
| 85 | +static inline unsigned long sbi_major_version(void) |
88 | 86 | {
|
89 |
| - SBI_CALL_3(SBI_EXT_0_1_REMOTE_SFENCE_VMA, hart_mask, start, size); |
| 87 | + return (sbi_spec_version >> SBI_SPEC_VERSION_MAJOR_SHIFT) & |
| 88 | + SBI_SPEC_VERSION_MAJOR_MASK; |
90 | 89 | }
|
91 | 90 |
|
92 |
| -static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, |
93 |
| - unsigned long start, |
94 |
| - unsigned long size, |
95 |
| - unsigned long asid) |
| 91 | +/* Get the minor version of SBI */ |
| 92 | +static inline unsigned long sbi_minor_version(void) |
96 | 93 | {
|
97 |
| - SBI_CALL_4(SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID, hart_mask, |
98 |
| - start, size, asid); |
| 94 | + return sbi_spec_version & SBI_SPEC_VERSION_MINOR_MASK; |
99 | 95 | }
|
100 | 96 | #else /* CONFIG_RISCV_SBI */
|
101 | 97 | /* stubs for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
|
102 | 98 | void sbi_set_timer(uint64_t stime_value);
|
103 | 99 | void sbi_clear_ipi(void);
|
104 | 100 | void sbi_send_ipi(const unsigned long *hart_mask);
|
105 | 101 | void sbi_remote_fence_i(const unsigned long *hart_mask);
|
| 102 | +void sbi_init(void); |
106 | 103 | #endif /* CONFIG_RISCV_SBI */
|
107 | 104 | #endif /* _ASM_RISCV_SBI_H */
|
0 commit comments