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