1 // Copyright 2017 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6
7 #pragma once
8 #include <arch/arm64.h>
9 #include <reg.h>
10
11 extern vaddr_t arm_gicv3_gic_base;
12 extern uint64_t arm_gicv3_gicd_offset;
13 extern uint64_t arm_gicv3_gicr_offset;
14 extern uint64_t arm_gicv3_gicr_stride;
15
16 #define BIT_32(bit) (1u << bit)
17 #define BIT_64(bit) (1ul << bit)
18
19 #define GICREG(gic, reg) (*REG32(arm_gicv3_gic_base + (reg)))
20 #define GICREG64(gic, reg) (*REG64(arm_gicv3_gic_base + (reg)))
21 #define GICD_OFFSET arm_gicv3_gicd_offset
22 #define GICR_OFFSET arm_gicv3_gicr_offset
23 #define GICR_STRIDE arm_gicv3_gicr_stride
24
25 #define ICC_CTLR_EL1 "S3_0_C12_C12_4"
26 #define ICC_PMR_EL1 "S3_0_C4_C6_0"
27 #define ICC_IAR1_EL1 "S3_0_C12_C12_0"
28 #define ICC_SRE_EL1 "S3_0_C12_C12_5"
29 #define ICC_BPR1_EL1 "S3_0_C12_C12_3"
30 #define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7"
31 #define ICC_EOIR1_EL1 "S3_0_C12_C12_1"
32 #define ICC_DIR_EL1 "S3_0_C12_C11_1"
33 #define ICC_SGI1R_EL1 "S3_0_C12_C11_5"
34
35 /* distributor registers */
36
37 #define GICD_CTLR (GICD_OFFSET + 0x0000)
38 #define GICD_TYPER (GICD_OFFSET + 0x0004)
39 #define GICD_IIDR (GICD_OFFSET + 0x0008)
40 #define GICD_IGROUPR(n) (GICD_OFFSET + 0x0080 + (n)*4)
41 #define GICD_ISENABLER(n) (GICD_OFFSET + 0x0100 + (n)*4)
42 #define GICD_ICENABLER(n) (GICD_OFFSET + 0x0180 + (n)*4)
43 #define GICD_ISPENDR(n) (GICD_OFFSET + 0x0200 + (n)*4)
44 #define GICD_ICPENDR(n) (GICD_OFFSET + 0x0280 + (n)*4)
45 #define GICD_ISACTIVER(n) (GICD_OFFSET + 0x0300 + (n)*4)
46 #define GICD_ICACTIVER(n) (GICD_OFFSET + 0x0380 + (n)*4)
47 #define GICD_IPRIORITYR(n) (GICD_OFFSET + 0x0400 + (n)*4)
48 #define GICD_ITARGETSR(n) (GICD_OFFSET + 0x0800 + (n)*4)
49 #define GICD_ICFGR(n) (GICD_OFFSET + 0x0c00 + (n)*4)
50 #define GICD_IGRPMODR(n) (GICD_OFFSET + 0x0d00 + (n)*4)
51 #define GICD_NSACR(n) (GICD_OFFSET + 0x0e00 + (n)*4)
52 #define GICD_SGIR (GICD_OFFSET + 0x0f00)
53 #define GICD_CPENDSGIR(n) (GICD_OFFSET + 0x0f10 + (n)*4)
54 #define GICD_SPENDSGIR(n) (GICD_OFFSET + 0x0f20 + (n)*4)
55 #define GICD_IROUTER(n) (GICD_OFFSET + 0x6000 + (n)*8)
56
57 /* GICD_CTLR bit definitions */
58
59 #define CTLR_ENABLE_G0 BIT_32(0)
60 #define CTLR_ENABLE_G1NS BIT_32(1)
61 #define CTLR_ENABLE_G1S BIT_32(2)
62 #define CTLR_RES0 BIT_32(3)
63 #define CTLR_ARE_S BIT_32(4)
64 #define CTLR_ARE_NS BIT_32(5)
65 #define CTLR_DS BIT_32(6)
66 #define CTLR_E1NWF BIT_32(7)
67 #define GICD_CTLR_RWP BIT_32(31)
68
69 /* peripheral identification registers */
70
71 #define GICD_CIDR0 (GICD_OFFSET + 0xfff0)
72 #define GICD_CIDR1 (GICD_OFFSET + 0xfff4)
73 #define GICD_CIDR2 (GICD_OFFSET + 0xfff8)
74 #define GICD_CIDR3 (GICD_OFFSET + 0xfffc)
75 #define GICD_PIDR0 (GICD_OFFSET + 0xffe0)
76 #define GICD_PIDR1 (GICD_OFFSET + 0xffe4)
77 #define GICD_PIDR2 (GICD_OFFSET + 0xffe8)
78 #define GICD_PIDR3 (GICD_OFFSET + 0xffec)
79
80 /* GICD_PIDR bit definitions and masks */
81
82 #define GICD_PIDR2_ARCHREV_SHIFT 4
83 #define GICD_PIDR2_ARCHREV_MASK 0xf
84
85 /* redistributor registers */
86
87 #define GICR_SGI_OFFSET (GICR_OFFSET + 0x10000)
88
89 #define GICR_CTLR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0000)
90 #define GICR_IIDR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0004)
91 #define GICR_TYPER(i, n) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0008 + (n)*4)
92 #define GICR_STATUSR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0010)
93 #define GICR_WAKER(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0014)
94 #define GICR_IGROUPR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0080)
95 #define GICR_IGRPMOD0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0d00)
96 #define GICR_ISENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0100)
97 #define GICR_ICENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0180)
98 #define GICR_ISPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0200)
99 #define GICR_ICPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0280)
100 #define GICR_ISACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0300)
101 #define GICR_ICACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0380)
102 #define GICR_IPRIORITYR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0400)
103 #define GICR_ICFGR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c00)
104 #define GICR_ICFGR1(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c04)
105 #define GICR_NSACR(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0e00)
106
gic_write_ctlr(uint32_t val)107 static inline void gic_write_ctlr(uint32_t val) {
108 __asm__ volatile("msr " ICC_CTLR_EL1 ", %0" :: "r"((uint64_t)val));
109 __isb(ARM_MB_SY);
110 }
111
gic_write_pmr(uint32_t val)112 static inline void gic_write_pmr(uint32_t val) {
113 __asm__ volatile("msr " ICC_PMR_EL1 ", %0" :: "r"((uint64_t)val));
114 __isb(ARM_MB_SY);
115 __dsb(ARM_MB_SY);
116 }
117
gic_write_igrpen(uint32_t val)118 static inline void gic_write_igrpen(uint32_t val) {
119 __asm__ volatile("msr " ICC_IGRPEN1_EL1 ", %0" :: "r"((uint64_t)val));
120 __isb(ARM_MB_SY);
121 }
122
gic_read_sre(void)123 static inline uint32_t gic_read_sre(void) {
124 uint64_t temp;
125 __asm__ volatile("mrs %0, " ICC_SRE_EL1 : "=r"(temp));
126 return (uint32_t)temp;
127 }
128
gic_write_sre(uint32_t val)129 static inline void gic_write_sre(uint32_t val) {
130 __asm__ volatile("msr " ICC_SRE_EL1 ", %0" :: "r"((uint64_t)val));
131 __isb(ARM_MB_SY);
132 }
133
gic_write_eoir(uint32_t val)134 static inline void gic_write_eoir(uint32_t val) {
135 __asm__ volatile("msr " ICC_EOIR1_EL1 ", %0" :: "r"((uint64_t)val));
136 __isb(ARM_MB_SY);
137 }
138
gic_write_dir(uint32_t val)139 static inline void gic_write_dir(uint32_t val) {
140 __asm__ volatile("msr " ICC_DIR_EL1 ", %0" :: "r"((uint64_t)val));
141 __isb(ARM_MB_SY);
142 }
143
gic_read_iar()144 static inline uint32_t gic_read_iar() {
145 uint64_t temp;
146 __asm__ volatile("mrs %0, " ICC_IAR1_EL1 : "=r"(temp));
147 __dsb(ARM_MB_SY);
148 return (uint32_t)temp;
149 }
150
gic_write_sgi1r(uint64_t val)151 static inline void gic_write_sgi1r(uint64_t val) {
152 __asm__ volatile("msr " ICC_SGI1R_EL1 ", %0" :: "r"((uint64_t)val));
153 __isb(ARM_MB_SY);
154 __dsb(ARM_MB_SY);
155 }
156