1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2019 Western Digital Corporation or its affiliates.
5  *
6  * Authors:
7  *   Anup Patel <anup.patel@wdc.com>
8  */
9 
10 #ifndef __SBI_PLATFORM_H__
11 #define __SBI_PLATFORM_H__
12 
13 /** OpenSBI 32-bit platform version with:
14  *  1. upper 16-bits as major number
15  *  2. lower 16-bits as minor number
16  */
17 #define SBI_PLATFORM_VERSION(Major, Minor) ((Major << 16) | Minor)
18 
19 /** Offset of opensbi_version in struct sbi_platform */
20 #define SBI_PLATFORM_OPENSBI_VERSION_OFFSET (0x00)
21 /** Offset of platform_version in struct sbi_platform */
22 #define SBI_PLATFORM_VERSION_OFFSET (0x04)
23 /** Offset of name in struct sbi_platform */
24 #define SBI_PLATFORM_NAME_OFFSET (0x08)
25 /** Offset of features in struct sbi_platform */
26 #define SBI_PLATFORM_FEATURES_OFFSET (0x48)
27 /** Offset of hart_count in struct sbi_platform */
28 #define SBI_PLATFORM_HART_COUNT_OFFSET (0x50)
29 /** Offset of hart_stack_size in struct sbi_platform */
30 #define SBI_PLATFORM_HART_STACK_SIZE_OFFSET (0x54)
31 /** Offset of disabled_hart_mask in struct sbi_platform */
32 #define SBI_PLATFORM_DISABLED_HART_OFFSET (0x58)
33 /** Offset of platform_ops_addr in struct sbi_platform */
34 #define SBI_PLATFORM_OPS_OFFSET (0x60)
35 /** Offset of firmware_context in struct sbi_platform */
36 #define SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET (0x60 + __SIZEOF_POINTER__)
37 
38 #define SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT		(1UL << 12)
39 
40 #ifndef __ASSEMBLY__
41 
42 #include <sbi/sbi_ecall.h>
43 #include <sbi/sbi_error.h>
44 #include <sbi/sbi_scratch.h>
45 #include <sbi/sbi_trap.h>
46 #include <sbi/sbi_version.h>
47 
48 /** Possible feature flags of a platform */
49 enum sbi_platform_features {
50 	/** Platform has timer value */
51 	SBI_PLATFORM_HAS_TIMER_VALUE = (1 << 0),
52 	/** Platform has HART hotplug support */
53 	SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1),
54 	/** Platform has PMP support */
55 	SBI_PLATFORM_HAS_PMP = (1 << 2),
56 	/** Platform has S-mode counter enable */
57 	SBI_PLATFORM_HAS_SCOUNTEREN = (1 << 3),
58 	/** Platform has M-mode counter enable */
59 	SBI_PLATFORM_HAS_MCOUNTEREN = (1 << 4),
60 	/** Platform has fault delegation support */
61 	SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 5),
62 };
63 
64 /** Default feature set for a platform */
65 #define SBI_PLATFORM_DEFAULT_FEATURES                                \
66 	(SBI_PLATFORM_HAS_TIMER_VALUE | SBI_PLATFORM_HAS_PMP |       \
67 	 SBI_PLATFORM_HAS_SCOUNTEREN | SBI_PLATFORM_HAS_MCOUNTEREN | \
68 	 SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
69 
70 /** Platform functions */
71 struct sbi_platform_operations {
72 	/** Platform early initialization */
73 	int (*early_init)(bool cold_boot);
74 	/** Platform final initialization */
75 	int (*final_init)(bool cold_boot);
76 
77 	/** Platform early exit */
78 	void (*early_exit)(void);
79 	/** Platform final exit */
80 	void (*final_exit)(void);
81 
82 	/** For platforms that do not implement misa, non-standard
83 	 * methods are needed to determine cpu extension.
84 	 */
85 	int (*misa_check_extension)(char ext);
86 
87 	/** For platforms that do not implement misa, non-standard
88 	 * methods are needed to get MXL field of misa.
89 	 */
90 	int (*misa_get_xlen)(void);
91 
92 	/** Get number of PMP regions for given HART */
93 	u32 (*pmp_region_count)(u32 hartid);
94 	/**
95 	 * Get PMP regions details (namely: protection, base address,
96 	 * and size) for given HART
97 	 */
98 	int (*pmp_region_info)(u32 hartid, u32 index, ulong *prot, ulong *addr,
99 			       ulong *log2size);
100 
101 	/** Write a character to the platform console output */
102 	void (*console_putc)(char ch);
103 	/** Read a character from the platform console input */
104 	int (*console_getc)(void);
105 	/** Initialize the platform console */
106 	int (*console_init)(void);
107 
108 	/** Initialize the platform interrupt controller for current HART */
109 	int (*irqchip_init)(bool cold_boot);
110 	/** Exit the platform interrupt controller for current HART */
111 	void (*irqchip_exit)(void);
112 
113 	/** Send IPI to a target HART */
114 	void (*ipi_send)(u32 target_hart);
115 	/** Clear IPI for a target HART */
116 	void (*ipi_clear)(u32 target_hart);
117 	/** Initialize IPI for current HART */
118 	int (*ipi_init)(bool cold_boot);
119 	/** Exit IPI for current HART */
120 	void (*ipi_exit)(void);
121 
122 	/** Get tlb flush limit value **/
123 	u64 (*get_tlbr_flush_limit)(void);
124 
125 	/** Get platform timer value */
126 	u64 (*timer_value)(void);
127 	/** Start platform timer event for current HART */
128 	void (*timer_event_start)(u64 next_event);
129 	/** Stop platform timer event for current HART */
130 	void (*timer_event_stop)(void);
131 	/** Initialize platform timer for current HART */
132 	int (*timer_init)(bool cold_boot);
133 	/** Exit platform timer for current HART */
134 	void (*timer_exit)(void);
135 
136 	/** Reboot the platform */
137 	int (*system_reboot)(u32 type);
138 	/** Shutdown or poweroff the platform */
139 	int (*system_shutdown)(u32 type);
140 
141 	/** platform specific SBI extension implementation probe function */
142 	int (*vendor_ext_check)(long extid);
143 	/** platform specific SBI extension implementation provider */
144 	int (*vendor_ext_provider)(long extid, long funcid,
145 				   unsigned long *args,
146 				   unsigned long *out_value,
147 				   struct sbi_trap_info *out_trap);
148 } __packed;
149 
150 /** Representation of a platform */
151 struct sbi_platform {
152 	/**
153 	 * OpenSBI version this sbi_platform is based on.
154 	 * It's a 32-bit value where upper 16-bits are major number
155 	 * and lower 16-bits are minor number
156 	 */
157 	u32 opensbi_version;
158 	/**
159 	 * OpenSBI platform version released by vendor.
160 	 * It's a 32-bit value where upper 16-bits are major number
161 	 * and lower 16-bits are minor number
162 	 */
163 	u32 platform_version;
164 	/** Name of the platform */
165 	char name[64];
166 	/** Supported features */
167 	u64 features;
168 	/** Total number of HARTs */
169 	u32 hart_count;
170 	/** Per-HART stack size for exception/interrupt handling */
171 	u32 hart_stack_size;
172 	/** Mask representing the set of disabled HARTs */
173 	u64 disabled_hart_mask;
174 	/** Pointer to sbi platform operations */
175 	unsigned long platform_ops_addr;
176 	/** Pointer to system firmware specific context */
177 	unsigned long firmware_context;
178 } __packed;
179 
180 /** Get pointer to sbi_platform for sbi_scratch pointer */
181 #define sbi_platform_ptr(__s) \
182 	((const struct sbi_platform *)((__s)->platform_addr))
183 /** Get pointer to sbi_platform for current HART */
184 #define sbi_platform_thishart_ptr() ((const struct sbi_platform *) \
185 	(sbi_scratch_thishart_ptr()->platform_addr))
186 /** Get pointer to platform_ops_addr from platform pointer **/
187 #define sbi_platform_ops(__p) \
188 	((const struct sbi_platform_operations *)(__p)->platform_ops_addr)
189 
190 /** Check whether the platform supports timer value */
191 #define sbi_platform_has_timer_value(__p) \
192 	((__p)->features & SBI_PLATFORM_HAS_TIMER_VALUE)
193 /** Check whether the platform supports HART hotplug */
194 #define sbi_platform_has_hart_hotplug(__p) \
195 	((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG)
196 /** Check whether the platform has PMP support */
197 #define sbi_platform_has_pmp(__p) ((__p)->features & SBI_PLATFORM_HAS_PMP)
198 /** Check whether the platform supports scounteren CSR */
199 #define sbi_platform_has_scounteren(__p) \
200 	((__p)->features & SBI_PLATFORM_HAS_SCOUNTEREN)
201 /** Check whether the platform supports mcounteren CSR */
202 #define sbi_platform_has_mcounteren(__p) \
203 	((__p)->features & SBI_PLATFORM_HAS_MCOUNTEREN)
204 /** Check whether the platform supports fault delegation */
205 #define sbi_platform_has_mfaults_delegation(__p) \
206 	((__p)->features & SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
207 
208 /**
209  * Get name of the platform
210  *
211  * @param plat pointer to struct sbi_platform
212  *
213  * @return pointer to platform name on success and "Unknown" on failure
214  */
sbi_platform_name(const struct sbi_platform * plat)215 static inline const char *sbi_platform_name(const struct sbi_platform *plat)
216 {
217 	if (plat)
218 		return plat->name;
219 	return "Unknown";
220 }
221 
222 /**
223  * Check whether the given HART is disabled
224  *
225  * @param plat pointer to struct sbi_platform
226  * @param hartid HART ID
227  *
228  * @return TRUE if HART is disabled and FALSE otherwise
229  */
sbi_platform_hart_disabled(const struct sbi_platform * plat,u32 hartid)230 static inline bool sbi_platform_hart_disabled(const struct sbi_platform *plat,
231 					      u32 hartid)
232 {
233 	if (plat && (plat->disabled_hart_mask & (1 << hartid)))
234 		return TRUE;
235 	return FALSE;
236 }
237 
238 /**
239  * Get platform specific tlb range flush maximum value. Any request with size
240  * higher than this is upgraded to a full flush.
241  *
242  * @param plat pointer to struct sbi_platform
243  *
244  * @return tlb range flush limit value. Returns a default (page size) if not
245  * defined by platform.
246  */
sbi_platform_tlbr_flush_limit(const struct sbi_platform * plat)247 static inline u64 sbi_platform_tlbr_flush_limit(const struct sbi_platform *plat)
248 {
249 	if (plat && sbi_platform_ops(plat)->get_tlbr_flush_limit)
250 		return sbi_platform_ops(plat)->get_tlbr_flush_limit();
251 	return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT;
252 }
253 
254 /**
255  * Get total number of HARTs supported by the platform
256  *
257  * @param plat pointer to struct sbi_platform
258  *
259  * @return total number of HARTs
260  */
sbi_platform_hart_count(const struct sbi_platform * plat)261 static inline u32 sbi_platform_hart_count(const struct sbi_platform *plat)
262 {
263 	if (plat)
264 		return plat->hart_count;
265 	return 0;
266 }
267 
268 /**
269  * Get per-HART stack size for exception/interrupt handling
270  *
271  * @param plat pointer to struct sbi_platform
272  *
273  * @return stack size in bytes
274  */
sbi_platform_hart_stack_size(const struct sbi_platform * plat)275 static inline u32 sbi_platform_hart_stack_size(const struct sbi_platform *plat)
276 {
277 	if (plat)
278 		return plat->hart_stack_size;
279 	return 0;
280 }
281 
282 /**
283  * Early initialization for current HART
284  *
285  * @param plat pointer to struct sbi_platform
286  * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
287  *
288  * @return 0 on success and negative error code on failure
289  */
sbi_platform_early_init(const struct sbi_platform * plat,bool cold_boot)290 static inline int sbi_platform_early_init(const struct sbi_platform *plat,
291 					  bool cold_boot)
292 {
293 	if (plat && sbi_platform_ops(plat)->early_init)
294 		return sbi_platform_ops(plat)->early_init(cold_boot);
295 	return 0;
296 }
297 
298 /**
299  * Final initialization for current HART
300  *
301  * @param plat pointer to struct sbi_platform
302  * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
303  *
304  * @return 0 on success and negative error code on failure
305  */
sbi_platform_final_init(const struct sbi_platform * plat,bool cold_boot)306 static inline int sbi_platform_final_init(const struct sbi_platform *plat,
307 					  bool cold_boot)
308 {
309 	if (plat && sbi_platform_ops(plat)->final_init)
310 		return sbi_platform_ops(plat)->final_init(cold_boot);
311 	return 0;
312 }
313 
314 /**
315  * Early exit for current HART
316  *
317  * @param plat pointer to struct sbi_platform
318  */
sbi_platform_early_exit(const struct sbi_platform * plat)319 static inline void sbi_platform_early_exit(const struct sbi_platform *plat)
320 {
321 	if (plat && sbi_platform_ops(plat)->early_exit)
322 		sbi_platform_ops(plat)->early_exit();
323 }
324 
325 /**
326  * Final exit for current HART
327  *
328  * @param plat pointer to struct sbi_platform
329  */
sbi_platform_final_exit(const struct sbi_platform * plat)330 static inline void sbi_platform_final_exit(const struct sbi_platform *plat)
331 {
332 	if (plat && sbi_platform_ops(plat)->final_exit)
333 		sbi_platform_ops(plat)->final_exit();
334 }
335 
336 /**
337  * Check CPU extension in MISA
338  *
339  * @param plat pointer to struct sbi_platform
340  * @param ext shorthand letter for CPU extensions
341  *
342  * @return zero for not-supported and non-zero for supported
343  */
sbi_platform_misa_extension(const struct sbi_platform * plat,char ext)344 static inline int sbi_platform_misa_extension(const struct sbi_platform *plat,
345 					      char ext)
346 {
347 	if (plat && sbi_platform_ops(plat)->misa_check_extension)
348 		return sbi_platform_ops(plat)->misa_check_extension(ext);
349 	return 0;
350 }
351 
352 /**
353  * Get MXL field of MISA
354  *
355  * @param plat pointer to struct sbi_platform
356  *
357  * @return 1/2/3 on success and error code on failure
358  */
sbi_platform_misa_xlen(const struct sbi_platform * plat)359 static inline int sbi_platform_misa_xlen(const struct sbi_platform *plat)
360 {
361 	if (plat && sbi_platform_ops(plat)->misa_get_xlen)
362 		return sbi_platform_ops(plat)->misa_get_xlen();
363 	return -1;
364 }
365 
366 /**
367  * Get the number of PMP regions of a HART
368  *
369  * @param plat pointer to struct sbi_platform
370  * @param hartid HART ID
371  *
372  * @return number of PMP regions
373  */
sbi_platform_pmp_region_count(const struct sbi_platform * plat,u32 hartid)374 static inline u32 sbi_platform_pmp_region_count(const struct sbi_platform *plat,
375 						u32 hartid)
376 {
377 	if (plat && sbi_platform_ops(plat)->pmp_region_count)
378 		return sbi_platform_ops(plat)->pmp_region_count(hartid);
379 	return 0;
380 }
381 
382 /**
383  * Get PMP regions details (namely: protection, base address,
384  * and size) of a HART
385  *
386  * @param plat pointer to struct sbi_platform
387  * @param hartid HART ID
388  * @param index index of PMP region for which we want details
389  * @param prot output pointer for PMP region protection
390  * @param addr output pointer for PMP region base address
391  * @param log2size output pointer for log-of-2 PMP region size
392  *
393  * @return 0 on success and negative error code on failure
394  */
sbi_platform_pmp_region_info(const struct sbi_platform * plat,u32 hartid,u32 index,ulong * prot,ulong * addr,ulong * log2size)395 static inline int sbi_platform_pmp_region_info(const struct sbi_platform *plat,
396 						u32 hartid, u32 index,
397 						ulong *prot, ulong *addr,
398 						ulong *log2size)
399 {
400 	if (plat && sbi_platform_ops(plat)->pmp_region_info)
401 		return sbi_platform_ops(plat)->pmp_region_info(hartid, index, prot, addr,
402                                                                               log2size);
403 	return 0;
404 }
405 
406 /**
407  * Write a character to the platform console output
408  *
409  * @param plat pointer to struct sbi_platform
410  * @param ch character to write
411  */
sbi_platform_console_putc(const struct sbi_platform * plat,char ch)412 static inline void sbi_platform_console_putc(const struct sbi_platform *plat,
413 						char ch)
414 {
415 	if (plat && sbi_platform_ops(plat)->console_putc)
416 		sbi_platform_ops(plat)->console_putc(ch);
417 }
418 
419 /**
420  * Read a character from the platform console input
421  *
422  * @param plat pointer to struct sbi_platform
423  *
424  * @return character read from console input
425  */
sbi_platform_console_getc(const struct sbi_platform * plat)426 static inline int sbi_platform_console_getc(const struct sbi_platform *plat)
427 {
428 	if (plat && sbi_platform_ops(plat)->console_getc)
429 		return sbi_platform_ops(plat)->console_getc();
430 	return -1;
431 }
432 
433 /**
434  * Initialize the platform console
435  *
436  * @param plat pointer to struct sbi_platform
437  *
438  * @return 0 on success and negative error code on failure
439  */
sbi_platform_console_init(const struct sbi_platform * plat)440 static inline int sbi_platform_console_init(const struct sbi_platform *plat)
441 {
442 	if (plat && sbi_platform_ops(plat)->console_init)
443 		return sbi_platform_ops(plat)->console_init();
444 	return 0;
445 }
446 
447 /**
448  * Initialize the platform interrupt controller for current HART
449  *
450  * @param plat pointer to struct sbi_platform
451  * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
452  *
453  * @return 0 on success and negative error code on failure
454  */
sbi_platform_irqchip_init(const struct sbi_platform * plat,bool cold_boot)455 static inline int sbi_platform_irqchip_init(const struct sbi_platform *plat,
456 					    bool cold_boot)
457 {
458 	if (plat && sbi_platform_ops(plat)->irqchip_init)
459 		return sbi_platform_ops(plat)->irqchip_init(cold_boot);
460 	return 0;
461 }
462 
463 /**
464  * Exit the platform interrupt controller for current HART
465  *
466  * @param plat pointer to struct sbi_platform
467  */
sbi_platform_irqchip_exit(const struct sbi_platform * plat)468 static inline void sbi_platform_irqchip_exit(const struct sbi_platform *plat)
469 {
470 	if (plat && sbi_platform_ops(plat)->irqchip_exit)
471 		sbi_platform_ops(plat)->irqchip_exit();
472 }
473 
474 /**
475  * Send IPI to a target HART
476  *
477  * @param plat pointer to struct sbi_platform
478  * @param target_hart HART ID of IPI target
479  */
sbi_platform_ipi_send(const struct sbi_platform * plat,u32 target_hart)480 static inline void sbi_platform_ipi_send(const struct sbi_platform *plat,
481 					 u32 target_hart)
482 {
483 	if (plat && sbi_platform_ops(plat)->ipi_send)
484 		sbi_platform_ops(plat)->ipi_send(target_hart);
485 }
486 
487 /**
488  * Clear IPI for a target HART
489  *
490  * @param plat pointer to struct sbi_platform
491  * @param target_hart HART ID of IPI target
492  */
sbi_platform_ipi_clear(const struct sbi_platform * plat,u32 target_hart)493 static inline void sbi_platform_ipi_clear(const struct sbi_platform *plat,
494 					  u32 target_hart)
495 {
496 	if (plat && sbi_platform_ops(plat)->ipi_clear)
497 		sbi_platform_ops(plat)->ipi_clear(target_hart);
498 }
499 
500 /**
501  * Initialize the platform IPI support for current HART
502  *
503  * @param plat pointer to struct sbi_platform
504  * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
505  *
506  * @return 0 on success and negative error code on failure
507  */
sbi_platform_ipi_init(const struct sbi_platform * plat,bool cold_boot)508 static inline int sbi_platform_ipi_init(const struct sbi_platform *plat,
509 					bool cold_boot)
510 {
511 	if (plat && sbi_platform_ops(plat)->ipi_init)
512 		return sbi_platform_ops(plat)->ipi_init(cold_boot);
513 	return 0;
514 }
515 
516 /**
517  * Exit the platform IPI support for current HART
518  *
519  * @param plat pointer to struct sbi_platform
520  */
sbi_platform_ipi_exit(const struct sbi_platform * plat)521 static inline void sbi_platform_ipi_exit(const struct sbi_platform *plat)
522 {
523 	if (plat && sbi_platform_ops(plat)->ipi_exit)
524 		sbi_platform_ops(plat)->ipi_exit();
525 }
526 
527 /**
528  * Get platform timer value
529  *
530  * @param plat pointer to struct sbi_platform
531  *
532  * @return 64-bit timer value
533  */
sbi_platform_timer_value(const struct sbi_platform * plat)534 static inline u64 sbi_platform_timer_value(const struct sbi_platform *plat)
535 {
536 	if (plat && sbi_platform_ops(plat)->timer_value)
537 		return sbi_platform_ops(plat)->timer_value();
538 	return 0;
539 }
540 
541 /**
542  * Start platform timer event for current HART
543  *
544  * @param plat pointer to struct struct sbi_platform
545  * @param next_event timer value when timer event will happen
546  */
547 static inline void
sbi_platform_timer_event_start(const struct sbi_platform * plat,u64 next_event)548 sbi_platform_timer_event_start(const struct sbi_platform *plat, u64 next_event)
549 {
550 	if (plat && sbi_platform_ops(plat)->timer_event_start)
551 		sbi_platform_ops(plat)->timer_event_start(next_event);
552 }
553 
554 /**
555  * Stop platform timer event for current HART
556  *
557  * @param plat pointer to struct sbi_platform
558  */
559 static inline void
sbi_platform_timer_event_stop(const struct sbi_platform * plat)560 sbi_platform_timer_event_stop(const struct sbi_platform *plat)
561 {
562 	if (plat && sbi_platform_ops(plat)->timer_event_stop)
563 		sbi_platform_ops(plat)->timer_event_stop();
564 }
565 
566 /**
567  * Initialize the platform timer for current HART
568  *
569  * @param plat pointer to struct sbi_platform
570  * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
571  *
572  * @return 0 on success and negative error code on failure
573  */
sbi_platform_timer_init(const struct sbi_platform * plat,bool cold_boot)574 static inline int sbi_platform_timer_init(const struct sbi_platform *plat,
575 					  bool cold_boot)
576 {
577 	if (plat && sbi_platform_ops(plat)->timer_init)
578 		return sbi_platform_ops(plat)->timer_init(cold_boot);
579 	return 0;
580 }
581 
582 /**
583  * Exit the platform timer for current HART
584  *
585  * @param plat pointer to struct sbi_platform
586  */
sbi_platform_timer_exit(const struct sbi_platform * plat)587 static inline void sbi_platform_timer_exit(const struct sbi_platform *plat)
588 {
589 	if (plat && sbi_platform_ops(plat)->timer_exit)
590 		sbi_platform_ops(plat)->timer_exit();
591 }
592 
593 /**
594  * Reboot the platform
595  *
596  * @param plat pointer to struct sbi_platform
597  * @param type type of reboot
598  *
599  * @return 0 on success and negative error code on failure
600  */
sbi_platform_system_reboot(const struct sbi_platform * plat,u32 type)601 static inline int sbi_platform_system_reboot(const struct sbi_platform *plat,
602 					     u32 type)
603 {
604 	if (plat && sbi_platform_ops(plat)->system_reboot)
605 		return sbi_platform_ops(plat)->system_reboot(type);
606 	return 0;
607 }
608 
609 /**
610  * Shutdown or poweroff the platform
611  *
612  * @param plat pointer to struct sbi_platform
613  * @param type type of shutdown or poweroff
614  *
615  * @return 0 on success and negative error code on failure
616  */
sbi_platform_system_shutdown(const struct sbi_platform * plat,u32 type)617 static inline int sbi_platform_system_shutdown(const struct sbi_platform *plat,
618 					       u32 type)
619 {
620 	if (plat && sbi_platform_ops(plat)->system_shutdown)
621 		return sbi_platform_ops(plat)->system_shutdown(type);
622 	return 0;
623 }
624 
625 /**
626  * Check if a vendor extension is implemented or not.
627  *
628  * @param plat pointer to struct sbi_platform
629  * @param extid	vendor SBI extension id
630  *
631  * @return 0 if extid is not implemented and 1 if implemented
632  */
sbi_platform_vendor_ext_check(const struct sbi_platform * plat,long extid)633 static inline int sbi_platform_vendor_ext_check(const struct sbi_platform *plat,
634 						long extid)
635 {
636 	if (plat && sbi_platform_ops(plat)->vendor_ext_check)
637 		return sbi_platform_ops(plat)->vendor_ext_check(extid);
638 
639 	return 0;
640 }
641 
642 /**
643  * Invoke platform specific vendor SBI extension implementation.
644  *
645  * @param plat pointer to struct sbi_platform
646  * @param extid	vendor SBI extension id
647  * @param funcid SBI function id within the extension id
648  * @param args pointer to arguments passed by the caller
649  * @param out_value output value that can be filled by the callee
650  * @param out_trap trap info that can be filled by the callee
651  *
652  * @return 0 on success and negative error code on failure
653  */
sbi_platform_vendor_ext_provider(const struct sbi_platform * plat,long extid,long funcid,unsigned long * args,unsigned long * out_value,struct sbi_trap_info * out_trap)654 static inline int sbi_platform_vendor_ext_provider(
655 					const struct sbi_platform *plat,
656 					long extid, long funcid,
657 					unsigned long *args,
658 					unsigned long *out_value,
659 					struct sbi_trap_info *out_trap)
660 {
661 	if (plat && sbi_platform_ops(plat)->vendor_ext_provider) {
662 		return sbi_platform_ops(plat)->vendor_ext_provider(extid,
663 								funcid, args,
664 								out_value,
665 								out_trap);
666 	}
667 
668 	return SBI_ENOTSUPP;
669 }
670 
671 #endif
672 
673 #endif
674