arch_gicv3.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * arch/arm/include/asm/arch_gicv3.h
  4. *
  5. * Copyright (C) 2015 ARM Ltd.
  6. */
  7. #ifndef __ASM_ARCH_GICV3_H
  8. #define __ASM_ARCH_GICV3_H
  9. #ifndef __ASSEMBLY__
  10. #include <linux/io.h>
  11. #include <linux/io-64-nonatomic-lo-hi.h>
  12. #include <asm/barrier.h>
  13. #include <asm/cacheflush.h>
  14. #include <asm/cp15.h>
  15. #define ICC_EOIR1 __ACCESS_CP15(c12, 0, c12, 1)
  16. #define ICC_DIR __ACCESS_CP15(c12, 0, c11, 1)
  17. #define ICC_IAR1 __ACCESS_CP15(c12, 0, c12, 0)
  18. #define ICC_SGI1R __ACCESS_CP15_64(0, c12)
  19. #define ICC_PMR __ACCESS_CP15(c4, 0, c6, 0)
  20. #define ICC_CTLR __ACCESS_CP15(c12, 0, c12, 4)
  21. #define ICC_SRE __ACCESS_CP15(c12, 0, c12, 5)
  22. #define ICC_IGRPEN1 __ACCESS_CP15(c12, 0, c12, 7)
  23. #define ICC_BPR1 __ACCESS_CP15(c12, 0, c12, 3)
  24. #define ICC_RPR __ACCESS_CP15(c12, 0, c11, 3)
  25. #define __ICC_AP0Rx(x) __ACCESS_CP15(c12, 0, c8, 4 | x)
  26. #define ICC_AP0R0 __ICC_AP0Rx(0)
  27. #define ICC_AP0R1 __ICC_AP0Rx(1)
  28. #define ICC_AP0R2 __ICC_AP0Rx(2)
  29. #define ICC_AP0R3 __ICC_AP0Rx(3)
  30. #define __ICC_AP1Rx(x) __ACCESS_CP15(c12, 0, c9, x)
  31. #define ICC_AP1R0 __ICC_AP1Rx(0)
  32. #define ICC_AP1R1 __ICC_AP1Rx(1)
  33. #define ICC_AP1R2 __ICC_AP1Rx(2)
  34. #define ICC_AP1R3 __ICC_AP1Rx(3)
  35. #define CPUIF_MAP(a32, a64) \
  36. static inline void write_ ## a64(u32 val) \
  37. { \
  38. write_sysreg(val, a32); \
  39. } \
  40. static inline u32 read_ ## a64(void) \
  41. { \
  42. return read_sysreg(a32); \
  43. } \
  44. CPUIF_MAP(ICC_EOIR1, ICC_EOIR1_EL1)
  45. CPUIF_MAP(ICC_PMR, ICC_PMR_EL1)
  46. CPUIF_MAP(ICC_AP0R0, ICC_AP0R0_EL1)
  47. CPUIF_MAP(ICC_AP0R1, ICC_AP0R1_EL1)
  48. CPUIF_MAP(ICC_AP0R2, ICC_AP0R2_EL1)
  49. CPUIF_MAP(ICC_AP0R3, ICC_AP0R3_EL1)
  50. CPUIF_MAP(ICC_AP1R0, ICC_AP1R0_EL1)
  51. CPUIF_MAP(ICC_AP1R1, ICC_AP1R1_EL1)
  52. CPUIF_MAP(ICC_AP1R2, ICC_AP1R2_EL1)
  53. CPUIF_MAP(ICC_AP1R3, ICC_AP1R3_EL1)
  54. #define read_gicreg(r) read_##r()
  55. #define write_gicreg(v, r) write_##r(v)
  56. /* Low-level accessors */
  57. static inline void gic_write_dir(u32 val)
  58. {
  59. write_sysreg(val, ICC_DIR);
  60. isb();
  61. }
  62. static inline u32 gic_read_iar(void)
  63. {
  64. u32 irqstat = read_sysreg(ICC_IAR1);
  65. dsb(sy);
  66. return irqstat;
  67. }
  68. static inline void gic_write_ctlr(u32 val)
  69. {
  70. write_sysreg(val, ICC_CTLR);
  71. isb();
  72. }
  73. static inline u32 gic_read_ctlr(void)
  74. {
  75. return read_sysreg(ICC_CTLR);
  76. }
  77. static inline void gic_write_grpen1(u32 val)
  78. {
  79. write_sysreg(val, ICC_IGRPEN1);
  80. isb();
  81. }
  82. static inline void gic_write_sgi1r(u64 val)
  83. {
  84. write_sysreg(val, ICC_SGI1R);
  85. }
  86. static inline u32 gic_read_sre(void)
  87. {
  88. return read_sysreg(ICC_SRE);
  89. }
  90. static inline void gic_write_sre(u32 val)
  91. {
  92. write_sysreg(val, ICC_SRE);
  93. isb();
  94. }
  95. static inline void gic_write_bpr1(u32 val)
  96. {
  97. write_sysreg(val, ICC_BPR1);
  98. }
  99. static inline u32 gic_read_pmr(void)
  100. {
  101. return read_sysreg(ICC_PMR);
  102. }
  103. static inline void gic_write_pmr(u32 val)
  104. {
  105. write_sysreg(val, ICC_PMR);
  106. }
  107. static inline u32 gic_read_rpr(void)
  108. {
  109. return read_sysreg(ICC_RPR);
  110. }
  111. /*
  112. * Even in 32bit systems that use LPAE, there is no guarantee that the I/O
  113. * interface provides true 64bit atomic accesses, so using strd/ldrd doesn't
  114. * make much sense.
  115. * Moreover, 64bit I/O emulation is extremely difficult to implement on
  116. * AArch32, since the syndrome register doesn't provide any information for
  117. * them.
  118. * Consequently, the following IO helpers use 32bit accesses.
  119. */
  120. static inline void __gic_writeq_nonatomic(u64 val, volatile void __iomem *addr)
  121. {
  122. writel_relaxed((u32)val, addr);
  123. writel_relaxed((u32)(val >> 32), addr + 4);
  124. }
  125. static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
  126. {
  127. u64 val;
  128. val = readl_relaxed(addr);
  129. val |= (u64)readl_relaxed(addr + 4) << 32;
  130. return val;
  131. }
  132. #define gic_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l))
  133. /*
  134. * GICD_IROUTERn, contain the affinity values associated to each interrupt.
  135. * The upper-word (aff3) will always be 0, so there is no need for a lock.
  136. */
  137. #define gic_write_irouter(v, c) __gic_writeq_nonatomic(v, c)
  138. /*
  139. * GICR_TYPER is an ID register and doesn't need atomicity.
  140. */
  141. #define gic_read_typer(c) __gic_readq_nonatomic(c)
  142. /*
  143. * GITS_BASER - hi and lo bits may be accessed independently.
  144. */
  145. #define gits_read_baser(c) __gic_readq_nonatomic(c)
  146. #define gits_write_baser(v, c) __gic_writeq_nonatomic(v, c)
  147. /*
  148. * GICR_PENDBASER and GICR_PROPBASE are changed with LPIs disabled, so they
  149. * won't be being used during any updates and can be changed non-atomically
  150. */
  151. #define gicr_read_propbaser(c) __gic_readq_nonatomic(c)
  152. #define gicr_write_propbaser(v, c) __gic_writeq_nonatomic(v, c)
  153. #define gicr_read_pendbaser(c) __gic_readq_nonatomic(c)
  154. #define gicr_write_pendbaser(v, c) __gic_writeq_nonatomic(v, c)
  155. /*
  156. * GICR_xLPIR - only the lower bits are significant
  157. */
  158. #define gic_read_lpir(c) readl_relaxed(c)
  159. #define gic_write_lpir(v, c) writel_relaxed(lower_32_bits(v), c)
  160. /*
  161. * GITS_TYPER is an ID register and doesn't need atomicity.
  162. */
  163. #define gits_read_typer(c) __gic_readq_nonatomic(c)
  164. /*
  165. * GITS_CBASER - hi and lo bits may be accessed independently.
  166. */
  167. #define gits_read_cbaser(c) __gic_readq_nonatomic(c)
  168. #define gits_write_cbaser(v, c) __gic_writeq_nonatomic(v, c)
  169. /*
  170. * GITS_CWRITER - hi and lo bits may be accessed independently.
  171. */
  172. #define gits_write_cwriter(v, c) __gic_writeq_nonatomic(v, c)
  173. /*
  174. * GICR_VPROPBASER - hi and lo bits may be accessed independently.
  175. */
  176. #define gicr_read_vpropbaser(c) __gic_readq_nonatomic(c)
  177. #define gicr_write_vpropbaser(v, c) __gic_writeq_nonatomic(v, c)
  178. /*
  179. * GICR_VPENDBASER - the Valid bit must be cleared before changing
  180. * anything else.
  181. */
  182. static inline void gicr_write_vpendbaser(u64 val, void __iomem *addr)
  183. {
  184. u32 tmp;
  185. tmp = readl_relaxed(addr + 4);
  186. if (tmp & (GICR_VPENDBASER_Valid >> 32)) {
  187. tmp &= ~(GICR_VPENDBASER_Valid >> 32);
  188. writel_relaxed(tmp, addr + 4);
  189. }
  190. /*
  191. * Use the fact that __gic_writeq_nonatomic writes the second
  192. * half of the 64bit quantity after the first.
  193. */
  194. __gic_writeq_nonatomic(val, addr);
  195. }
  196. #define gicr_read_vpendbaser(c) __gic_readq_nonatomic(c)
  197. static inline bool gic_prio_masking_enabled(void)
  198. {
  199. return false;
  200. }
  201. static inline void gic_pmr_mask_irqs(void)
  202. {
  203. /* Should not get called. */
  204. WARN_ON_ONCE(true);
  205. }
  206. static inline void gic_arch_enable_irqs(void)
  207. {
  208. /* Should not get called. */
  209. WARN_ON_ONCE(true);
  210. }
  211. #endif /* !__ASSEMBLY__ */
  212. #endif /* !__ASM_ARCH_GICV3_H */