1 /*
2  * Copyright (c) 2012-2019 LK Trusty Authors. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #pragma once
24 
25 #include <stdint.h>
26 #include <platform/gic.h>
27 #include <reg.h>
28 
29 #if ARCH_ARM
30 #include <arch/arm.h>
31 #endif
32 #if ARCH_ARM64
33 #include <arch/arm64.h>
34 #endif
35 
36 #ifdef ARCH_ARM
37 /*
38  * AArch32 does not have 64 bit mmio support, but the gic spec allows 32 bit
39  * upper and lower access to _most_ 64 bit gic registers (not GICR_VSGIPENDR,
40  * GICR_VSGIR or GITS_SGIR).
41  */
42 /* TODO: add mmio_read32 when needed */
mmio_write64(volatile uint64_t * ptr64,uint64_t val)43 static inline void mmio_write64(volatile uint64_t *ptr64, uint64_t val) {
44     volatile uint32_t *ptr = (volatile uint32_t *)ptr64;
45     mmio_write32(ptr, (uint32_t)val);
46     mmio_write32(ptr + 1, val >> 32);
47 }
48 #endif
49 
50 struct arm_gic {
51     vaddr_t gicc_vaddr;
52     size_t gicc_size;
53     vaddr_t gicd_vaddr;
54     size_t gicd_size;
55     vaddr_t gicr_vaddr;
56     size_t gicr_size;
57 };
58 
59 #define NUM_ARM_GICS 1
60 
61 extern struct arm_gic arm_gics[NUM_ARM_GICS];
62 
63 #if GIC_VERSION > 2
64 
65 #if WITH_LIB_SM
66 #define ARM_GIC_USE_DOORBELL_NS_IRQ 1
67 #define ARM_GIC_DOORBELL_IRQ 13
68 #endif
69 
70     /* GICv3/v4 */
71 
72 #define GICV3_IRQ_GROUP_GRP0S   0
73 #define GICV3_IRQ_GROUP_GRP1NS  1
74 #define GICV3_IRQ_GROUP_GRP1S   2
75 
76 #ifndef ARM_GIC_SELECTED_IRQ_GROUP
77 #define ARM_GIC_SELECTED_IRQ_GROUP GRP1S
78 #endif
79 
80 #define COMBINE2(a, b)  a ## b
81 #define XCOMBINE2(a, b) COMBINE2(a,b)
82 #define GICV3_IRQ_GROUP XCOMBINE2(GICV3_IRQ_GROUP_, ARM_GIC_SELECTED_IRQ_GROUP)
83 
84 /*
85  * In ARMv8 for GICv3/v4, ARM suggest to use system register
86  * to access GICC instead of memory map.
87  */
88 #ifdef ARCH_ARM64
89 
90 #define GICCREG_READ(gic, reg)  ARM64_READ_SYSREG(reg)
91 #define GICCREG_WRITE(gic, reg, val) ARM64_WRITE_SYSREG(reg, (uint64_t)val)
92 
93 #else /* ARCH_ARM64 */
94 
95 /* For 32bit mode, use different way to access registers */
96 #define GICCREG_READ(gic, reg) COMBINE2(arm_read_,reg)()
97 #define GICCREG_WRITE(gic, reg, val) COMBINE2(arm_write_,reg)(val)
98 
99 GEN_CP15_REG_FUNCS(icc_ctlr_el1, 0, c12, c12, 4);
100 GEN_CP15_REG_FUNCS(icc_pmr_el1, 0, c4, c6, 0);
101 GEN_CP15_REG_FUNCS(icc_bpr0_el1, 0, c12, c8, 3);
102 GEN_CP15_REG_FUNCS(icc_iar0_el1, 0, c12, c8, 0);
103 GEN_CP15_REG_FUNCS(icc_eoir0_el1, 0, c12, c8, 1);
104 GEN_CP15_REG_FUNCS(icc_rpr_el1, 0, c12, c11, 3);
105 GEN_CP15_REG_FUNCS(icc_hppir0_el1, 0, c12, c8, 2);
106 GEN_CP15_REG_FUNCS(icc_bpr1_el1, 0, c12, c12, 3);
107 GEN_CP15_REG_FUNCS(icc_iar1_el1, 0, c12, c12, 0);
108 GEN_CP15_REG_FUNCS(icc_eoir1_el1, 0, c12, c12, 1);
109 GEN_CP15_REG_FUNCS(icc_hppir1_el1, 0, c12, c12, 2);
110 GEN_CP15_REG_FUNCS(icc_dir_el1, 0, c12, c11, 1);
111 GEN_CP15_REG_FUNCS(icc_sre_el1, 0, c12, c12, 5);
112 GEN_CP15_REG_FUNCS(icc_igrpen0_el1, 0, c12, c12, 6);
113 GEN_CP15_REG_FUNCS(icc_igrpen1_el1, 0, c12, c12, 7);
114 GEN_CP15_REG_FUNCS(icc_ap0r0_el1, 0, c12, c8, 4);
115 GEN_CP15_REG_FUNCS(icc_ap0r1_el1, 0, c12, c8, 5);
116 GEN_CP15_REG_FUNCS(icc_ap0r2_el1, 0, c12, c8, 6);
117 GEN_CP15_REG_FUNCS(icc_ap0r3_el1, 0, c12, c8, 7);
118 GEN_CP15_REG_FUNCS(icc_ap1r0_el1, 0, c12, c9, 0);
119 GEN_CP15_REG_FUNCS(icc_ap1r1_el1, 0, c12, c9, 1);
120 GEN_CP15_REG_FUNCS(icc_ap1r2_el1, 0, c12, c9, 2);
121 GEN_CP15_REG_FUNCS(icc_ap1r3_el1, 0, c12, c9, 3);
122 GEN_CP15_REG64_FUNCS(icc_sgi1r_el1, 0, c12);
123 GEN_CP15_REG64_FUNCS(icc_asgi1r_el1, 1, c12);
124 GEN_CP15_REG64_FUNCS(icc_sgi0r_el1, 2, c12);
125 
126 #endif /* ARCH_ARM64 */
127 
128 #if GICV3_IRQ_GROUP == GICV3_IRQ_GROUP_GRP0S
129 #define GICC_PRIMARY_HPPIR       icc_hppir0_el1
130 #define GICC_PRIMARY_IAR         icc_iar0_el1
131 #define GICC_PRIMARY_EOIR        icc_eoir0_el1
132 #define GICC_PRIMARY_SGIR        icc_sgi0r_el1
133 #else
134 #define GICC_PRIMARY_HPPIR       icc_hppir1_el1
135 #define GICC_PRIMARY_IAR         icc_iar1_el1
136 #define GICC_PRIMARY_EOIR        icc_eoir1_el1
137 #define GICC_PRIMARY_SGIR        icc_sgi1r_el1
138 #endif
139 
140 #define GICC_LIMIT (0x0000)
141 
142 #else /* GIC_VERSION > 2 */
143 
144 #ifndef GICC_OFFSET
145 #define GICC_OFFSET (0x0000)
146 #endif
147 
148 #define GICCREG_READ(gic, reg) ({ \
149         ASSERT(gic < NUM_ARM_GICS); \
150         ASSERT(reg >= GICC_OFFSET); \
151         ASSERT(reg < GICC_LIMIT); \
152         mmio_read32((volatile uint32_t *)(arm_gics[(gic)].gicc_vaddr + ((reg) - GICC_OFFSET))); \
153     })
154 #define GICCREG_WRITE(gic, reg, val) ({ \
155         ASSERT(gic < NUM_ARM_GICS); \
156         ASSERT(reg >= GICC_OFFSET); \
157         ASSERT(reg < GICC_LIMIT); \
158         mmio_write32((volatile uint32_t *)(arm_gics[(gic)].gicc_vaddr + ((reg) - GICC_OFFSET)), (val)); \
159     })
160 /* main cpu regs */
161 #define GICC_CTLR               (GICC_OFFSET + 0x0000)
162 #define GICC_PMR                (GICC_OFFSET + 0x0004)
163 #define GICC_BPR                (GICC_OFFSET + 0x0008)
164 #define GICC_IAR                (GICC_OFFSET + 0x000c)
165 #define GICC_EOIR               (GICC_OFFSET + 0x0010)
166 #define GICC_RPR                (GICC_OFFSET + 0x0014)
167 #define GICC_HPPIR              (GICC_OFFSET + 0x0018)
168 #define GICC_ABPR               (GICC_OFFSET + 0x001c)
169 #define GICC_AIAR               (GICC_OFFSET + 0x0020)
170 #define GICC_AEOIR              (GICC_OFFSET + 0x0024)
171 #define GICC_AHPPIR             (GICC_OFFSET + 0x0028)
172 #define GICC_APR(n)             (GICC_OFFSET + 0x00d0 + (n) * 4)
173 #define GICC_NSAPR(n)           (GICC_OFFSET + 0x00e0 + (n) * 4)
174 #define GICC_IIDR               (GICC_OFFSET + 0x00fc)
175 #if 0 /* GICC_DIR is not currently used by anything */
176 #define GICC_DIR                (GICC_OFFSET + 0x1000)
177 #endif
178 #define GICC_LIMIT              (GICC_OFFSET + 0x1000)
179 #define GICC_MIN_SIZE           (GICC_LIMIT - GICC_OFFSET)
180 
181 #if WITH_LIB_SM
182 #define GICC_PRIMARY_HPPIR      GICC_AHPPIR
183 #define GICC_PRIMARY_IAR        GICC_AIAR
184 #define GICC_PRIMARY_EOIR       GICC_AEOIR
185 #else
186 #define GICC_PRIMARY_HPPIR      GICC_HPPIR
187 #define GICC_PRIMARY_IAR        GICC_IAR
188 #define GICC_PRIMARY_EOIR       GICC_EOIR
189 #endif
190 
191 #endif /* GIC_VERSION > 2 */
192 
193 #ifndef GICD_OFFSET
194 #define GICD_OFFSET (GICC_LIMIT)
195 #endif
196 
197 #define GICDREG_READ(gic, reg) ({ \
198         ASSERT(gic < NUM_ARM_GICS); \
199         ASSERT(reg >= GICD_OFFSET); \
200         ASSERT(reg < GICD_LIMIT); \
201         mmio_read32((volatile uint32_t *)(arm_gics[(gic)].gicd_vaddr + ((reg) - GICD_OFFSET))); \
202     })
203 #define GICDREG_WRITE(gic, reg, val) ({ \
204         ASSERT(gic < NUM_ARM_GICS); \
205         ASSERT(reg >= GICD_OFFSET); \
206         ASSERT(reg < GICD_LIMIT); \
207         mmio_write32((volatile uint32_t *)(arm_gics[(gic)].gicd_vaddr + ((reg) - GICD_OFFSET)), (val)); \
208     })
209 /* distribution regs */
210 #define GICD_CTLR               (GICD_OFFSET + 0x000)
211 #define GICD_TYPER              (GICD_OFFSET + 0x004)
212 #define GICD_IIDR               (GICD_OFFSET + 0x008)
213 #define GICD_IGROUPR(n)         (GICD_OFFSET + 0x080 + (n) * 4)
214 #define GICD_ISENABLER(n)       (GICD_OFFSET + 0x100 + (n) * 4)
215 #define GICD_ICENABLER(n)       (GICD_OFFSET + 0x180 + (n) * 4)
216 #define GICD_ISPENDR(n)         (GICD_OFFSET + 0x200 + (n) * 4)
217 #define GICD_ICPENDR(n)         (GICD_OFFSET + 0x280 + (n) * 4)
218 #define GICD_ISACTIVER(n)       (GICD_OFFSET + 0x300 + (n) * 4)
219 #define GICD_ICACTIVER(n)       (GICD_OFFSET + 0x380 + (n) * 4)
220 #define GICD_IPRIORITYR(n)      (GICD_OFFSET + 0x400 + (n) * 4)
221 #define GICD_ITARGETSR(n)       (GICD_OFFSET + 0x800 + (n) * 4)
222 #define GICD_ICFGR(n)           (GICD_OFFSET + 0xc00 + (n) * 4)
223 #define GICD_NSACR(n)           (GICD_OFFSET + 0xe00 + (n) * 4)
224 #define GICD_SGIR               (GICD_OFFSET + 0xf00)
225 #define GICD_CPENDSGIR(n)       (GICD_OFFSET + 0xf10 + (n) * 4)
226 #define GICD_SPENDSGIR(n)       (GICD_OFFSET + 0xf20 + (n) * 4)
227 #if GIC_VERSION <= 2
228 /* for v3 and higher, these are defined later */
229 #define GICD_LIMIT              (GICD_OFFSET + 0x1000)
230 #define GICD_MIN_SIZE           (GICD_LIMIT - GICD_OFFSET)
231 #endif /* GIC_VERSION <= 2 */
232 
233 #if GIC_VERSION > 2
234 /* some registers of GICD are 64 bit */
235 #define GICDREG_READ64(gic, reg) ({ \
236         ASSERT(gic < NUM_ARM_GICS); \
237         ASSERT(reg >= GICD_OFFSET); \
238         ASSERT(reg < GICD_LIMIT); \
239         mmio_read64((volatile uint64_t *)(arm_gics[(gic)].gicd_vaddr + ((reg) - GICD_OFFSET))); \
240     })
241 #define GICDREG_WRITE64(gic, reg, val) ({ \
242         ASSERT(gic < NUM_ARM_GICS); \
243         ASSERT(reg >= GICD_OFFSET); \
244         ASSERT(reg < GICD_LIMIT); \
245         mmio_write64((volatile uint64_t *)(arm_gics[(gic)].gicd_vaddr + ((reg) - GICD_OFFSET)), (val)); \
246     })
247 
248 /* GICv3/v4 Distributor interface */
249 #define GICD_STATUSR            (GICD_OFFSET + 0x0010)
250 #define GICD_SETSPI_NSR         (GICD_OFFSET + 0x0040)
251 #define GICD_CLRSPI_NSR         (GICD_OFFSET + 0x0048)
252 #define GICD_SETSPI_SR          (GICD_OFFSET + 0x0050)
253 #define GICD_CLRSPI_SR          (GICD_OFFSET + 0x0058)
254 #define GICD_IGRPMODR(n)        (GICD_OFFSET + 0x0D00 + (n) * 4)
255 #define GICD_IROUTER(n)         (GICD_OFFSET + 0x6000 + (n) * 8)
256 #define GICD_LIMIT              (GICD_OFFSET + 0x10000)
257 #define GICD_MIN_SIZE           (GICD_LIMIT - GICD_OFFSET)
258 
259 /* GICv3/v4 Redistrubutor interface */
260 #if GIC_VERSION == 3
261 #define GICR_CPU_OFFSET(cpu) ((cpu) * 0x20000)
262 #endif
263 #if GIC_VERSION == 4
264 #define GICR_CPU_OFFSET(cpu) ((cpu) * 0x40000)
265 #endif
266 
267 #ifndef GICR_OFFSET
268 #define GICR_OFFSET (GICD_LIMIT)
269 #endif
270 
271 #define GICRREG_READ(gic, cpu, reg) ({ \
272         ASSERT(gic < NUM_ARM_GICS); \
273         ASSERT(cpu < SMP_MAX_CPUS); \
274         ASSERT(reg >= GICR_OFFSET); \
275         ASSERT(reg < GICR_LIMIT); \
276         mmio_read32((volatile uint32_t *)(arm_gics[(gic)].gicr_vaddr + GICR_CPU_OFFSET(cpu) + ((reg) - GICR_OFFSET))); \
277     })
278 #define GICRREG_WRITE(gic, cpu, reg, val) ({ \
279         ASSERT(gic < NUM_ARM_GICS); \
280         ASSERT(cpu < SMP_MAX_CPUS); \
281         ASSERT(reg >= GICR_OFFSET); \
282         ASSERT(reg < GICR_LIMIT); \
283         mmio_write32((volatile uint32_t *)(arm_gics[(gic)].gicr_vaddr + GICR_CPU_OFFSET(cpu) + ((reg) - GICR_OFFSET)), (val)); \
284     })
285 
286 #define GICR_CTRL               (GICR_OFFSET + 0x0000)
287 #define GICR_IIDR               (GICR_OFFSET + 0x0004)
288 #define GICR_TYPER              (GICR_OFFSET + 0x0008)
289 #define GICR_STATUSR            (GICR_OFFSET + 0x0010)
290 #define GICR_WAKER              (GICR_OFFSET + 0x0014)
291 
292 /* The following GICR registers are on separate 64KB page */
293 #define GICR_SGI_OFFSET         (GICR_OFFSET + 0x10000)
294 #define GICR_IGROUPR0           (GICR_SGI_OFFSET + 0x0080)
295 #define GICR_ISENABLER0         (GICR_SGI_OFFSET + 0x0100)
296 #define GICR_ICENABLER0         (GICR_SGI_OFFSET + 0x0180)
297 #define GICR_ISPENDR0           (GICR_SGI_OFFSET + 0x0200)
298 #define GICR_ICPENDR0           (GICR_SGI_OFFSET + 0x0280)
299 #define GICR_ISACTIVER0         (GICR_SGI_OFFSET + 0x0300)
300 #define GICR_ICACTIVER0         (GICR_SGI_OFFSET + 0x0380)
301 #define GICR_IPRIORITYR(n)      (GICR_SGI_OFFSET + 0x0400 + (n) * 4)
302 #define GICR_ICFGR(n)           (GICR_SGI_OFFSET + 0x0C00 + (n) * 4)
303 #define GICR_IGRPMODR0          (GICR_SGI_OFFSET + 0x0D00)
304 #define GICR_NSACR              (GICR_SGI_OFFSET + 0x0E00)
305 #define GICR_LIMIT              (GICR_SGI_OFFSET + 0x1000)
306 #define GICR_MIN_SIZE           (GICR_LIMIT - GICR_OFFSET)
307 #endif /* GIC_VERSION > 2 */
308