sbi_platform.h 22 KB

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