fgic_cpu_interface.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: fgic_cpu_interface.h
  15. * Date: 2022-03-28 14:55:27
  16. * LastEditTime: 2022-03-28 14:55:27
  17. * Description:  This file is for
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. */
  23. #ifndef DRIVERS_CPU_INTERFACE_H
  24. #define DRIVERS_CPU_INTERFACE_H
  25. #include "ftypes.h"
  26. #define FGIC_ICC_SGI1R_INTID_MASK 0xFULL /* The INTID of the SGI. */
  27. #define GICC_SGIR_IRM_BITS SGI_ROUTING_MODE
  28. typedef enum
  29. {
  30. GICC_SRE_SRE = (1 << 0),
  31. GICC_SRE_DFB = (1 << 1),
  32. GICC_SRE_DIB = (1 << 2),
  33. GICC_SRE_ENABLE = (1 << 3)
  34. } GICC_SRE_BITS;
  35. typedef enum
  36. {
  37. GICC_CTLR_CBPR = (1 << 0),
  38. GICC_CTLR_CBPR_EL1S = (1 << 0),
  39. GICC_CTLR_EOIMODE = (1 << 1),
  40. GICC_CTLR_CBPR_EL1NS = (1 << 1),
  41. GICC_CTLR_EOIMODE_EL3 = (1 << 2),
  42. GICC_CTLR_EOIMODE_EL1S = (1 << 3),
  43. GICC_CTLR_EOIMODE_EL1NS = (1 << 4), /* GICC_EOIR and GICC_AEOIR provide priority drop functionality only. GICC_DIR provides interrupt deactivation functionality. */
  44. GICC_CTLR_RM = (1 << 5),
  45. GICC_CTLR_PMHE = (1 << 6)
  46. } GICC_CTLR_BITS;
  47. #ifdef __aarch64__
  48. void FGicSetICC_SRE_EL3(GICC_SRE_BITS bits);
  49. void FGicSetICC_SRE_EL2(GICC_SRE_BITS bits);
  50. void FGicSetICC_SRE_EL1(GICC_SRE_BITS bits);
  51. u32 FGicGetICC_SRE_EL3(void);
  52. u32 FGicGetICC_SRE_EL2(void);
  53. u32 FGicGetICC_SRE_EL1(void);
  54. void FGicEnableGroup0(void);
  55. void FGicDisableGroup0(void);
  56. void FGicEnableGroup1_EL1(void);
  57. void FGicEnableGroup1_EL3(void);
  58. void FGicDisableGroup1_EL1(void);
  59. void FGicDisableGroup1_EL3(void);
  60. void FGicSetICC_CTLR_EL3(GICC_CTLR_BITS reg_bits);
  61. void FGicSetICC_CTLR_EL1(GICC_CTLR_BITS reg_bits);
  62. u32 FGicGetICC_CTLR_EL3(void);
  63. u32 FGicGetICC_CTLR_EL1(void);
  64. u32 FGicWriteICC_APR0(void);
  65. s32 FGicGetICC_APR1(void);
  66. void FGicSetICC_EOIR0(u32 intnum);
  67. void FGicSetICC_EOIR1(u32 intnum);
  68. void FGicSetICC_DIR(u32 intnum);
  69. void FGicSetICC_PMR(u32 priority_mask);
  70. u32 FGicGetICC_PMR(void);
  71. u32 FGicGetICC_BPR1(void);
  72. void FGicSetICC_BPR1(u32 binary_point);
  73. u32 FGicGetICC_BPR0(void);
  74. void FGicSetICC_BPR0(u32 binary_point);
  75. u32 FGicGetICC_HPPIR1(void);
  76. void FGicSetICC_HPPIR1(u32 binary_point);
  77. u32 FGicGetICC_HPPIR0(void);
  78. void FGicSetICC_HPPIR0(u32 binary_point);
  79. u32 FGicGetICC_RPR(void);
  80. /* SGI interface */
  81. void FGicSetICC_SGI0R(u32 intnum, u32 target_list, GICC_SGIR_IRM_BITS mode, u64 affinity_list);
  82. void FGicSetICC_SGI1R(u32 intnum, u32 target_list, GICC_SGIR_IRM_BITS mode, u64 affinity_list);
  83. void FGicSetICC_ASGI1R(u32 intnum, u32 target_list, GICC_SGIR_IRM_BITS mode, u64 affinity_list);
  84. #else /* aarch32 */
  85. /* For AArch32 state, accesses to GIC registers that are visible in the System register */
  86. #define FGIC_SYS_READ32(CR, Rt) __asm__ volatile("MRC " CR \
  87. : "=r"(Rt) \
  88. : \
  89. : "memory")
  90. #define FGIC_SYS_WRITE32(CR, Rt) __asm__ volatile("MCR " CR \
  91. : \
  92. : "r"(Rt) \
  93. : "memory")
  94. #define FGIC_SYS_WRITE64(cp, op1, Rt, CRm) __asm__ volatile("MCRR p" #cp ", " #op1 ", %Q0, %R0, c" #CRm \
  95. : \
  96. : "r"(Rt) \
  97. : "memory")
  98. #define ICC_IAR0 "p15, 0, %0, c12, c8, 0"
  99. #define ICC_IAR1 "p15, 0, %0, c12, c12, 0"
  100. /* writes to this register to inform the CPU interface
  101. that it has completed the processing */
  102. #define ICC_EOIR0 "p15, 0, %0, c12, c8, 1"
  103. #define ICC_EOIR1 "p15, 0, %0, c12, c12, 1"
  104. /* GET the INTID of highest priority pending interrupt */
  105. #define ICC_HPPIR0 "p15, 0, %0, c12, c8, 2"
  106. #define ICC_HPPIR1 "p15, 0, %0, c12, c12, 2"
  107. #define ICC_BPR0 "p15, 0, %0, c12, c8, 3"
  108. #define ICC_BPR1 "p15, 0, %0, c12, c12, 3"
  109. #define ICC_DIR "p15, 0, %0, c12, c11, 1"
  110. #define ICC_PMR "p15, 0, %0, c4, c6, 0"
  111. #define ICC_RPR "p15, 0, %0, c12, c11, 3"
  112. #define ICC_CTLR "p15, 0, %0, c12, c12, 4"
  113. #define ICC_MCTLR "p15, 6, %0, c12, c12, 4"
  114. #define ICC_SRE "p15, 0, %0, c12, c12, 5"
  115. #define ICC_HSRE "p15, 4, %0, c12, c9, 5"
  116. #define ICC_MSRE "p15, 6, %0, c12, c12, 5"
  117. #define ICC_IGRPEN0 "p15, 0, %0, c12, c12, 6"
  118. #define ICC_IGRPEN1 "p15, 0, %0, c12, c12, 7"
  119. #define ICC_MGRPEN1 "p15, 6, %0, c12, c12, 7"
  120. #define FGicSetICC_SRE_EL1 FGicSetICC_SRE
  121. #define FGicSetICC_SRE_EL2 FGicSetICC_SRE
  122. #define FGicSetICC_SRE_EL3 FGicSetICC_SRE
  123. /**
  124. * @name:
  125. * @msg: void FGicSetICC_SRE(GICC_SRE_BITS bits) --- Interrupt Controller System Register Enable
  126. * @return {*}
  127. */
  128. static inline void FGicSetICC_SRE(GICC_SRE_BITS bits)
  129. {
  130. FGIC_SYS_WRITE32(ICC_SRE, (u32)bits);
  131. __asm__ volatile("isb 0xF" ::
  132. : "memory");
  133. }
  134. #define FGicGetICC_SRE_EL3 FGicGetICC_SRE
  135. #define FGicGetICC_SRE_EL2 FGicGetICC_SRE
  136. #define FGicGetICC_SRE_EL1 FGicGetICC_SRE
  137. /**
  138. * @name:
  139. * @msg: u32 FGicGetICC_SRE(void) -- Interrupt Controller System Register Enable
  140. * @return {*}
  141. */
  142. static inline u32 FGicGetICC_SRE(void)
  143. {
  144. u32 value;
  145. FGIC_SYS_READ32(ICC_SRE, value);
  146. return value;
  147. }
  148. /**
  149. * @name:
  150. * @msg: void FGicEnableGroup0(void)
  151. * @return {*}
  152. */
  153. static inline void FGicEnableGroup0(void)
  154. {
  155. u32 value = 1;
  156. FGIC_SYS_WRITE32(ICC_IGRPEN0, value);
  157. __asm__ volatile("isb 0xF" ::
  158. : "memory");
  159. }
  160. /**
  161. * @name:
  162. * @msg: void FGicDisableGroup0(void)
  163. * @return {*}
  164. */
  165. static inline void FGicDisableGroup0(void)
  166. {
  167. u32 value = 0;
  168. FGIC_SYS_WRITE32(ICC_IGRPEN0, value);
  169. __asm__ volatile("isb 0xF" ::
  170. : "memory");
  171. }
  172. #define FGicEnableGroup1_EL3 FGicEnableGroup1
  173. #define FGicEnableGroup1_EL1 FGicEnableGroup1
  174. /**
  175. * @name:
  176. * @msg:
  177. * @return {*}
  178. */
  179. static inline void FGicEnableGroup1(void)
  180. {
  181. u32 value = 1;
  182. FGIC_SYS_WRITE32(ICC_IGRPEN1, value);
  183. __asm__ volatile("isb 0xF" ::
  184. : "memory");
  185. }
  186. #define FGicDisableGroup1_EL3 FGicDisableGroup1
  187. #define FGicDisableGroup1_EL1 FGicDisableGroup1
  188. /**
  189. * @name:
  190. * @msg: void FGicDisableGroup1(void)
  191. * @return {*}
  192. */
  193. static inline void FGicDisableGroup1(void)
  194. {
  195. u32 value = 0;
  196. FGIC_SYS_WRITE32(ICC_IGRPEN1, value);
  197. __asm__ volatile("isb 0xF" ::
  198. : "memory");
  199. }
  200. #define FGicSetICC_CTLR_EL3 FGicSetICC_CTLR
  201. #define FGicSetICC_CTLR_EL1 FGicSetICC_CTLR
  202. /**
  203. * @name:
  204. * @msg: void FGicSetICC_CTLR(GICC_CTLR_BITS reg_bits)
  205. * @return {*}
  206. */
  207. static inline void FGicSetICC_CTLR(GICC_CTLR_BITS bits)
  208. {
  209. FGIC_SYS_WRITE32(ICC_CTLR, bits);
  210. __asm__ volatile("isb 0xF" ::
  211. : "memory");
  212. }
  213. #define FGicGetICC_CTLR_EL3 FGicGetICC_CTLR
  214. #define FGicGetICC_CTLR_EL1 FGicGetICC_CTLR
  215. /**
  216. * @name:
  217. * @msg: static inline u32 FGicGetICC_CTLR(void) -- Controls aspects of the behavior of the GIC CPU interface and provides information about the features implemented.
  218. * @return {*}
  219. */
  220. static inline u32 FGicGetICC_CTLR(void)
  221. {
  222. u32 reg;
  223. FGIC_SYS_READ32(ICC_CTLR, reg);
  224. return reg;
  225. }
  226. /**
  227. * @name:
  228. * @msg: static inline u32 FGicWriteICC_APR0(void) -- The PE reads this register to obtain the INTID of the signaled Group 0 interrupt.
  229. * @return {*}
  230. */
  231. static inline u32 FGicWriteICC_APR0(void)
  232. {
  233. u32 reg;
  234. FGIC_SYS_READ32(ICC_IAR0, reg);
  235. return reg;
  236. }
  237. /**
  238. * @name:
  239. * @msg: static inline s32 FGicGetICC_APR1(void) -- The PE reads this register to obtain the INTID of the signaled Group 1 interrupt.
  240. * @return {*}
  241. */
  242. static inline s32 FGicGetICC_APR1(void)
  243. {
  244. s32 reg;
  245. FGIC_SYS_READ32(ICC_IAR1, reg);
  246. return reg;
  247. }
  248. /**
  249. * @name:
  250. * @msg: static inline void FGicSetICC_EOIR0(u32 intnum) -- /* A PE writes to this register to inform the CPU interface that it has completed the processing of the specified Group 0 interrupt
  251. * @return {*}
  252. * @param {u32} intnum
  253. */
  254. static inline void FGicSetICC_EOIR0(u32 intnum)
  255. {
  256. FGIC_SYS_WRITE32(ICC_EOIR0, intnum);
  257. __asm__ volatile("isb 0xF" ::
  258. : "memory");
  259. }
  260. /**
  261. * @name:
  262. * @msg: static inline void FGicSetICC_EOIR1(u32 intnum) -- /* A PE writes to this register to inform the CPU interface that it has completed the processing of the specified Group 1 interrupt
  263. * @return {*}
  264. */
  265. static inline void FGicSetICC_EOIR1(u32 intnum)
  266. {
  267. FGIC_SYS_WRITE32(ICC_EOIR1, intnum);
  268. __asm__ volatile("isb 0xF" ::
  269. : "memory");
  270. }
  271. /**
  272. * @name:
  273. * @msg: static inline void FGicSetICC_DIR(u32 intnum) -- When interrupt priority drop is separated from interrupt deactivation, a write to this register deactivates the specified interrupt.
  274. * @return {*}
  275. */
  276. static inline void FGicSetICC_DIR(u32 intnum)
  277. {
  278. FGIC_SYS_WRITE32(ICC_DIR, intnum);
  279. __asm__ volatile("isb 0xF" ::
  280. : "memory");
  281. }
  282. /**
  283. * @name:
  284. * @msg: static inline void FGicSetICC_PMR(u32 priority_mask) -- Provides an interrupt priority filter.
  285. * @return {*}
  286. */
  287. /**
  288. * @name:
  289. * @msg:
  290. * @param {u32} priority_mask is level for the CPU interface. If the priority of an interrupt is higher than the value
  291. * indicated by this field, the interface signals the interrupt to the PE.
  292. */
  293. static inline void FGicSetICC_PMR(u32 priority_mask)
  294. {
  295. FGIC_SYS_WRITE32(ICC_PMR, priority_mask);
  296. __asm__ volatile("isb 0xF" ::
  297. : "memory");
  298. }
  299. /**
  300. * @name:
  301. * @msg: static inline u32 FGicGetICC_PMR(void)
  302. * @return {*}
  303. */
  304. static inline u32 FGicGetICC_PMR(void)
  305. {
  306. u32 reg;
  307. FGIC_SYS_READ32(ICC_PMR, reg);
  308. return reg;
  309. }
  310. /**
  311. * @name:
  312. * @msg: static inline u32 FGicGetICC_BPR1(void) --- Defines the point at which the priority value fields split into two parts, the group priority field and the subpriority field. The group priority field determines Group 1 interrupt preemption.
  313. * @return {*}
  314. */
  315. static inline u32 FGicGetICC_BPR1(void)
  316. {
  317. u32 reg;
  318. FGIC_SYS_READ32(ICC_BPR1, reg);
  319. return reg;
  320. }
  321. /**
  322. * @name:
  323. * @msg: static inline void FGicSetICC_BPR1(u32 binary_point)
  324. * @return {*}
  325. */
  326. static inline void FGicSetICC_BPR1(u32 binary_point)
  327. {
  328. FGIC_SYS_WRITE32(ICC_BPR1, binary_point);
  329. __asm__ volatile("isb 0xF" ::
  330. : "memory");
  331. }
  332. /**
  333. * @name:
  334. * @msg: static inline u32 FGicGetICC_BPR0(void) --- Defines the point at which the priority value fields split into two parts, the group priority field and the subpriority field. The group priority field determines Group 0 interrupt preemption.
  335. * @return {*}
  336. */
  337. static inline u32 FGicGetICC_BPR0(void)
  338. {
  339. u32 reg;
  340. FGIC_SYS_READ32(ICC_BPR0, reg);
  341. return reg;
  342. }
  343. /**
  344. * @name:
  345. * @msg: static inline void FGicSetICC_BPR0(u32 binary_point)
  346. * @return {*}
  347. */
  348. static inline void FGicSetICC_BPR0(u32 binary_point)
  349. {
  350. FGIC_SYS_WRITE32(ICC_BPR0, binary_point);
  351. __asm__ volatile("isb 0xF" ::
  352. : "memory");
  353. }
  354. /**
  355. * @name:
  356. * @msg: static inline u32 FGicGetICC_HPPIR1(void) --- Indicates the highest priority pending Group 1 interrupt on the CPU interface.
  357. * @return {*}
  358. */
  359. static inline u32 FGicGetICC_HPPIR1(void)
  360. {
  361. u32 reg;
  362. FGIC_SYS_READ32(ICC_HPPIR1, reg);
  363. return reg;
  364. }
  365. /**
  366. * @name:
  367. * @msg: static inline void FGicSetICC_HPPIR1(u32 binary_point)
  368. * @return {*}
  369. */
  370. static inline void FGicSetICC_HPPIR1(u32 binary_point)
  371. {
  372. FGIC_SYS_WRITE32(ICC_HPPIR1, binary_point);
  373. __asm__ volatile("isb 0xF" ::
  374. : "memory");
  375. }
  376. /**
  377. * @name:
  378. * @msg: static inline u32 FGicGetICC_HPPIR0(void) --- Indicates the highest priority pending Group 0 interrupt on the CPU interface.
  379. * @return {*}
  380. */
  381. static inline u32 FGicGetICC_HPPIR0(void)
  382. {
  383. u32 reg;
  384. FGIC_SYS_READ32(ICC_HPPIR0, reg);
  385. return reg;
  386. }
  387. /**
  388. * @name:
  389. * @msg: static inline void FGicSetICC_HPPIR0(u32 binary_point)
  390. * @return {*}
  391. */
  392. static inline void FGicSetICC_HPPIR0(u32 binary_point)
  393. {
  394. FGIC_SYS_WRITE32(ICC_HPPIR0, binary_point);
  395. __asm__ volatile("isb 0xF" ::
  396. : "memory");
  397. }
  398. /**
  399. * @name:
  400. * @msg: static inline u32 FGicGetICC_RPR(void) --- Indicates the Running priority of the CPU interface.
  401. * @return {*}
  402. */
  403. static inline u32 FGicGetICC_RPR(void)
  404. {
  405. u32 reg;
  406. FGIC_SYS_READ32(ICC_RPR, reg);
  407. return reg;
  408. }
  409. /* SGI interface */
  410. /**
  411. * @name:
  412. * @msg: static inline void FGicSetICC_SGI0R(u32 intnum,u32 target_list,GICC_SGIR_IRM_BITS mode,u64 affinity_list) --- Generates Secure Group 0 SGIs
  413. * @return {*}
  414. */
  415. /**
  416. * @name:
  417. * @msg:
  418. * @return {*}
  419. * @param {u32} intnum_bit
  420. * @param {u32} target_list
  421. * @param {GICC_SGIR_IRM_BITS} irm_bit
  422. * @param {u64} affinity_list
  423. */
  424. static inline void FGicSetICC_SGI0R(u32 intnum_bit, u32 target_list, GICC_SGIR_IRM_BITS irm_bit, u64 affinity_list)
  425. {
  426. u64 sgi_val;
  427. sgi_val = intnum_bit; /* The INTID of the SGI. */
  428. sgi_val |= affinity_list ; /* Aff3.Aff2.Aff1 */
  429. sgi_val |= irm_bit ; /* Interrupt Routing Mode. */
  430. sgi_val |= target_list; /* Target List. The set of PEs for which SGI interrupts will be generated. */
  431. __asm__ volatile("dsb 0xF" ::
  432. : "memory");
  433. FGIC_SYS_WRITE64(15, 2, sgi_val, 12);
  434. __asm__ volatile("isb 0xF" ::
  435. : "memory");
  436. }
  437. /**
  438. * @name:
  439. * @msg: static inline void FGicSetICC_SGI1R(u32 intnum,u32 target_list,GICC_SGIR_IRM_BITS mode,u64 affinity_list)
  440. * @return {*}
  441. */
  442. static inline void FGicSetICC_SGI1R(u32 intnum_bit, u32 target_list, GICC_SGIR_IRM_BITS irm_bit, u64 affinity_list)
  443. {
  444. u64 sgi_val;
  445. sgi_val = intnum_bit; /* The INTID of the SGI. */
  446. sgi_val |= affinity_list ; /* Aff3.Aff2.Aff1 */
  447. sgi_val |= irm_bit ; /* Interrupt Routing Mode. */
  448. sgi_val |= target_list; /* Target List. The set of PEs for which SGI interrupts will be generated. */
  449. __asm__ volatile("dsb 0xF" ::
  450. : "memory");
  451. FGIC_SYS_WRITE64(15, 0, sgi_val, 12);
  452. __asm__ volatile("isb 0xF" ::
  453. : "memory");
  454. }
  455. /**
  456. * @name:
  457. * @msg: static inline void FGicSetICC_ASGI1R(u32 intnum,u32 target_list,GICC_SGIR_IRM_BITS mode,u64 affinity_list)
  458. * @return {*}
  459. */
  460. static inline void FGicSetICC_ASGI1R(u32 intnum_bit, u32 target_list, GICC_SGIR_IRM_BITS irm_bit, u64 affinity_list)
  461. {
  462. u64 sgi_val;
  463. sgi_val = intnum_bit; /* The INTID of the SGI. */
  464. sgi_val |= affinity_list ; /* Aff3.Aff2.Aff1 */
  465. sgi_val |= irm_bit ; /* Interrupt Routing Mode. */
  466. sgi_val |= target_list; /* Target List. The set of PEs for which SGI interrupts will be generated. */
  467. __asm__ volatile("dsb 0xF" ::
  468. : "memory");
  469. FGIC_SYS_WRITE64(15, 1, sgi_val, 12);
  470. __asm__ volatile("isb 0xF" ::
  471. : "memory");
  472. }
  473. #endif
  474. #endif