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