1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #ifndef _ASMRISCV_SBI_H_
3 #define _ASMRISCV_SBI_H_
4
5 #define SBI_SUCCESS 0
6 #define SBI_ERR_FAILURE -1
7 #define SBI_ERR_NOT_SUPPORTED -2
8 #define SBI_ERR_INVALID_PARAM -3
9 #define SBI_ERR_DENIED -4
10 #define SBI_ERR_INVALID_ADDRESS -5
11 #define SBI_ERR_ALREADY_AVAILABLE -6
12 #define SBI_ERR_ALREADY_STARTED -7
13 #define SBI_ERR_ALREADY_STOPPED -8
14 #define SBI_ERR_NO_SHMEM -9
15 #define SBI_ERR_INVALID_STATE -10
16 #define SBI_ERR_BAD_RANGE -11
17 #define SBI_ERR_TIMEOUT -12
18 #define SBI_ERR_IO -13
19 #define SBI_ERR_DENIED_LOCKED -14
20
21 #define SBI_IMPL_BBL 0
22 #define SBI_IMPL_OPENSBI 1
23 #define SBI_IMPL_XVISOR 2
24 #define SBI_IMPL_KVM 3
25 #define SBI_IMPL_RUSTSBI 4
26 #define SBI_IMPL_DIOSIX 5
27 #define SBI_IMPL_COFFER 6
28 #define SBI_IMPL_XEN 7
29 #define SBI_IMPL_POLARFIRE_HSS 8
30 #define SBI_IMPL_COREBOOT 9
31 #define SBI_IMPL_OREBOOT 10
32 #define SBI_IMPL_BHYVE 11
33
34 /* SBI spec version fields */
35 #define SBI_SPEC_VERSION_MAJOR_SHIFT 24
36 #define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
37 #define SBI_SPEC_VERSION_MINOR_MASK 0xffffff
38 #define SBI_SPEC_VERSION_MASK ((SBI_SPEC_VERSION_MAJOR_MASK << SBI_SPEC_VERSION_MAJOR_SHIFT) | \
39 SBI_SPEC_VERSION_MINOR_MASK)
40
41 #ifndef __ASSEMBLER__
42 #include <cpumask.h>
43
44 enum sbi_ext_id {
45 SBI_EXT_BASE = 0x10,
46 SBI_EXT_TIME = 0x54494d45,
47 SBI_EXT_IPI = 0x735049,
48 SBI_EXT_HSM = 0x48534d,
49 SBI_EXT_SRST = 0x53525354,
50 SBI_EXT_DBCN = 0x4442434E,
51 SBI_EXT_SUSP = 0x53555350,
52 SBI_EXT_FWFT = 0x46574654,
53 SBI_EXT_SSE = 0x535345,
54 };
55
56 enum sbi_ext_base_fid {
57 SBI_EXT_BASE_GET_SPEC_VERSION = 0,
58 SBI_EXT_BASE_GET_IMP_ID,
59 SBI_EXT_BASE_GET_IMP_VERSION,
60 SBI_EXT_BASE_PROBE_EXT,
61 SBI_EXT_BASE_GET_MVENDORID,
62 SBI_EXT_BASE_GET_MARCHID,
63 SBI_EXT_BASE_GET_MIMPID,
64 };
65
66 enum sbi_ext_hsm_fid {
67 SBI_EXT_HSM_HART_START = 0,
68 SBI_EXT_HSM_HART_STOP,
69 SBI_EXT_HSM_HART_STATUS,
70 SBI_EXT_HSM_HART_SUSPEND,
71 };
72
73 enum sbi_ext_time_fid {
74 SBI_EXT_TIME_SET_TIMER = 0,
75 };
76
77 enum sbi_ext_ipi_fid {
78 SBI_EXT_IPI_SEND_IPI = 0,
79 };
80
81 enum sbi_ext_hsm_sid {
82 SBI_EXT_HSM_STARTED = 0,
83 SBI_EXT_HSM_STOPPED,
84 SBI_EXT_HSM_START_PENDING,
85 SBI_EXT_HSM_STOP_PENDING,
86 SBI_EXT_HSM_SUSPENDED,
87 SBI_EXT_HSM_SUSPEND_PENDING,
88 SBI_EXT_HSM_RESUME_PENDING,
89 };
90
91 enum sbi_ext_hsm_hart_suspend_type {
92 SBI_EXT_HSM_HART_SUSPEND_RETENTIVE = 0,
93 SBI_EXT_HSM_HART_SUSPEND_NON_RETENTIVE = 0x80000000,
94 };
95
96 enum sbi_ext_dbcn_fid {
97 SBI_EXT_DBCN_CONSOLE_WRITE = 0,
98 SBI_EXT_DBCN_CONSOLE_READ,
99 SBI_EXT_DBCN_CONSOLE_WRITE_BYTE,
100 };
101
102 enum sbi_ext_fwft_fid {
103 SBI_EXT_FWFT_SET = 0,
104 SBI_EXT_FWFT_GET,
105 };
106
107 #define SBI_FWFT_MISALIGNED_EXC_DELEG 0x0
108 #define SBI_FWFT_LANDING_PAD 0x1
109 #define SBI_FWFT_SHADOW_STACK 0x2
110 #define SBI_FWFT_DOUBLE_TRAP 0x3
111 #define SBI_FWFT_PTE_AD_HW_UPDATING 0x4
112 #define SBI_FWFT_POINTER_MASKING_PMLEN 0x5
113 #define SBI_FWFT_LOCAL_RESERVED_START 0x6
114 #define SBI_FWFT_LOCAL_RESERVED_END 0x3fffffff
115 #define SBI_FWFT_LOCAL_PLATFORM_START 0x40000000
116 #define SBI_FWFT_LOCAL_PLATFORM_END 0x7fffffff
117
118 #define SBI_FWFT_GLOBAL_RESERVED_START 0x80000000
119 #define SBI_FWFT_GLOBAL_RESERVED_END 0xbfffffff
120 #define SBI_FWFT_GLOBAL_PLATFORM_START 0xc0000000
121 #define SBI_FWFT_GLOBAL_PLATFORM_END 0xffffffff
122
123 #define SBI_FWFT_PLATFORM_FEATURE_BIT BIT(30)
124 #define SBI_FWFT_GLOBAL_FEATURE_BIT BIT(31)
125
126 #define SBI_FWFT_SET_FLAG_LOCK BIT(0)
127
128 enum sbi_ext_sse_fid {
129 SBI_EXT_SSE_READ_ATTRS = 0,
130 SBI_EXT_SSE_WRITE_ATTRS,
131 SBI_EXT_SSE_REGISTER,
132 SBI_EXT_SSE_UNREGISTER,
133 SBI_EXT_SSE_ENABLE,
134 SBI_EXT_SSE_DISABLE,
135 SBI_EXT_SSE_COMPLETE,
136 SBI_EXT_SSE_INJECT,
137 SBI_EXT_SSE_HART_UNMASK,
138 SBI_EXT_SSE_HART_MASK,
139 };
140
141 /* SBI SSE Event Attributes. */
142 enum sbi_sse_attr_id {
143 SBI_SSE_ATTR_STATUS = 0x00000000,
144 SBI_SSE_ATTR_PRIORITY = 0x00000001,
145 SBI_SSE_ATTR_CONFIG = 0x00000002,
146 SBI_SSE_ATTR_PREFERRED_HART = 0x00000003,
147 SBI_SSE_ATTR_ENTRY_PC = 0x00000004,
148 SBI_SSE_ATTR_ENTRY_ARG = 0x00000005,
149 SBI_SSE_ATTR_INTERRUPTED_SEPC = 0x00000006,
150 SBI_SSE_ATTR_INTERRUPTED_FLAGS = 0x00000007,
151 SBI_SSE_ATTR_INTERRUPTED_A6 = 0x00000008,
152 SBI_SSE_ATTR_INTERRUPTED_A7 = 0x00000009,
153 };
154
155 #define SBI_SSE_ATTR_STATUS_STATE_OFFSET 0
156 #define SBI_SSE_ATTR_STATUS_STATE_MASK 0x3
157 #define SBI_SSE_ATTR_STATUS_PENDING_OFFSET 2
158 #define SBI_SSE_ATTR_STATUS_INJECT_OFFSET 3
159
160 #define SBI_SSE_ATTR_CONFIG_ONESHOT BIT(0)
161
162 #define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPP BIT(0)
163 #define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPIE BIT(1)
164 #define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV BIT(2)
165 #define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP BIT(3)
166 #define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP BIT(4)
167 #define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SDT BIT(5)
168
169 enum sbi_sse_state {
170 SBI_SSE_STATE_UNUSED = 0,
171 SBI_SSE_STATE_REGISTERED = 1,
172 SBI_SSE_STATE_ENABLED = 2,
173 SBI_SSE_STATE_RUNNING = 3,
174 };
175
176 /* SBI SSE Event IDs. */
177 /* Range 0x00000000 - 0x0000ffff */
178 #define SBI_SSE_EVENT_LOCAL_HIGH_PRIO_RAS 0x00000000
179 #define SBI_SSE_EVENT_LOCAL_DOUBLE_TRAP 0x00000001
180 #define SBI_SSE_EVENT_LOCAL_RESERVED_0_START 0x00000002
181 #define SBI_SSE_EVENT_LOCAL_RESERVED_0_END 0x00003fff
182 #define SBI_SSE_EVENT_LOCAL_PLAT_0_START 0x00004000
183 #define SBI_SSE_EVENT_LOCAL_PLAT_0_END 0x00007fff
184
185 #define SBI_SSE_EVENT_GLOBAL_HIGH_PRIO_RAS 0x00008000
186 #define SBI_SSE_EVENT_GLOBAL_RESERVED_0_START 0x00008001
187 #define SBI_SSE_EVENT_GLOBAL_RESERVED_0_END 0x0000bfff
188 #define SBI_SSE_EVENT_GLOBAL_PLAT_0_START 0x0000c000
189 #define SBI_SSE_EVENT_GLOBAL_PLAT_0_END 0x0000ffff
190
191 /* Range 0x00010000 - 0x0001ffff */
192 #define SBI_SSE_EVENT_LOCAL_PMU_OVERFLOW 0x00010000
193 #define SBI_SSE_EVENT_LOCAL_RESERVED_1_START 0x00010001
194 #define SBI_SSE_EVENT_LOCAL_RESERVED_1_END 0x00013fff
195 #define SBI_SSE_EVENT_LOCAL_PLAT_1_START 0x00014000
196 #define SBI_SSE_EVENT_LOCAL_PLAT_1_END 0x00017fff
197
198 #define SBI_SSE_EVENT_GLOBAL_RESERVED_1_START 0x00018000
199 #define SBI_SSE_EVENT_GLOBAL_RESERVED_1_END 0x0001bfff
200 #define SBI_SSE_EVENT_GLOBAL_PLAT_1_START 0x0001c000
201 #define SBI_SSE_EVENT_GLOBAL_PLAT_1_END 0x0001ffff
202
203 /* Range 0x00100000 - 0x0010ffff */
204 #define SBI_SSE_EVENT_LOCAL_LOW_PRIO_RAS 0x00100000
205 #define SBI_SSE_EVENT_LOCAL_RESERVED_2_START 0x00100001
206 #define SBI_SSE_EVENT_LOCAL_RESERVED_2_END 0x00103fff
207 #define SBI_SSE_EVENT_LOCAL_PLAT_2_START 0x00104000
208 #define SBI_SSE_EVENT_LOCAL_PLAT_2_END 0x00107fff
209
210 #define SBI_SSE_EVENT_GLOBAL_LOW_PRIO_RAS 0x00108000
211 #define SBI_SSE_EVENT_GLOBAL_RESERVED_2_START 0x00108001
212 #define SBI_SSE_EVENT_GLOBAL_RESERVED_2_END 0x0010bfff
213 #define SBI_SSE_EVENT_GLOBAL_PLAT_2_START 0x0010c000
214 #define SBI_SSE_EVENT_GLOBAL_PLAT_2_END 0x0010ffff
215
216 /* Range 0xffff0000 - 0xffffffff */
217 #define SBI_SSE_EVENT_LOCAL_SOFTWARE 0xffff0000
218 #define SBI_SSE_EVENT_LOCAL_RESERVED_3_START 0xffff0001
219 #define SBI_SSE_EVENT_LOCAL_RESERVED_3_END 0xffff3fff
220 #define SBI_SSE_EVENT_LOCAL_PLAT_3_START 0xffff4000
221 #define SBI_SSE_EVENT_LOCAL_PLAT_3_END 0xffff7fff
222
223 #define SBI_SSE_EVENT_GLOBAL_SOFTWARE 0xffff8000
224 #define SBI_SSE_EVENT_GLOBAL_RESERVED_3_START 0xffff8001
225 #define SBI_SSE_EVENT_GLOBAL_RESERVED_3_END 0xffffbfff
226 #define SBI_SSE_EVENT_GLOBAL_PLAT_3_START 0xffffc000
227 #define SBI_SSE_EVENT_GLOBAL_PLAT_3_END 0xffffffff
228
229 #define SBI_SSE_EVENT_PLATFORM_BIT BIT(14)
230 #define SBI_SSE_EVENT_GLOBAL_BIT BIT(15)
231
232 struct sbiret {
233 long error;
234 long value;
235 };
236
sbi_mk_version(unsigned long major,unsigned long minor)237 static inline unsigned long sbi_mk_version(unsigned long major, unsigned long minor)
238 {
239 return ((major & SBI_SPEC_VERSION_MAJOR_MASK) << SBI_SPEC_VERSION_MAJOR_SHIFT)
240 | (minor & SBI_SPEC_VERSION_MINOR_MASK);
241 }
242
sbi_impl_opensbi_mk_version(unsigned long major,unsigned long minor)243 static inline unsigned long sbi_impl_opensbi_mk_version(unsigned long major, unsigned long minor)
244 {
245 return (((major & 0xffff) << 16) | (minor & 0xffff));
246 }
247
248 struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
249 unsigned long arg1, unsigned long arg2,
250 unsigned long arg3, unsigned long arg4,
251 unsigned long arg5);
252
253 void sbi_shutdown(void);
254 struct sbiret sbi_hart_start(unsigned long hartid, unsigned long entry, unsigned long sp);
255 struct sbiret sbi_hart_stop(void);
256 struct sbiret sbi_hart_get_status(unsigned long hartid);
257 struct sbiret sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base);
258 struct sbiret sbi_send_ipi_cpu(int cpu);
259 struct sbiret sbi_send_ipi_cpumask(const cpumask_t *mask);
260 struct sbiret sbi_send_ipi_broadcast(void);
261 struct sbiret sbi_set_timer(unsigned long stime_value);
262 struct sbiret sbi_get_spec_version(void);
263 struct sbiret sbi_get_imp_version(void);
264 struct sbiret sbi_get_imp_id(void);
265 long sbi_probe(int ext);
266 unsigned long __sbi_get_imp_version(void);
267 unsigned long __sbi_get_imp_id(void);
268
269 typedef void (*sbi_sse_handler_fn)(void *data, struct pt_regs *regs, unsigned int hartid);
270
271 struct sbi_sse_handler_arg {
272 unsigned long reg_tmp;
273 sbi_sse_handler_fn handler;
274 void *handler_data;
275 void *stack;
276 };
277
278 extern void sbi_sse_entry(void);
279
sbi_sse_event_is_global(uint32_t event_id)280 static inline bool sbi_sse_event_is_global(uint32_t event_id)
281 {
282 return !!(event_id & SBI_SSE_EVENT_GLOBAL_BIT);
283 }
284
285 struct sbiret sbi_sse_read_attrs_raw(unsigned long event_id, unsigned long base_attr_id,
286 unsigned long attr_count, unsigned long phys_lo,
287 unsigned long phys_hi);
288 struct sbiret sbi_sse_read_attrs(unsigned long event_id, unsigned long base_attr_id,
289 unsigned long attr_count, unsigned long *values);
290 struct sbiret sbi_sse_write_attrs_raw(unsigned long event_id, unsigned long base_attr_id,
291 unsigned long attr_count, unsigned long phys_lo,
292 unsigned long phys_hi);
293 struct sbiret sbi_sse_write_attrs(unsigned long event_id, unsigned long base_attr_id,
294 unsigned long attr_count, unsigned long *values);
295 struct sbiret sbi_sse_register_raw(unsigned long event_id, unsigned long entry_pc,
296 unsigned long entry_arg);
297 struct sbiret sbi_sse_register(unsigned long event_id, struct sbi_sse_handler_arg *arg);
298 struct sbiret sbi_sse_unregister(unsigned long event_id);
299 struct sbiret sbi_sse_enable(unsigned long event_id);
300 struct sbiret sbi_sse_disable(unsigned long event_id);
301 struct sbiret sbi_sse_hart_mask(void);
302 struct sbiret sbi_sse_hart_unmask(void);
303 struct sbiret sbi_sse_inject(unsigned long event_id, unsigned long hart_id);
304
305 #endif /* !__ASSEMBLER__ */
306 #endif /* _ASMRISCV_SBI_H_ */
307