xref: /freebsd/sys/arm64/vmm/io/vgic_v3.c (revision 1ecf7d5b38319d110d0f5bff26d6f8a9c1042cf4)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (C) 2018 Alexandru Elisei <alexandru.elisei@gmail.com>
5  * Copyright (C) 2020-2022 Andrew Turner
6  * Copyright (C) 2023 Arm Ltd
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/cdefs.h>
31 
32 #include <sys/types.h>
33 #include <sys/errno.h>
34 #include <sys/systm.h>
35 #include <sys/bitstring.h>
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/malloc.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/rman.h>
43 #include <sys/smp.h>
44 
45 #include <vm/vm.h>
46 #include <vm/pmap.h>
47 
48 #include <dev/ofw/openfirm.h>
49 
50 #include <machine/atomic.h>
51 #include <machine/bus.h>
52 #include <machine/cpufunc.h>
53 #include <machine/cpu.h>
54 #include <machine/machdep.h>
55 #include <machine/param.h>
56 #include <machine/pmap.h>
57 #include <machine/vmparam.h>
58 #include <machine/intr.h>
59 #include <machine/vmm.h>
60 #include <machine/vmm_instruction_emul.h>
61 
62 #include <arm/arm/gic_common.h>
63 #include <arm64/arm64/gic_v3_reg.h>
64 #include <arm64/arm64/gic_v3_var.h>
65 
66 #include <arm64/vmm/hyp.h>
67 #include <arm64/vmm/mmu.h>
68 #include <arm64/vmm/arm64.h>
69 #include <arm64/vmm/vmm_handlers.h>
70 
71 #include <dev/vmm/vmm_dev.h>
72 #include <dev/vmm/vmm_vm.h>
73 
74 #include "vgic.h"
75 #include "vgic_internal.h"
76 #include "vgic_v3.h"
77 #include "vgic_v3_reg.h"
78 
79 #include "vgic_if.h"
80 
81 #define VGIC_SGI_NUM		(GIC_LAST_SGI - GIC_FIRST_SGI + 1)
82 #define VGIC_PPI_NUM		(GIC_LAST_PPI - GIC_FIRST_PPI + 1)
83 #define VGIC_SPI_NUM		(GIC_LAST_SPI - GIC_FIRST_SPI + 1)
84 #define VGIC_PRV_I_NUM		(VGIC_SGI_NUM + VGIC_PPI_NUM)
85 #define VGIC_SHR_I_NUM		(VGIC_SPI_NUM)
86 
87 MALLOC_DEFINE(M_VGIC_V3, "ARM VMM VGIC V3", "ARM VMM VGIC V3");
88 
89 /* TODO: Move to softc */
90 struct vgic_v3_virt_features {
91 	uint8_t min_prio;
92 	size_t ich_lr_num;
93 	size_t ich_apr_num;
94 };
95 
96 
97 /* How many IRQs we support (SGIs + PPIs + SPIs). Not including LPIs */
98 #define	VGIC_NIRQS	1023
99 /* Pretend to be an Arm design */
100 #define	VGIC_IIDR	0x43b
101 
102 static vgic_inject_irq_t vgic_v3_inject_irq;
103 static vgic_inject_msi_t vgic_v3_inject_msi;
104 
105 static int vgic_v3_max_cpu_count(device_t dev, struct hyp *hyp);
106 
107 #define	INJECT_IRQ(hyp, vcpuid, irqid, level)			\
108     vgic_v3_inject_irq(NULL, (hyp), (vcpuid), (irqid), (level))
109 
110 static register_read gic_pidr2_read;
111 
112 /* GICD_CTLR */
113 static register_read dist_ctlr_read;
114 static register_write dist_ctlr_write;
115 /* GICD_TYPER */
116 static register_read dist_typer_read;
117 /* GICD_IIDR */
118 static register_read dist_iidr_read;
119 /* GICD_STATUSR - RAZ/WI as we don't report errors (yet) */
120 /* GICD_SETSPI_NSR & GICD_CLRSPI_NSR */
121 static register_write dist_setclrspi_nsr_write;
122 /* GICD_SETSPI_SR - RAZ/WI */
123 /* GICD_CLRSPI_SR - RAZ/WI */
124 /* GICD_IGROUPR - RAZ/WI as GICD_CTLR.ARE == 1 */
125 /* GICD_ISENABLER */
126 static register_read dist_isenabler_read;
127 static register_write dist_isenabler_write;
128 /* GICD_ICENABLER */
129 static register_read dist_icenabler_read;
130 static register_write dist_icenabler_write;
131 /* GICD_ISPENDR */
132 static register_read dist_ispendr_read;
133 static register_write dist_ispendr_write;
134 /* GICD_ICPENDR */
135 static register_read dist_icpendr_read;
136 static register_write dist_icpendr_write;
137 /* GICD_ISACTIVER */
138 static register_read dist_isactiver_read;
139 static register_write dist_isactiver_write;
140 /* GICD_ICACTIVER */
141 static register_read dist_icactiver_read;
142 static register_write dist_icactiver_write;
143 /* GICD_IPRIORITYR */
144 static register_read dist_ipriorityr_read;
145 static register_write dist_ipriorityr_write;
146 /* GICD_ITARGETSR - RAZ/WI as GICD_CTLR.ARE == 1 */
147 /* GICD_ICFGR */
148 static register_read dist_icfgr_read;
149 static register_write dist_icfgr_write;
150 /* GICD_IGRPMODR - RAZ/WI from non-secure mode */
151 /* GICD_NSACR - RAZ/WI from non-secure mode */
152 /* GICD_SGIR - RAZ/WI as GICD_CTLR.ARE == 1 */
153 /* GICD_CPENDSGIR - RAZ/WI as GICD_CTLR.ARE == 1 */
154 /* GICD_SPENDSGIR - RAZ/WI as GICD_CTLR.ARE == 1 */
155 /* GICD_IROUTER */
156 static register_read dist_irouter_read;
157 static register_write dist_irouter_write;
158 
159 static struct vgic_register dist_registers[] = {
160 	VGIC_REGISTER(GICD_CTLR, 4, VGIC_32_BIT, dist_ctlr_read,
161 	    dist_ctlr_write),
162 	VGIC_REGISTER(GICD_TYPER, 4, VGIC_32_BIT, dist_typer_read,
163 	    vgic_ignore_write),
164 	VGIC_REGISTER(GICD_IIDR, 4, VGIC_32_BIT, dist_iidr_read,
165 	    vgic_ignore_write),
166 	VGIC_REGISTER_RAZ_WI(GICD_STATUSR, 4, VGIC_32_BIT),
167 	VGIC_REGISTER(GICD_SETSPI_NSR, 4, VGIC_32_BIT, vgic_zero_read,
168 	    dist_setclrspi_nsr_write),
169 	VGIC_REGISTER(GICD_CLRSPI_NSR, 4, VGIC_32_BIT, vgic_zero_read,
170 	    dist_setclrspi_nsr_write),
171 	VGIC_REGISTER_RAZ_WI(GICD_SETSPI_SR, 4, VGIC_32_BIT),
172 	VGIC_REGISTER_RAZ_WI(GICD_CLRSPI_SR, 4, VGIC_32_BIT),
173 	VGIC_REGISTER_RANGE_RAZ_WI(GICD_IGROUPR(0), GICD_IGROUPR(1024), 4,
174 	    VGIC_32_BIT),
175 
176 	VGIC_REGISTER_RAZ_WI(GICD_ISENABLER(0), 4, VGIC_32_BIT),
177 	VGIC_REGISTER_RANGE(GICD_ISENABLER(32), GICD_ISENABLER(1024), 4,
178 	    VGIC_32_BIT, dist_isenabler_read, dist_isenabler_write),
179 
180 	VGIC_REGISTER_RAZ_WI(GICD_ICENABLER(0), 4, VGIC_32_BIT),
181 	VGIC_REGISTER_RANGE(GICD_ICENABLER(32), GICD_ICENABLER(1024), 4,
182 	    VGIC_32_BIT, dist_icenabler_read, dist_icenabler_write),
183 
184 	VGIC_REGISTER_RAZ_WI(GICD_ISPENDR(0), 4, VGIC_32_BIT),
185 	VGIC_REGISTER_RANGE(GICD_ISPENDR(32), GICD_ISPENDR(1024), 4,
186 	    VGIC_32_BIT, dist_ispendr_read, dist_ispendr_write),
187 
188 	VGIC_REGISTER_RAZ_WI(GICD_ICPENDR(0), 4, VGIC_32_BIT),
189 	VGIC_REGISTER_RANGE(GICD_ICPENDR(32), GICD_ICPENDR(1024), 4,
190 	    VGIC_32_BIT, dist_icpendr_read, dist_icpendr_write),
191 
192 	VGIC_REGISTER_RAZ_WI(GICD_ISACTIVER(0), 4, VGIC_32_BIT),
193 	VGIC_REGISTER_RANGE(GICD_ISACTIVER(32), GICD_ISACTIVER(1024), 4,
194 	    VGIC_32_BIT, dist_isactiver_read, dist_isactiver_write),
195 
196 	VGIC_REGISTER_RAZ_WI(GICD_ICACTIVER(0), 4, VGIC_32_BIT),
197 	VGIC_REGISTER_RANGE(GICD_ICACTIVER(32), GICD_ICACTIVER(1024), 4,
198 	    VGIC_32_BIT, dist_icactiver_read, dist_icactiver_write),
199 
200 	VGIC_REGISTER_RANGE_RAZ_WI(GICD_IPRIORITYR(0), GICD_IPRIORITYR(32), 4,
201 	    VGIC_32_BIT | VGIC_8_BIT),
202 	VGIC_REGISTER_RANGE(GICD_IPRIORITYR(32), GICD_IPRIORITYR(1024), 4,
203 	    VGIC_32_BIT | VGIC_8_BIT, dist_ipriorityr_read,
204 	    dist_ipriorityr_write),
205 
206 	VGIC_REGISTER_RANGE_RAZ_WI(GICD_ITARGETSR(0), GICD_ITARGETSR(1024), 4,
207 	    VGIC_32_BIT | VGIC_8_BIT),
208 
209 	VGIC_REGISTER_RANGE_RAZ_WI(GICD_ICFGR(0), GICD_ICFGR(32), 4,
210 	    VGIC_32_BIT),
211 	VGIC_REGISTER_RANGE(GICD_ICFGR(32), GICD_ICFGR(1024), 4,
212 	    VGIC_32_BIT, dist_icfgr_read, dist_icfgr_write),
213 /*
214 	VGIC_REGISTER_RANGE(GICD_IGRPMODR(0), GICD_IGRPMODR(1024), 4,
215 	    VGIC_32_BIT, dist_igrpmodr_read, dist_igrpmodr_write),
216 	VGIC_REGISTER_RANGE(GICD_NSACR(0), GICD_NSACR(1024), 4,
217 	    VGIC_32_BIT, dist_nsacr_read, dist_nsacr_write),
218 */
219 	VGIC_REGISTER_RAZ_WI(GICD_SGIR, 4, VGIC_32_BIT),
220 /*
221 	VGIC_REGISTER_RANGE(GICD_CPENDSGIR(0), GICD_CPENDSGIR(1024), 4,
222 	    VGIC_32_BIT | VGIC_8_BIT, dist_cpendsgir_read,
223 	    dist_cpendsgir_write),
224 	VGIC_REGISTER_RANGE(GICD_SPENDSGIR(0), GICD_SPENDSGIR(1024), 4,
225 	    VGIC_32_BIT | VGIC_8_BIT, dist_spendsgir_read,
226 	    dist_spendsgir_write),
227 */
228 	VGIC_REGISTER_RANGE(GICD_IROUTER(32), GICD_IROUTER(1024), 8,
229 	    VGIC_64_BIT | VGIC_32_BIT, dist_irouter_read, dist_irouter_write),
230 
231 	VGIC_REGISTER_RANGE_RAZ_WI(GICD_PIDR4, GICD_PIDR2, 4, VGIC_32_BIT),
232 	VGIC_REGISTER(GICD_PIDR2, 4, VGIC_32_BIT, gic_pidr2_read,
233 	    vgic_ignore_write),
234 	VGIC_REGISTER_RANGE_RAZ_WI(GICD_PIDR2 + 4, GICD_SIZE, 4, VGIC_32_BIT),
235 };
236 
237 /* GICR_CTLR - Ignore writes as no bits can be set */
238 static register_read redist_ctlr_read;
239 /* GICR_IIDR */
240 static register_read redist_iidr_read;
241 /* GICR_TYPER */
242 static register_read redist_typer_read;
243 /* GICR_STATUSR - RAZ/WI as we don't report errors (yet) */
244 /* GICR_WAKER - RAZ/WI from non-secure mode */
245 /* GICR_SETLPIR - RAZ/WI as no LPIs are supported */
246 /* GICR_CLRLPIR - RAZ/WI as no LPIs are supported */
247 /* GICR_PROPBASER - RAZ/WI as no LPIs are supported */
248 /* GICR_PENDBASER - RAZ/WI as no LPIs are supported */
249 /* GICR_INVLPIR - RAZ/WI as no LPIs are supported */
250 /* GICR_INVALLR - RAZ/WI as no LPIs are supported */
251 /* GICR_SYNCR - RAZ/WI as no LPIs are supported */
252 
253 static struct vgic_register redist_rd_registers[] = {
254 	VGIC_REGISTER(GICR_CTLR, 4, VGIC_32_BIT, redist_ctlr_read,
255 	    vgic_ignore_write),
256 	VGIC_REGISTER(GICR_IIDR, 4, VGIC_32_BIT, redist_iidr_read,
257 	    vgic_ignore_write),
258 	VGIC_REGISTER(GICR_TYPER, 8, VGIC_64_BIT | VGIC_32_BIT,
259 	    redist_typer_read, vgic_ignore_write),
260 	VGIC_REGISTER_RAZ_WI(GICR_STATUSR, 4, VGIC_32_BIT),
261 	VGIC_REGISTER_RAZ_WI(GICR_WAKER, 4, VGIC_32_BIT),
262 	VGIC_REGISTER_RAZ_WI(GICR_SETLPIR, 8, VGIC_64_BIT | VGIC_32_BIT),
263 	VGIC_REGISTER_RAZ_WI(GICR_CLRLPIR, 8, VGIC_64_BIT | VGIC_32_BIT),
264 	VGIC_REGISTER_RAZ_WI(GICR_PROPBASER, 8, VGIC_64_BIT | VGIC_32_BIT),
265 	VGIC_REGISTER_RAZ_WI(GICR_PENDBASER, 8, VGIC_64_BIT | VGIC_32_BIT),
266 	VGIC_REGISTER_RAZ_WI(GICR_INVLPIR, 8, VGIC_64_BIT | VGIC_32_BIT),
267 	VGIC_REGISTER_RAZ_WI(GICR_INVALLR, 8, VGIC_64_BIT | VGIC_32_BIT),
268 	VGIC_REGISTER_RAZ_WI(GICR_SYNCR, 4, VGIC_32_BIT),
269 
270 	/* These are identical to the dist registers */
271 	VGIC_REGISTER_RANGE_RAZ_WI(GICD_PIDR4, GICD_PIDR2, 4, VGIC_32_BIT),
272 	VGIC_REGISTER(GICD_PIDR2, 4, VGIC_32_BIT, gic_pidr2_read,
273 	    vgic_ignore_write),
274 	VGIC_REGISTER_RANGE_RAZ_WI(GICD_PIDR2 + 4, GICD_SIZE, 4,
275 	    VGIC_32_BIT),
276 };
277 
278 /* GICR_IGROUPR0 - RAZ/WI from non-secure mode */
279 /* GICR_ISENABLER0 */
280 static register_read redist_ienabler0_read;
281 static register_write redist_isenabler0_write;
282 /* GICR_ICENABLER0 */
283 static register_write redist_icenabler0_write;
284 /* GICR_ISPENDR0 */
285 static register_read redist_ipendr0_read;
286 static register_write redist_ispendr0_write;
287 /* GICR_ICPENDR0 */
288 static register_write redist_icpendr0_write;
289 /* GICR_ISACTIVER0 */
290 static register_read redist_iactiver0_read;
291 static register_write redist_isactiver0_write;
292 /* GICR_ICACTIVER0 */
293 static register_write redist_icactiver0_write;
294 /* GICR_IPRIORITYR */
295 static register_read redist_ipriorityr_read;
296 static register_write redist_ipriorityr_write;
297 /* GICR_ICFGR0 - RAZ/WI from non-secure mode */
298 /* GICR_ICFGR1 */
299 static register_read redist_icfgr1_read;
300 static register_write redist_icfgr1_write;
301 /* GICR_IGRPMODR0 - RAZ/WI from non-secure mode */
302 /* GICR_NSCAR - RAZ/WI from non-secure mode */
303 
304 static struct vgic_register redist_sgi_registers[] = {
305 	VGIC_REGISTER_RAZ_WI(GICR_IGROUPR0, 4, VGIC_32_BIT),
306 	VGIC_REGISTER(GICR_ISENABLER0, 4, VGIC_32_BIT, redist_ienabler0_read,
307 	    redist_isenabler0_write),
308 	VGIC_REGISTER(GICR_ICENABLER0, 4, VGIC_32_BIT, redist_ienabler0_read,
309 	    redist_icenabler0_write),
310 	VGIC_REGISTER(GICR_ISPENDR0, 4, VGIC_32_BIT, redist_ipendr0_read,
311 	    redist_ispendr0_write),
312 	VGIC_REGISTER(GICR_ICPENDR0, 4, VGIC_32_BIT, redist_ipendr0_read,
313 	    redist_icpendr0_write),
314 	VGIC_REGISTER(GICR_ISACTIVER0, 4, VGIC_32_BIT, redist_iactiver0_read,
315 	    redist_isactiver0_write),
316 	VGIC_REGISTER(GICR_ICACTIVER0, 4, VGIC_32_BIT, redist_iactiver0_read,
317 	    redist_icactiver0_write),
318 	VGIC_REGISTER_RANGE(GICR_IPRIORITYR(0), GICR_IPRIORITYR(32), 4,
319 	    VGIC_32_BIT | VGIC_8_BIT, redist_ipriorityr_read,
320 	    redist_ipriorityr_write),
321 	VGIC_REGISTER_RAZ_WI(GICR_ICFGR0, 4, VGIC_32_BIT),
322 	VGIC_REGISTER(GICR_ICFGR1, 4, VGIC_32_BIT, redist_icfgr1_read,
323 	    redist_icfgr1_write),
324 	VGIC_REGISTER_RAZ_WI(GICR_IGRPMODR0, 4, VGIC_32_BIT),
325 	VGIC_REGISTER_RAZ_WI(GICR_NSACR, 4, VGIC_32_BIT),
326 };
327 
328 static struct vgic_v3_virt_features virt_features;
329 
330 static struct vgic_v3_irq *vgic_v3_get_irq(struct hyp *, int, uint32_t);
331 static void vgic_v3_release_irq(struct vgic_v3_irq *);
332 
333 /* TODO: Move to a common file */
334 static int
mpidr_to_vcpu(struct hyp * hyp,uint64_t mpidr)335 mpidr_to_vcpu(struct hyp *hyp, uint64_t mpidr)
336 {
337 	struct vm *vm;
338 	struct hypctx *hypctx;
339 
340 	vm = hyp->vm;
341 	for (int i = 0; i < vm_get_maxcpus(vm); i++) {
342 		hypctx = hyp->ctx[i];
343 		if (hypctx != NULL && (hypctx_read_sys_reg(hypctx, HOST_VMPIDR_EL2) & GICD_AFF) == mpidr)
344 			return (i);
345 	}
346 	return (-1);
347 }
348 
349 static void
vgic_v3_vminit(device_t dev,struct hyp * hyp)350 vgic_v3_vminit(device_t dev, struct hyp *hyp)
351 {
352 	struct vgic_v3 *vgic;
353 
354 	hyp->vgic = malloc(sizeof(*hyp->vgic), M_VGIC_V3,
355 	    M_WAITOK | M_ZERO);
356 	vgic = hyp->vgic;
357 
358 	/*
359 	 * Configure the Distributor control register. The register resets to an
360 	 * architecturally UNKNOWN value, so we reset to 0 to disable all
361 	 * functionality controlled by the register.
362 	 *
363 	 * The exception is GICD_CTLR.DS, which is RA0/WI when the Distributor
364 	 * supports one security state (ARM GIC Architecture Specification for
365 	 * GICv3 and GICv4, p. 4-464)
366 	 */
367 	vgic->gicd_ctlr = 0;
368 
369 	mtx_init(&vgic->dist_mtx, "VGICv3 Distributor lock", NULL,
370 	    MTX_SPIN);
371 }
372 
373 static void
vgic_v3_cpuinit(device_t dev,struct hypctx * hypctx)374 vgic_v3_cpuinit(device_t dev, struct hypctx *hypctx)
375 {
376 	struct vgic_v3_cpu *vgic_cpu;
377 	struct vgic_v3_irq *irq;
378 	int i, irqid;
379 
380 	hypctx->vgic_cpu = malloc(sizeof(*hypctx->vgic_cpu),
381 	    M_VGIC_V3, M_WAITOK | M_ZERO);
382 	vgic_cpu = hypctx->vgic_cpu;
383 
384 	mtx_init(&vgic_cpu->lr_mtx, "VGICv3 ICH_LR_EL2 lock", NULL, MTX_SPIN);
385 
386 	vgic_cpu->private_irqs = mallocarray(VGIC_PRV_I_NUM,
387 	    sizeof(*vgic_cpu->private_irqs), M_VGIC_V3, M_WAITOK | M_ZERO);
388 
389 	/* Set the SGI and PPI state */
390 	for (irqid = 0; irqid < VGIC_PRV_I_NUM; irqid++) {
391 		irq = &vgic_cpu->private_irqs[irqid];
392 
393 		mtx_init(&irq->irq_spinmtx, "VGIC IRQ spinlock", NULL,
394 		    MTX_SPIN);
395 		irq->irq = irqid;
396 		irq->mpidr = hypctx_read_sys_reg(hypctx, HOST_VMPIDR_EL2) & GICD_AFF;
397 		irq->target_vcpu = vcpu_vcpuid(hypctx->vcpu);
398 		MPASS(irq->target_vcpu >= 0);
399 
400 		if (irqid < VGIC_SGI_NUM) {
401 			/* SGIs */
402 			irq->enabled = true;
403 			irq->config = VGIC_CONFIG_EDGE;
404 		} else {
405 			/* PPIs */
406 			irq->config = VGIC_CONFIG_LEVEL;
407 		}
408 		irq->priority = 0;
409 	}
410 
411 	/*
412 	 * Configure the Interrupt Controller Hyp Control Register.
413 	 *
414 	 * ICH_HCR_EL2_En: enable virtual CPU interface.
415 	 *
416 	 * Maintenance interrupts are disabled.
417 	 */
418 	hypctx_write_sys_reg(hypctx, HOST_ICH_HCR_EL2, ICH_HCR_EL2_En);
419 
420 	/*
421 	 * Configure the Interrupt Controller Virtual Machine Control Register.
422 	 *
423 	 * ICH_VMCR_EL2_VPMR: lowest priority mask for the VCPU interface
424 	 * ICH_VMCR_EL2_VBPR1_NO_PREEMPTION: disable interrupt preemption for
425 	 * Group 1 interrupts
426 	 * ICH_VMCR_EL2_VBPR0_NO_PREEMPTION: disable interrupt preemption for
427 	 * Group 0 interrupts
428 	 * ~ICH_VMCR_EL2_VEOIM: writes to EOI registers perform priority drop
429 	 * and interrupt deactivation.
430 	 * ICH_VMCR_EL2_VENG0: virtual Group 0 interrupts enabled.
431 	 * ICH_VMCR_EL2_VENG1: virtual Group 1 interrupts enabled.
432 	 */
433 	hypctx_write_sys_reg(hypctx, HOST_ICH_VMCR_EL2,
434 	    (virt_features.min_prio << ICH_VMCR_EL2_VPMR_SHIFT) |
435 		ICH_VMCR_EL2_VBPR1_NO_PREEMPTION |
436 			ICH_VMCR_EL2_VBPR0_NO_PREEMPTION);
437 	*hypctx_sys_reg(hypctx, HOST_ICH_VMCR_EL2) &= ~ICH_VMCR_EL2_VEOIM;
438 	*hypctx_sys_reg(hypctx, HOST_ICH_VMCR_EL2) |= ICH_VMCR_EL2_VENG0 |
439 	    ICH_VMCR_EL2_VENG1;
440 
441 	hypctx->vgic_v3.ich_lr_num = virt_features.ich_lr_num;
442 	for (i = 0; i < hypctx->vgic_v3.ich_lr_num; i++)
443 		hypctx_write_sys_reg(hypctx, HOST_ICH_LR_EL2(i), 0UL);
444 	vgic_cpu->ich_lr_used = 0;
445 	TAILQ_INIT(&vgic_cpu->irq_act_pend);
446 
447 	hypctx->vgic_v3.ich_apr_num = virt_features.ich_apr_num;
448 }
449 
450 static void
vgic_v3_cpucleanup(device_t dev,struct hypctx * hypctx)451 vgic_v3_cpucleanup(device_t dev, struct hypctx *hypctx)
452 {
453 	struct vgic_v3_cpu *vgic_cpu;
454 	struct vgic_v3_irq *irq;
455 	int irqid;
456 
457 	vgic_cpu = hypctx->vgic_cpu;
458 	for (irqid = 0; irqid < VGIC_PRV_I_NUM; irqid++) {
459 		irq = &vgic_cpu->private_irqs[irqid];
460 		mtx_destroy(&irq->irq_spinmtx);
461 	}
462 
463 	mtx_destroy(&vgic_cpu->lr_mtx);
464 	free(hypctx->vgic_cpu, M_VGIC_V3);
465 }
466 
467 static void
vgic_v3_vmcleanup(device_t dev,struct hyp * hyp)468 vgic_v3_vmcleanup(device_t dev, struct hyp *hyp)
469 {
470 	mtx_destroy(&hyp->vgic->dist_mtx);
471 	free(hyp->vgic, M_VGIC_V3);
472 }
473 
474 static int
vgic_v3_max_cpu_count(device_t dev,struct hyp * hyp)475 vgic_v3_max_cpu_count(device_t dev, struct hyp *hyp)
476 {
477 	struct vgic_v3 *vgic;
478 	size_t count;
479 	int16_t max_count;
480 
481 	vgic = hyp->vgic;
482 	max_count = vm_get_maxcpus(hyp->vm);
483 
484 	/* No registers, assume the maximum CPUs */
485 	if (vgic->redist_start == 0 && vgic->redist_end == 0)
486 		return (max_count);
487 
488 	count = (vgic->redist_end - vgic->redist_start) /
489 	    (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE);
490 
491 	/*
492 	 * max_count is smaller than INT_MAX so will also limit count
493 	 * to a positive integer value.
494 	 */
495 	if (count > max_count)
496 		return (max_count);
497 
498 	return (count);
499 }
500 
501 static bool
vgic_v3_irq_pending(struct vgic_v3_irq * irq)502 vgic_v3_irq_pending(struct vgic_v3_irq *irq)
503 {
504 	if ((irq->config & VGIC_CONFIG_MASK) == VGIC_CONFIG_LEVEL) {
505 		return (irq->pending || irq->level);
506 	} else {
507 		return (irq->pending);
508 	}
509 }
510 
511 static bool
vgic_v3_queue_irq(struct hyp * hyp,struct vgic_v3_cpu * vgic_cpu,int vcpuid,struct vgic_v3_irq * irq)512 vgic_v3_queue_irq(struct hyp *hyp, struct vgic_v3_cpu *vgic_cpu,
513     int vcpuid, struct vgic_v3_irq *irq)
514 {
515 	MPASS(vcpuid >= 0);
516 	MPASS(vcpuid < vm_get_maxcpus(hyp->vm));
517 
518 	mtx_assert(&vgic_cpu->lr_mtx, MA_OWNED);
519 	mtx_assert(&irq->irq_spinmtx, MA_OWNED);
520 
521 	/* No need to queue the IRQ */
522 	if (!irq->level && !irq->pending)
523 		return (false);
524 
525 	if (!irq->on_aplist) {
526 		irq->on_aplist = true;
527 		TAILQ_INSERT_TAIL(&vgic_cpu->irq_act_pend, irq, act_pend_list);
528 	}
529 	return (true);
530 }
531 
532 static uint64_t
gic_reg_value_64(uint64_t field,uint64_t val,u_int offset,u_int size)533 gic_reg_value_64(uint64_t field, uint64_t val, u_int offset, u_int size)
534 {
535 	uint32_t mask;
536 
537 	if (offset != 0 || size != 8) {
538 		mask = ((1ul << (size * 8)) - 1) << (offset * 8);
539 		/* Shift the new bits to the correct place */
540 		val <<= (offset * 8);
541 		/* Keep only the interesting bits */
542 		val &= mask;
543 		/* Add the bits we are keeping from the old value */
544 		val |= field & ~mask;
545 	}
546 
547 	return (val);
548 }
549 
550 static void
gic_pidr2_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)551 gic_pidr2_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
552     void *arg)
553 {
554 	*rval = GICR_PIDR2_ARCH_GICv3 << GICR_PIDR2_ARCH_SHIFT;
555 }
556 
557 static uint64_t
read_enabler(struct hypctx * hypctx,int n)558 read_enabler(struct hypctx *hypctx, int n)
559 {
560 	struct vgic_v3_irq *irq;
561 	uint64_t ret;
562 	uint32_t irq_base;
563 	int i;
564 
565 	ret = 0;
566 	irq_base = n * 32;
567 	for (i = 0; i < 32; i++) {
568 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
569 		    irq_base + i);
570 		if (irq == NULL)
571 			continue;
572 
573 		if (irq->enabled)
574 			ret |= 1u << i;
575 		vgic_v3_release_irq(irq);
576 	}
577 
578 	return (ret);
579 }
580 
581 static void
write_enabler(struct hypctx * hypctx,int n,bool set,uint64_t val)582 write_enabler(struct hypctx *hypctx,int n, bool set, uint64_t val)
583 {
584 	struct vgic_v3_irq *irq;
585 	uint32_t irq_base;
586 	int i;
587 
588 	irq_base = n * 32;
589 	for (i = 0; i < 32; i++) {
590 		/* We only change interrupts when the appropriate bit is set */
591 		if ((val & (1u << i)) == 0)
592 			continue;
593 
594 		/* Find the interrupt this bit represents */
595 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
596 		    irq_base + i);
597 		if (irq == NULL)
598 			continue;
599 
600 		irq->enabled = set;
601 		vgic_v3_release_irq(irq);
602 	}
603 }
604 
605 static uint64_t
read_pendr(struct hypctx * hypctx,int n)606 read_pendr(struct hypctx *hypctx, int n)
607 {
608 	struct vgic_v3_irq *irq;
609 	uint64_t ret;
610 	uint32_t irq_base;
611 	int i;
612 
613 	ret = 0;
614 	irq_base = n * 32;
615 	for (i = 0; i < 32; i++) {
616 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
617 		    irq_base + i);
618 		if (irq == NULL)
619 			continue;
620 
621 		if (vgic_v3_irq_pending(irq))
622 			ret |= 1u << i;
623 		vgic_v3_release_irq(irq);
624 	}
625 
626 	return (ret);
627 }
628 
629 static uint64_t
write_pendr(struct hypctx * hypctx,int n,bool set,uint64_t val)630 write_pendr(struct hypctx *hypctx, int n, bool set, uint64_t val)
631 {
632 	struct vgic_v3_cpu *vgic_cpu;
633 	struct vgic_v3_irq *irq;
634 	struct hyp *hyp;
635 	struct hypctx *target_hypctx;
636 	uint64_t ret;
637 	uint32_t irq_base;
638 	int target_vcpu, i;
639 	bool notify;
640 
641 	hyp = hypctx->hyp;
642 	ret = 0;
643 	irq_base = n * 32;
644 	for (i = 0; i < 32; i++) {
645 		/* We only change interrupts when the appropriate bit is set */
646 		if ((val & (1u << i)) == 0)
647 			continue;
648 
649 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
650 		    irq_base + i);
651 		if (irq == NULL)
652 			continue;
653 
654 		notify = false;
655 		target_vcpu = irq->target_vcpu;
656 		if (target_vcpu < 0)
657 			goto next_irq;
658 		target_hypctx = hyp->ctx[target_vcpu];
659 		if (target_hypctx == NULL)
660 			goto next_irq;
661 		vgic_cpu = target_hypctx->vgic_cpu;
662 
663 		if (!set) {
664 			/* pending -> not pending */
665 			irq->pending = false;
666 		} else {
667 			irq->pending = true;
668 			mtx_lock_spin(&vgic_cpu->lr_mtx);
669 			notify = vgic_v3_queue_irq(hyp, vgic_cpu, target_vcpu,
670 			    irq);
671 			mtx_unlock_spin(&vgic_cpu->lr_mtx);
672 		}
673 next_irq:
674 		vgic_v3_release_irq(irq);
675 
676 		if (notify)
677 			vcpu_notify_event(vm_vcpu(hyp->vm, target_vcpu));
678 	}
679 
680 	return (ret);
681 }
682 
683 static uint64_t
read_activer(struct hypctx * hypctx,int n)684 read_activer(struct hypctx *hypctx, int n)
685 {
686 	struct vgic_v3_irq *irq;
687 	uint64_t ret;
688 	uint32_t irq_base;
689 	int i;
690 
691 	ret = 0;
692 	irq_base = n * 32;
693 	for (i = 0; i < 32; i++) {
694 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
695 		    irq_base + i);
696 		if (irq == NULL)
697 			continue;
698 
699 		if (irq->active)
700 			ret |= 1u << i;
701 		vgic_v3_release_irq(irq);
702 	}
703 
704 	return (ret);
705 }
706 
707 static void
write_activer(struct hypctx * hypctx,u_int n,bool set,uint64_t val)708 write_activer(struct hypctx *hypctx, u_int n, bool set, uint64_t val)
709 {
710 	struct vgic_v3_cpu *vgic_cpu;
711 	struct vgic_v3_irq *irq;
712 	struct hyp *hyp;
713 	struct hypctx *target_hypctx;
714 	uint32_t irq_base;
715 	int target_vcpu, i;
716 	bool notify;
717 
718 	hyp = hypctx->hyp;
719 	irq_base = n * 32;
720 	for (i = 0; i < 32; i++) {
721 		/* We only change interrupts when the appropriate bit is set */
722 		if ((val & (1u << i)) == 0)
723 			continue;
724 
725 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
726 		    irq_base + i);
727 		if (irq == NULL)
728 			continue;
729 
730 		notify = false;
731 		target_vcpu = irq->target_vcpu;
732 		if (target_vcpu < 0)
733 			goto next_irq;
734 		target_hypctx = hyp->ctx[target_vcpu];
735 		if (target_hypctx == NULL)
736 			goto next_irq;
737 		vgic_cpu = target_hypctx->vgic_cpu;
738 
739 		if (!set) {
740 			/* active -> not active */
741 			irq->active = false;
742 		} else {
743 			/* not active -> active */
744 			irq->active = true;
745 			mtx_lock_spin(&vgic_cpu->lr_mtx);
746 			notify = vgic_v3_queue_irq(hyp, vgic_cpu, target_vcpu,
747 			    irq);
748 			mtx_unlock_spin(&vgic_cpu->lr_mtx);
749 		}
750 next_irq:
751 		vgic_v3_release_irq(irq);
752 
753 		if (notify)
754 			vcpu_notify_event(vm_vcpu(hyp->vm, target_vcpu));
755 	}
756 }
757 
758 static uint64_t
read_priorityr(struct hypctx * hypctx,int n)759 read_priorityr(struct hypctx *hypctx, int n)
760 {
761 	struct vgic_v3_irq *irq;
762 	uint64_t ret;
763 	uint32_t irq_base;
764 	int i;
765 
766 	ret = 0;
767 	irq_base = n * 4;
768 	for (i = 0; i < 4; i++) {
769 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
770 		    irq_base + i);
771 		if (irq == NULL)
772 			continue;
773 
774 		ret |= ((uint64_t)irq->priority) << (i * 8);
775 		vgic_v3_release_irq(irq);
776 	}
777 
778 	return (ret);
779 }
780 
781 static void
write_priorityr(struct hypctx * hypctx,u_int irq_base,u_int size,uint64_t val)782 write_priorityr(struct hypctx *hypctx, u_int irq_base, u_int size, uint64_t val)
783 {
784 	struct vgic_v3_irq *irq;
785 	int i;
786 
787 	for (i = 0; i < size; i++) {
788 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
789 		    irq_base + i);
790 		if (irq == NULL)
791 			continue;
792 
793 		/* Set the priority. We support 32 priority steps (5 bits) */
794 		irq->priority = (val >> (i * 8)) & 0xf8;
795 		vgic_v3_release_irq(irq);
796 	}
797 }
798 
799 static uint64_t
read_config(struct hypctx * hypctx,int n)800 read_config(struct hypctx *hypctx, int n)
801 {
802 	struct vgic_v3_irq *irq;
803 	uint64_t ret;
804 	uint32_t irq_base;
805 	int i;
806 
807 	ret = 0;
808 	irq_base = n * 16;
809 	for (i = 0; i < 16; i++) {
810 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
811 		    irq_base + i);
812 		if (irq == NULL)
813 			continue;
814 
815 		ret |= ((uint64_t)irq->config) << (i * 2);
816 		vgic_v3_release_irq(irq);
817 	}
818 
819 	return (ret);
820 }
821 
822 static void
write_config(struct hypctx * hypctx,int n,uint64_t val)823 write_config(struct hypctx *hypctx, int n, uint64_t val)
824 {
825 	struct vgic_v3_irq *irq;
826 	uint32_t irq_base;
827 	int i;
828 
829 	irq_base = n * 16;
830 	for (i = 0; i < 16; i++) {
831 		/*
832 		 * The config can't be changed for SGIs and PPIs. SGIs have
833 		 * an edge-triggered behaviour, and the register is
834 		 * implementation defined to be read-only for PPIs.
835 		 */
836 		if (irq_base + i < VGIC_PRV_I_NUM)
837 			continue;
838 
839 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
840 		    irq_base + i);
841 		if (irq == NULL)
842 			continue;
843 
844 		/* Bit 0 is RES0 */
845 		irq->config = (val >> (i * 2)) & VGIC_CONFIG_MASK;
846 		vgic_v3_release_irq(irq);
847 	}
848 }
849 
850 static uint64_t
read_route(struct hypctx * hypctx,int n)851 read_route(struct hypctx *hypctx, int n)
852 {
853 	struct vgic_v3_irq *irq;
854 	uint64_t mpidr;
855 
856 	irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), n);
857 	if (irq == NULL)
858 		return (0);
859 
860 	mpidr = irq->mpidr;
861 	vgic_v3_release_irq(irq);
862 
863 	return (mpidr);
864 }
865 
866 static void
write_route(struct hypctx * hypctx,int n,uint64_t val,u_int offset,u_int size)867 write_route(struct hypctx *hypctx, int n, uint64_t val, u_int offset,
868     u_int size)
869 {
870 	struct vgic_v3_irq *irq;
871 
872 	irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), n);
873 	if (irq == NULL)
874 		return;
875 
876 	irq->mpidr = gic_reg_value_64(irq->mpidr, val, offset, size) & GICD_AFF;
877 	irq->target_vcpu = mpidr_to_vcpu(hypctx->hyp, irq->mpidr);
878 	/*
879 	 * If the interrupt is pending we can either use the old mpidr, or
880 	 * the new mpidr. To simplify this code we use the old value so we
881 	 * don't need to move the interrupt until the next time it is
882 	 * moved to the pending state.
883 	 */
884 	vgic_v3_release_irq(irq);
885 }
886 
887 /*
888  * Distributor register handlers.
889  */
890 /* GICD_CTLR */
891 static void
dist_ctlr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)892 dist_ctlr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
893     void *arg)
894 {
895 	struct hyp *hyp;
896 	struct vgic_v3 *vgic;
897 
898 	hyp = hypctx->hyp;
899 	vgic = hyp->vgic;
900 
901 	mtx_lock_spin(&vgic->dist_mtx);
902 	*rval = vgic->gicd_ctlr;
903 	mtx_unlock_spin(&vgic->dist_mtx);
904 
905 	/* Writes are never pending */
906 	*rval &= ~GICD_CTLR_RWP;
907 }
908 
909 static void
dist_ctlr_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)910 dist_ctlr_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
911     uint64_t wval, void *arg)
912 {
913 	struct vgic_v3 *vgic;
914 
915 	MPASS(offset == 0);
916 	MPASS(size == 4);
917 	vgic = hypctx->hyp->vgic;
918 
919 	/*
920 	 * GICv2 backwards compatibility is not implemented so
921 	 * ARE_NS is RAO/WI. This means EnableGrp1 is RES0.
922 	 *
923 	 * EnableGrp1A is supported, and RWP is read-only.
924 	 *
925 	 * All other bits are RES0 from non-secure mode as we
926 	 * implement as if we are in a system with two security
927 	 * states.
928 	 */
929 	wval &= GICD_CTLR_G1A;
930 	wval |= GICD_CTLR_ARE_NS;
931 	mtx_lock_spin(&vgic->dist_mtx);
932 	vgic->gicd_ctlr = wval;
933 	/* TODO: Wake any vcpus that have interrupts pending */
934 	mtx_unlock_spin(&vgic->dist_mtx);
935 }
936 
937 /* GICD_TYPER */
938 static void
dist_typer_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)939 dist_typer_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
940     void *arg)
941 {
942 	uint32_t typer;
943 
944 	typer = (10 - 1) << GICD_TYPER_IDBITS_SHIFT;
945 	typer |= GICD_TYPER_MBIS;
946 	/* ITLinesNumber: */
947 	typer |= howmany(VGIC_NIRQS + 1, 32) - 1;
948 
949 	*rval = typer;
950 }
951 
952 /* GICD_IIDR */
953 static void
dist_iidr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)954 dist_iidr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
955 {
956 	*rval = VGIC_IIDR;
957 }
958 
959 /* GICD_SETSPI_NSR & GICD_CLRSPI_NSR */
960 static void
dist_setclrspi_nsr_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)961 dist_setclrspi_nsr_write(struct hypctx *hypctx, u_int reg, u_int offset,
962     u_int size, uint64_t wval, void *arg)
963 {
964 	uint32_t irqid;
965 
966 	MPASS(offset == 0);
967 	MPASS(size == 4);
968 	irqid = wval & GICD_SPI_INTID_MASK;
969 	INJECT_IRQ(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), irqid,
970 	    reg == GICD_SETSPI_NSR);
971 }
972 
973 /* GICD_ISENABLER */
974 static void
dist_isenabler_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)975 dist_isenabler_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
976 {
977 	int n;
978 
979 	n = (reg - GICD_ISENABLER(0)) / 4;
980 	/* GICD_ISENABLER0 is RAZ/WI so handled separately */
981 	MPASS(n > 0);
982 	*rval = read_enabler(hypctx, n);
983 }
984 
985 static void
dist_isenabler_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)986 dist_isenabler_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
987     uint64_t wval, void *arg)
988 {
989 	int n;
990 
991 	MPASS(offset == 0);
992 	MPASS(size == 4);
993 	n = (reg - GICD_ISENABLER(0)) / 4;
994 	/* GICD_ISENABLER0 is RAZ/WI so handled separately */
995 	MPASS(n > 0);
996 	write_enabler(hypctx, n, true, wval);
997 }
998 
999 /* GICD_ICENABLER */
1000 static void
dist_icenabler_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1001 dist_icenabler_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1002 {
1003 	int n;
1004 
1005 	n = (reg - GICD_ICENABLER(0)) / 4;
1006 	/* GICD_ICENABLER0 is RAZ/WI so handled separately */
1007 	MPASS(n > 0);
1008 	*rval = read_enabler(hypctx, n);
1009 }
1010 
1011 static void
dist_icenabler_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1012 dist_icenabler_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
1013     uint64_t wval, void *arg)
1014 {
1015 	int n;
1016 
1017 	MPASS(offset == 0);
1018 	MPASS(size == 4);
1019 	n = (reg - GICD_ICENABLER(0)) / 4;
1020 	/* GICD_ICENABLER0 is RAZ/WI so handled separately */
1021 	MPASS(n > 0);
1022 	write_enabler(hypctx, n, false, wval);
1023 }
1024 
1025 /* GICD_ISPENDR */
1026 static void
dist_ispendr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1027 dist_ispendr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1028 {
1029 	int n;
1030 
1031 	n = (reg - GICD_ISPENDR(0)) / 4;
1032 	/* GICD_ISPENDR0 is RAZ/WI so handled separately */
1033 	MPASS(n > 0);
1034 	*rval = read_pendr(hypctx, n);
1035 }
1036 
1037 static void
dist_ispendr_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1038 dist_ispendr_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
1039     uint64_t wval, void *arg)
1040 {
1041 	int n;
1042 
1043 	MPASS(offset == 0);
1044 	MPASS(size == 4);
1045 	n = (reg - GICD_ISPENDR(0)) / 4;
1046 	/* GICD_ISPENDR0 is RAZ/WI so handled separately */
1047 	MPASS(n > 0);
1048 	write_pendr(hypctx, n, true, wval);
1049 }
1050 
1051 /* GICD_ICPENDR */
1052 static void
dist_icpendr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1053 dist_icpendr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1054 {
1055 	int n;
1056 
1057 	n = (reg - GICD_ICPENDR(0)) / 4;
1058 	/* GICD_ICPENDR0 is RAZ/WI so handled separately */
1059 	MPASS(n > 0);
1060 	*rval = read_pendr(hypctx, n);
1061 }
1062 
1063 static void
dist_icpendr_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1064 dist_icpendr_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
1065     uint64_t wval, void *arg)
1066 {
1067 	int n;
1068 
1069 	MPASS(offset == 0);
1070 	MPASS(size == 4);
1071 	n = (reg - GICD_ICPENDR(0)) / 4;
1072 	/* GICD_ICPENDR0 is RAZ/WI so handled separately */
1073 	MPASS(n > 0);
1074 	write_pendr(hypctx, n, false, wval);
1075 }
1076 
1077 /* GICD_ISACTIVER */
1078 /* Affinity routing is enabled so isactiver0 is RAZ/WI */
1079 static void
dist_isactiver_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1080 dist_isactiver_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1081 {
1082 	int n;
1083 
1084 	n = (reg - GICD_ISACTIVER(0)) / 4;
1085 	/* GICD_ISACTIVER0 is RAZ/WI so handled separately */
1086 	MPASS(n > 0);
1087 	*rval = read_activer(hypctx, n);
1088 }
1089 
1090 static void
dist_isactiver_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1091 dist_isactiver_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
1092     uint64_t wval, void *arg)
1093 {
1094 	int n;
1095 
1096 	MPASS(offset == 0);
1097 	MPASS(size == 4);
1098 	n = (reg - GICD_ISACTIVER(0)) / 4;
1099 	/* GICD_ISACTIVE0 is RAZ/WI so handled separately */
1100 	MPASS(n > 0);
1101 	write_activer(hypctx, n, true, wval);
1102 }
1103 
1104 /* GICD_ICACTIVER */
1105 static void
dist_icactiver_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1106 dist_icactiver_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
1107     void *arg)
1108 {
1109 	int n;
1110 
1111 	n = (reg - GICD_ICACTIVER(0)) / 4;
1112 	/* GICD_ICACTIVE0 is RAZ/WI so handled separately */
1113 	MPASS(n > 0);
1114 	*rval = read_activer(hypctx, n);
1115 }
1116 
1117 static void
dist_icactiver_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1118 dist_icactiver_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
1119     uint64_t wval, void *arg)
1120 {
1121 	int n;
1122 
1123 	MPASS(offset == 0);
1124 	MPASS(size == 4);
1125 	n = (reg - GICD_ICACTIVER(0)) / 4;
1126 	/* GICD_ICACTIVE0 is RAZ/WI so handled separately */
1127 	MPASS(n > 0);
1128 	write_activer(hypctx, n, false, wval);
1129 }
1130 
1131 /* GICD_IPRIORITYR */
1132 /* Affinity routing is enabled so ipriorityr0-7 is RAZ/WI */
1133 static void
dist_ipriorityr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1134 dist_ipriorityr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
1135     void *arg)
1136 {
1137 	int n;
1138 
1139 	n = (reg - GICD_IPRIORITYR(0)) / 4;
1140 	/* GICD_IPRIORITY0-7 is RAZ/WI so handled separately */
1141 	MPASS(n > 7);
1142 	*rval = read_priorityr(hypctx, n);
1143 }
1144 
1145 static void
dist_ipriorityr_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1146 dist_ipriorityr_write(struct hypctx *hypctx, u_int reg, u_int offset,
1147     u_int size, uint64_t wval, void *arg)
1148 {
1149 	u_int irq_base;
1150 
1151 	irq_base = (reg - GICD_IPRIORITYR(0)) + offset;
1152 	/* GICD_IPRIORITY0-7 is RAZ/WI so handled separately */
1153 	MPASS(irq_base > 31);
1154 	write_priorityr(hypctx, irq_base, size, wval);
1155 }
1156 
1157 /* GICD_ICFGR */
1158 static void
dist_icfgr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1159 dist_icfgr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1160 {
1161 	int n;
1162 
1163 	n = (reg - GICD_ICFGR(0)) / 4;
1164 	/* GICD_ICFGR0-1 are RAZ/WI so handled separately */
1165 	MPASS(n > 1);
1166 	*rval = read_config(hypctx, n);
1167 }
1168 
1169 static void
dist_icfgr_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1170 dist_icfgr_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
1171     uint64_t wval, void *arg)
1172 {
1173 	int n;
1174 
1175 	MPASS(offset == 0);
1176 	MPASS(size == 4);
1177 	n = (reg - GICD_ICFGR(0)) / 4;
1178 	/* GICD_ICFGR0-1 are RAZ/WI so handled separately */
1179 	MPASS(n > 1);
1180 	write_config(hypctx, n, wval);
1181 }
1182 
1183 /* GICD_IROUTER */
1184 static void
dist_irouter_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1185 dist_irouter_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1186 {
1187 	int n;
1188 
1189 	n = (reg - GICD_IROUTER(0)) / 8;
1190 	/* GICD_IROUTER0-31 don't exist */
1191 	MPASS(n > 31);
1192 	*rval = read_route(hypctx, n);
1193 }
1194 
1195 static void
dist_irouter_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1196 dist_irouter_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
1197     uint64_t wval, void *arg)
1198 {
1199 	int n;
1200 
1201 	n = (reg - GICD_IROUTER(0)) / 8;
1202 	/* GICD_IROUTER0-31 don't exist */
1203 	MPASS(n > 31);
1204 	write_route(hypctx, n, wval, offset, size);
1205 }
1206 
1207 static int
dist_read(struct vcpu * vcpu,uint64_t fault_ipa,uint64_t * rval,int size,void * arg)1208 dist_read(struct vcpu *vcpu, uint64_t fault_ipa, uint64_t *rval,
1209     int size, void *arg)
1210 {
1211 	struct hyp *hyp;
1212 	struct hypctx *hypctx;
1213 	struct vgic_v3 *vgic;
1214 	uint64_t reg;
1215 
1216 	hypctx = vcpu_get_cookie(vcpu);
1217 	hyp = hypctx->hyp;
1218 	vgic = hyp->vgic;
1219 
1220 	/* Check the register is one of ours and is the correct size */
1221 	if (fault_ipa < vgic->dist_start || fault_ipa + size > vgic->dist_end) {
1222 		return (EINVAL);
1223 	}
1224 
1225 	reg = fault_ipa - vgic->dist_start;
1226 	/*
1227 	 * As described in vgic_register_read an access with an invalid
1228 	 * alignment is read with an unknown value
1229 	 */
1230 	if ((reg & (size - 1)) != 0) {
1231 		*rval = 0;
1232 		return (0);
1233 	}
1234 
1235 	if (vgic_register_read(hypctx, dist_registers, nitems(dist_registers),
1236 	    reg, size, rval, NULL))
1237 		return (0);
1238 
1239 	/* Reserved register addresses are RES0 so we can hardware it to 0 */
1240 	*rval = 0;
1241 
1242 	return (0);
1243 }
1244 
1245 static int
dist_write(struct vcpu * vcpu,uint64_t fault_ipa,uint64_t wval,int size,void * arg)1246 dist_write(struct vcpu *vcpu, uint64_t fault_ipa, uint64_t wval,
1247     int size, void *arg)
1248 {
1249 	struct hyp *hyp;
1250 	struct hypctx *hypctx;
1251 	struct vgic_v3 *vgic;
1252 	uint64_t reg;
1253 
1254 	hypctx = vcpu_get_cookie(vcpu);
1255 	hyp = hypctx->hyp;
1256 	vgic = hyp->vgic;
1257 
1258 	/* Check the register is one of ours and is the correct size */
1259 	if (fault_ipa < vgic->dist_start || fault_ipa + size > vgic->dist_end) {
1260 		return (EINVAL);
1261 	}
1262 
1263 	reg = fault_ipa - vgic->dist_start;
1264 	/*
1265 	 * As described in vgic_register_read an access with an invalid
1266 	 * alignment is write ignored.
1267 	 */
1268 	if ((reg & (size - 1)) != 0)
1269 		return (0);
1270 
1271 	if (vgic_register_write(hypctx, dist_registers, nitems(dist_registers),
1272 	    reg, size, wval, NULL))
1273 		return (0);
1274 
1275 	/* Reserved register addresses are RES0 so we can ignore the write */
1276 	return (0);
1277 }
1278 
1279 /*
1280  * Redistributor register handlers.
1281  *
1282  * RD_base:
1283  */
1284 /* GICR_CTLR */
1285 static void
redist_ctlr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1286 redist_ctlr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1287 {
1288 	/* LPIs not supported */
1289 	*rval = 0;
1290 }
1291 
1292 /* GICR_IIDR */
1293 static void
redist_iidr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1294 redist_iidr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1295 {
1296 	*rval = VGIC_IIDR;
1297 }
1298 
1299 /* GICR_TYPER */
1300 static void
redist_typer_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1301 redist_typer_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1302 {
1303 	uint64_t aff, gicr_typer, vmpidr_el2;
1304 	bool last_vcpu;
1305 
1306 	last_vcpu = false;
1307 	if (vcpu_vcpuid(hypctx->vcpu) == (vgic_max_cpu_count(hypctx->hyp) - 1))
1308 		last_vcpu = true;
1309 
1310 	vmpidr_el2 = hypctx_read_sys_reg(hypctx, HOST_VMPIDR_EL2);
1311 	MPASS(vmpidr_el2 != 0);
1312 	/*
1313 	 * Get affinity for the current CPU. The guest CPU affinity is taken
1314 	 * from VMPIDR_EL2. The Redistributor corresponding to this CPU is
1315 	 * the Redistributor with the same affinity from GICR_TYPER.
1316 	 */
1317 	aff = (CPU_AFF3(vmpidr_el2) << 24) | (CPU_AFF2(vmpidr_el2) << 16) |
1318 	    (CPU_AFF1(vmpidr_el2) << 8) | CPU_AFF0(vmpidr_el2);
1319 
1320 	/* Set up GICR_TYPER. */
1321 	gicr_typer = aff << GICR_TYPER_AFF_SHIFT;
1322 	/* Set the vcpu as the processsor ID */
1323 	gicr_typer |=
1324 	    (uint64_t)vcpu_vcpuid(hypctx->vcpu) << GICR_TYPER_CPUNUM_SHIFT;
1325 
1326 	if (last_vcpu)
1327 		/* Mark the last Redistributor */
1328 		gicr_typer |= GICR_TYPER_LAST;
1329 
1330 	*rval = gicr_typer;
1331 }
1332 
1333 /*
1334  * SGI_base:
1335  */
1336 /* GICR_ISENABLER0 */
1337 static void
redist_ienabler0_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1338 redist_ienabler0_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
1339     void *arg)
1340 {
1341 	*rval = read_enabler(hypctx, 0);
1342 }
1343 
1344 static void
redist_isenabler0_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1345 redist_isenabler0_write(struct hypctx *hypctx, u_int reg, u_int offset,
1346     u_int size, uint64_t wval, void *arg)
1347 {
1348 	MPASS(offset == 0);
1349 	MPASS(size == 4);
1350 	write_enabler(hypctx, 0, true, wval);
1351 }
1352 
1353 /* GICR_ICENABLER0 */
1354 static void
redist_icenabler0_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1355 redist_icenabler0_write(struct hypctx *hypctx, u_int reg, u_int offset,
1356     u_int size, uint64_t wval, void *arg)
1357 {
1358 	MPASS(offset == 0);
1359 	MPASS(size == 4);
1360 	write_enabler(hypctx, 0, false, wval);
1361 }
1362 
1363 /* GICR_ISPENDR0 */
1364 static void
redist_ipendr0_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1365 redist_ipendr0_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
1366     void *arg)
1367 {
1368 	*rval = read_pendr(hypctx, 0);
1369 }
1370 
1371 static void
redist_ispendr0_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1372 redist_ispendr0_write(struct hypctx *hypctx, u_int reg, u_int offset,
1373     u_int size, uint64_t wval, void *arg)
1374 {
1375 	MPASS(offset == 0);
1376 	MPASS(size == 4);
1377 	write_pendr(hypctx, 0, true, wval);
1378 }
1379 
1380 /* GICR_ICPENDR0 */
1381 static void
redist_icpendr0_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1382 redist_icpendr0_write(struct hypctx *hypctx, u_int reg, u_int offset,
1383     u_int size, uint64_t wval, void *arg)
1384 {
1385 	MPASS(offset == 0);
1386 	MPASS(size == 4);
1387 	write_pendr(hypctx, 0, false, wval);
1388 }
1389 
1390 /* GICR_ISACTIVER0 */
1391 static void
redist_iactiver0_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1392 redist_iactiver0_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
1393     void *arg)
1394 {
1395 	*rval = read_activer(hypctx, 0);
1396 }
1397 
1398 static void
redist_isactiver0_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1399 redist_isactiver0_write(struct hypctx *hypctx, u_int reg, u_int offset,
1400     u_int size, uint64_t wval, void *arg)
1401 {
1402 	write_activer(hypctx, 0, true, wval);
1403 }
1404 
1405 /* GICR_ICACTIVER0 */
1406 static void
redist_icactiver0_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1407 redist_icactiver0_write(struct hypctx *hypctx, u_int reg, u_int offset,
1408     u_int size, uint64_t wval, void *arg)
1409 {
1410 	write_activer(hypctx, 0, false, wval);
1411 }
1412 
1413 /* GICR_IPRIORITYR */
1414 static void
redist_ipriorityr_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1415 redist_ipriorityr_read(struct hypctx *hypctx, u_int reg, uint64_t *rval,
1416     void *arg)
1417 {
1418 	int n;
1419 
1420 	n = (reg - GICR_IPRIORITYR(0)) / 4;
1421 	*rval = read_priorityr(hypctx, n);
1422 }
1423 
1424 static void
redist_ipriorityr_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1425 redist_ipriorityr_write(struct hypctx *hypctx, u_int reg, u_int offset,
1426     u_int size, uint64_t wval, void *arg)
1427 {
1428 	u_int irq_base;
1429 
1430 	irq_base = (reg - GICR_IPRIORITYR(0)) + offset;
1431 	write_priorityr(hypctx, irq_base, size, wval);
1432 }
1433 
1434 /* GICR_ICFGR1 */
1435 static void
redist_icfgr1_read(struct hypctx * hypctx,u_int reg,uint64_t * rval,void * arg)1436 redist_icfgr1_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
1437 {
1438 	*rval = read_config(hypctx, 1);
1439 }
1440 
1441 static void
redist_icfgr1_write(struct hypctx * hypctx,u_int reg,u_int offset,u_int size,uint64_t wval,void * arg)1442 redist_icfgr1_write(struct hypctx *hypctx, u_int reg, u_int offset, u_int size,
1443     uint64_t wval, void *arg)
1444 {
1445 	MPASS(offset == 0);
1446 	MPASS(size == 4);
1447 	write_config(hypctx, 1, wval);
1448 }
1449 
1450 static int
redist_read(struct vcpu * vcpu,uint64_t fault_ipa,uint64_t * rval,int size,void * arg)1451 redist_read(struct vcpu *vcpu, uint64_t fault_ipa, uint64_t *rval,
1452     int size, void *arg)
1453 {
1454 	struct hyp *hyp;
1455 	struct hypctx *hypctx, *target_hypctx;
1456 	struct vgic_v3 *vgic;
1457 	uint64_t reg;
1458 	int vcpuid;
1459 
1460 	/* Find the current vcpu ctx to get the vgic struct */
1461 	hypctx = vcpu_get_cookie(vcpu);
1462 	hyp = hypctx->hyp;
1463 	vgic = hyp->vgic;
1464 
1465 	/* Check the register is one of ours and is the correct size */
1466 	if (fault_ipa < vgic->redist_start ||
1467 	    fault_ipa + size > vgic->redist_end) {
1468 		return (EINVAL);
1469 	}
1470 
1471 	vcpuid = (fault_ipa - vgic->redist_start) /
1472 	    (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE);
1473 	if (vcpuid >= vm_get_maxcpus(hyp->vm)) {
1474 		/*
1475 		 * This should never happen, but lets be defensive so if it
1476 		 * does we don't panic a non-INVARIANTS kernel.
1477 		 */
1478 #ifdef INVARIANTS
1479 		panic("%s: Invalid vcpuid %d", __func__, vcpuid);
1480 #else
1481 		*rval = 0;
1482 		return (0);
1483 #endif
1484 	}
1485 
1486 	/* Find the target vcpu ctx for the access */
1487 	target_hypctx = hyp->ctx[vcpuid];
1488 	if (target_hypctx == NULL) {
1489 		/*
1490 		 * The CPU has not yet started. The redistributor and CPU are
1491 		 * in the same power domain. As such the redistributor will
1492 		 * also be powered down so any access will raise an external
1493 		 * abort.
1494 		 */
1495 		raise_data_insn_abort(hypctx, fault_ipa, true,
1496 		    ISS_DATA_DFSC_EXT);
1497 		return (0);
1498 	}
1499 
1500 	reg = (fault_ipa - vgic->redist_start) %
1501 	    (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE);
1502 
1503 	/*
1504 	 * As described in vgic_register_read an access with an invalid
1505 	 * alignment is read with an unknown value
1506 	 */
1507 	if ((reg & (size - 1)) != 0) {
1508 		*rval = 0;
1509 		return (0);
1510 	}
1511 
1512 	if (reg < GICR_RD_BASE_SIZE) {
1513 		if (vgic_register_read(target_hypctx, redist_rd_registers,
1514 		    nitems(redist_rd_registers), reg, size, rval, NULL))
1515 			return (0);
1516 	} else if (reg < (GICR_SGI_BASE + GICR_SGI_BASE_SIZE)) {
1517 		if (vgic_register_read(target_hypctx, redist_sgi_registers,
1518 		    nitems(redist_sgi_registers), reg - GICR_SGI_BASE, size,
1519 		    rval, NULL))
1520 			return (0);
1521 	}
1522 
1523 	/* Reserved register addresses are RES0 so we can hardware it to 0 */
1524 	*rval = 0;
1525 	return (0);
1526 }
1527 
1528 static int
redist_write(struct vcpu * vcpu,uint64_t fault_ipa,uint64_t wval,int size,void * arg)1529 redist_write(struct vcpu *vcpu, uint64_t fault_ipa, uint64_t wval,
1530     int size, void *arg)
1531 {
1532 	struct hyp *hyp;
1533 	struct hypctx *hypctx, *target_hypctx;
1534 	struct vgic_v3 *vgic;
1535 	uint64_t reg;
1536 	int vcpuid;
1537 
1538 	/* Find the current vcpu ctx to get the vgic struct */
1539 	hypctx = vcpu_get_cookie(vcpu);
1540 	hyp = hypctx->hyp;
1541 	vgic = hyp->vgic;
1542 
1543 	/* Check the register is one of ours and is the correct size */
1544 	if (fault_ipa < vgic->redist_start ||
1545 	    fault_ipa + size > vgic->redist_end) {
1546 		return (EINVAL);
1547 	}
1548 
1549 	vcpuid = (fault_ipa - vgic->redist_start) /
1550 	    (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE);
1551 	if (vcpuid >= vm_get_maxcpus(hyp->vm)) {
1552 		/*
1553 		 * This should never happen, but lets be defensive so if it
1554 		 * does we don't panic a non-INVARIANTS kernel.
1555 		 */
1556 #ifdef INVARIANTS
1557 		panic("%s: Invalid vcpuid %d", __func__, vcpuid);
1558 #else
1559 		return (0);
1560 #endif
1561 	}
1562 
1563 	/* Find the target vcpu ctx for the access */
1564 	target_hypctx = hyp->ctx[vcpuid];
1565 	if (target_hypctx == NULL) {
1566 		/*
1567 		 * The CPU has not yet started. The redistributor and CPU are
1568 		 * in the same power domain. As such the redistributor will
1569 		 * also be powered down so any access will raise an external
1570 		 * abort.
1571 		 */
1572 		raise_data_insn_abort(hypctx, fault_ipa, true,
1573 		    ISS_DATA_DFSC_EXT);
1574 		return (0);
1575 	}
1576 
1577 	reg = (fault_ipa - vgic->redist_start) %
1578 	    (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE);
1579 
1580 	/*
1581 	 * As described in vgic_register_read an access with an invalid
1582 	 * alignment is write ignored.
1583 	 */
1584 	if ((reg & (size - 1)) != 0)
1585 		return (0);
1586 
1587 	if (reg < GICR_RD_BASE_SIZE) {
1588 		if (vgic_register_write(target_hypctx, redist_rd_registers,
1589 		    nitems(redist_rd_registers), reg, size, wval, NULL))
1590 			return (0);
1591 	} else if (reg < (GICR_SGI_BASE + GICR_SGI_BASE_SIZE)) {
1592 		if (vgic_register_write(target_hypctx, redist_sgi_registers,
1593 		    nitems(redist_sgi_registers), reg - GICR_SGI_BASE, size,
1594 		    wval, NULL))
1595 			return (0);
1596 	}
1597 
1598 	/* Reserved register addresses are RES0 so we can ignore the write */
1599 	return (0);
1600 }
1601 
1602 static int
vgic_v3_icc_sgi1r_read(struct vcpu * vcpu,uint64_t * rval,void * arg)1603 vgic_v3_icc_sgi1r_read(struct vcpu *vcpu, uint64_t *rval, void *arg)
1604 {
1605 	/*
1606 	 * TODO: Inject an unknown exception.
1607 	 */
1608 	*rval = 0;
1609 	return (0);
1610 }
1611 
1612 static int
vgic_v3_icc_sgi1r_write(struct vcpu * vcpu,uint64_t rval,void * arg)1613 vgic_v3_icc_sgi1r_write(struct vcpu *vcpu, uint64_t rval, void *arg)
1614 {
1615 	struct vm *vm;
1616 	struct hyp *hyp;
1617 	cpuset_t active_cpus;
1618 	uint64_t mpidr, aff1, aff2, aff3;
1619 	uint32_t irqid;
1620 	int cpus, cpu_off, target_vcpuid, vcpuid;
1621 
1622 	vm = vcpu_vm(vcpu);
1623 	hyp = vm_get_cookie(vm);
1624 	active_cpus = vm_active_cpus(vm);
1625 	vcpuid = vcpu_vcpuid(vcpu);
1626 
1627 	irqid = ICC_SGI1R_EL1_SGIID_VAL(rval) >> ICC_SGI1R_EL1_SGIID_SHIFT;
1628 	if ((rval & ICC_SGI1R_EL1_IRM) == 0) {
1629 		/* Non-zero points at no vcpus */
1630 		if (ICC_SGI1R_EL1_RS_VAL(rval) != 0)
1631 			return (0);
1632 
1633 		aff1 = ICC_SGI1R_EL1_AFF1_VAL(rval) >> ICC_SGI1R_EL1_AFF1_SHIFT;
1634 		aff2 = ICC_SGI1R_EL1_AFF2_VAL(rval) >> ICC_SGI1R_EL1_AFF2_SHIFT;
1635 		aff3 = ICC_SGI1R_EL1_AFF3_VAL(rval) >> ICC_SGI1R_EL1_AFF3_SHIFT;
1636 		mpidr = aff3 << MPIDR_AFF3_SHIFT |
1637 		    aff2 << MPIDR_AFF2_SHIFT | aff1 << MPIDR_AFF1_SHIFT;
1638 
1639 		cpus = ICC_SGI1R_EL1_TL_VAL(rval) >> ICC_SGI1R_EL1_TL_SHIFT;
1640 		cpu_off = 0;
1641 		while (cpus > 0) {
1642 			if (cpus & 1) {
1643 				target_vcpuid = mpidr_to_vcpu(hyp,
1644 				    mpidr | (cpu_off << MPIDR_AFF0_SHIFT));
1645 				if (target_vcpuid >= 0 &&
1646 				    CPU_ISSET(target_vcpuid, &active_cpus)) {
1647 					INJECT_IRQ(hyp, target_vcpuid, irqid,
1648 					    true);
1649 				}
1650 			}
1651 			cpu_off++;
1652 			cpus >>= 1;
1653 		}
1654 	} else {
1655 		/* Send an IPI to all CPUs other than the current CPU */
1656 		for (target_vcpuid = 0; target_vcpuid < vm_get_maxcpus(vm);
1657 		    target_vcpuid++) {
1658 			if (CPU_ISSET(target_vcpuid, &active_cpus) &&
1659 			    target_vcpuid != vcpuid) {
1660 				INJECT_IRQ(hyp, target_vcpuid, irqid, true);
1661 			}
1662 		}
1663 	}
1664 
1665 	return (0);
1666 }
1667 
1668 static void
vgic_v3_mmio_init(struct hyp * hyp)1669 vgic_v3_mmio_init(struct hyp *hyp)
1670 {
1671 	struct vgic_v3 *vgic;
1672 	struct vgic_v3_irq *irq;
1673 	int i;
1674 
1675 	/* Allocate memory for the SPIs */
1676 	vgic = hyp->vgic;
1677 	vgic->irqs = malloc((VGIC_NIRQS - VGIC_PRV_I_NUM) *
1678 	    sizeof(*vgic->irqs), M_VGIC_V3, M_WAITOK | M_ZERO);
1679 
1680 	for (i = 0; i < VGIC_NIRQS - VGIC_PRV_I_NUM; i++) {
1681 		irq = &vgic->irqs[i];
1682 
1683 		mtx_init(&irq->irq_spinmtx, "VGIC IRQ spinlock", NULL,
1684 		    MTX_SPIN);
1685 
1686 		irq->irq = i + VGIC_PRV_I_NUM;
1687 	}
1688 }
1689 
1690 static void
vgic_v3_mmio_destroy(struct hyp * hyp)1691 vgic_v3_mmio_destroy(struct hyp *hyp)
1692 {
1693 	struct vgic_v3 *vgic;
1694 	struct vgic_v3_irq *irq;
1695 	int i;
1696 
1697 	vgic = hyp->vgic;
1698 	for (i = 0; i < VGIC_NIRQS - VGIC_PRV_I_NUM; i++) {
1699 		irq = &vgic->irqs[i];
1700 
1701 		mtx_destroy(&irq->irq_spinmtx);
1702 	}
1703 
1704 	free(vgic->irqs, M_VGIC_V3);
1705 }
1706 
1707 static int
vgic_v3_attach_to_vm(device_t dev,struct hyp * hyp,struct vm_vgic_descr * descr)1708 vgic_v3_attach_to_vm(device_t dev, struct hyp *hyp, struct vm_vgic_descr *descr)
1709 {
1710 	struct vm *vm;
1711 	struct vgic_v3 *vgic;
1712 	size_t cpu_count;
1713 
1714 	if (descr->ver.version != 3)
1715 		return (EINVAL);
1716 
1717 	/*
1718 	 * The register bases need to be 64k aligned
1719 	 * The redist register space is the RD + SGI size
1720 	 */
1721 	if (!__is_aligned(descr->v3_regs.dist_start, PAGE_SIZE_64K) ||
1722 	    !__is_aligned(descr->v3_regs.redist_start, PAGE_SIZE_64K) ||
1723 	    !__is_aligned(descr->v3_regs.redist_size,
1724 	     GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE))
1725 		return (EINVAL);
1726 
1727 	/* The dist register space is 1 64k block */
1728 	if (descr->v3_regs.dist_size != PAGE_SIZE_64K)
1729 		return (EINVAL);
1730 
1731 	vm = hyp->vm;
1732 
1733 	/*
1734 	 * Return an error if the redist space is too large for the maximum
1735 	 * number of CPUs we support.
1736 	 */
1737 	cpu_count = descr->v3_regs.redist_size /
1738 	    (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE);
1739 	if (cpu_count > vm_get_maxcpus(vm))
1740 		return (EINVAL);
1741 
1742 	vgic = hyp->vgic;
1743 
1744 	/* Set the distributor address and size for trapping guest access. */
1745 	vgic->dist_start = descr->v3_regs.dist_start;
1746 	vgic->dist_end = descr->v3_regs.dist_start + descr->v3_regs.dist_size;
1747 
1748 	vgic->redist_start = descr->v3_regs.redist_start;
1749 	vgic->redist_end = descr->v3_regs.redist_start +
1750 	    descr->v3_regs.redist_size;
1751 
1752 	vm_register_inst_handler(vm, descr->v3_regs.dist_start,
1753 	    descr->v3_regs.dist_size, dist_read, dist_write);
1754 	vm_register_inst_handler(vm, descr->v3_regs.redist_start,
1755 	    descr->v3_regs.redist_size, redist_read, redist_write);
1756 
1757 	vm_register_reg_handler(vm, ISS_MSR_REG(ICC_SGI1R_EL1),
1758 	    ISS_MSR_REG_MASK, vgic_v3_icc_sgi1r_read, vgic_v3_icc_sgi1r_write,
1759 	    NULL);
1760 
1761 	vgic_v3_mmio_init(hyp);
1762 
1763 	hyp->vgic_attached = true;
1764 
1765 	return (0);
1766 }
1767 
1768 static void
vgic_v3_detach_from_vm(device_t dev,struct hyp * hyp)1769 vgic_v3_detach_from_vm(device_t dev, struct hyp *hyp)
1770 {
1771 	if (hyp->vgic_attached) {
1772 		hyp->vgic_attached = false;
1773 		vgic_v3_mmio_destroy(hyp);
1774 	}
1775 }
1776 
1777 static struct vgic_v3_irq *
vgic_v3_get_irq(struct hyp * hyp,int vcpuid,uint32_t irqid)1778 vgic_v3_get_irq(struct hyp *hyp, int vcpuid, uint32_t irqid)
1779 {
1780 	struct vgic_v3_cpu *vgic_cpu;
1781 	struct vgic_v3_irq *irq;
1782 	struct hypctx *hypctx;
1783 
1784 	if (irqid < VGIC_PRV_I_NUM) {
1785 		if (vcpuid < 0 || vcpuid >= vm_get_maxcpus(hyp->vm))
1786 			return (NULL);
1787 		hypctx = hyp->ctx[vcpuid];
1788 		if (hypctx == NULL)
1789 			return (NULL);
1790 		vgic_cpu = hypctx->vgic_cpu;
1791 		irq = &vgic_cpu->private_irqs[irqid];
1792 	} else if (irqid <= GIC_LAST_SPI) {
1793 		irqid -= VGIC_PRV_I_NUM;
1794 		if (irqid >= VGIC_NIRQS)
1795 			return (NULL);
1796 		irq = &hyp->vgic->irqs[irqid];
1797 	} else if (irqid < GIC_FIRST_LPI) {
1798 		return (NULL);
1799 	} else {
1800 		/* No support for LPIs */
1801 		return (NULL);
1802 	}
1803 
1804 	mtx_lock_spin(&irq->irq_spinmtx);
1805 	return (irq);
1806 }
1807 
1808 static void
vgic_v3_release_irq(struct vgic_v3_irq * irq)1809 vgic_v3_release_irq(struct vgic_v3_irq *irq)
1810 {
1811 
1812 	mtx_unlock_spin(&irq->irq_spinmtx);
1813 }
1814 
1815 static bool
vgic_v3_has_pending_irq(device_t dev,struct hypctx * hypctx)1816 vgic_v3_has_pending_irq(device_t dev, struct hypctx *hypctx)
1817 {
1818 	struct vgic_v3_cpu *vgic_cpu;
1819 	bool empty;
1820 
1821 	vgic_cpu = hypctx->vgic_cpu;
1822 	mtx_lock_spin(&vgic_cpu->lr_mtx);
1823 	empty = TAILQ_EMPTY(&vgic_cpu->irq_act_pend);
1824 	mtx_unlock_spin(&vgic_cpu->lr_mtx);
1825 
1826 	return (!empty);
1827 }
1828 
1829 static bool
vgic_v3_check_irq(struct vgic_v3_irq * irq,bool level)1830 vgic_v3_check_irq(struct vgic_v3_irq *irq, bool level)
1831 {
1832 	/*
1833 	 * Only inject if:
1834 	 *  - Level-triggered IRQ: level changes low -> high
1835 	 *  - Edge-triggered IRQ: level is high
1836 	 */
1837 	switch (irq->config & VGIC_CONFIG_MASK) {
1838 	case VGIC_CONFIG_LEVEL:
1839 		return (level != irq->level);
1840 	case VGIC_CONFIG_EDGE:
1841 		return (level);
1842 	default:
1843 		break;
1844 	}
1845 
1846 	return (false);
1847 }
1848 
1849 static int
vgic_v3_inject_irq(device_t dev,struct hyp * hyp,int vcpuid,uint32_t irqid,bool level)1850 vgic_v3_inject_irq(device_t dev, struct hyp *hyp, int vcpuid, uint32_t irqid,
1851     bool level)
1852 {
1853 	struct vgic_v3_cpu *vgic_cpu;
1854 	struct vgic_v3_irq *irq;
1855 	struct hypctx *hypctx;
1856 	int target_vcpu;
1857 	bool notify;
1858 
1859 	if (!hyp->vgic_attached)
1860 		return (ENODEV);
1861 
1862 	KASSERT(vcpuid == -1 || irqid < VGIC_PRV_I_NUM,
1863 	    ("%s: SPI/LPI with vcpuid set: irq %u vcpuid %u", __func__, irqid,
1864 	    vcpuid));
1865 
1866 	irq = vgic_v3_get_irq(hyp, vcpuid, irqid);
1867 	if (irq == NULL) {
1868 		eprintf("Malformed IRQ %u.\n", irqid);
1869 		return (EINVAL);
1870 	}
1871 
1872 	target_vcpu = irq->target_vcpu;
1873 	KASSERT(vcpuid == -1 || vcpuid == target_vcpu,
1874 	    ("%s: Interrupt %u has bad cpu affinity: vcpu %d target vcpu %d",
1875 	    __func__, irqid, vcpuid, target_vcpu));
1876 	KASSERT(target_vcpu >= 0 && target_vcpu < vm_get_maxcpus(hyp->vm),
1877 	    ("%s: Interrupt %u sent to invalid vcpu %d", __func__, irqid,
1878 	    target_vcpu));
1879 
1880 	if (vcpuid == -1)
1881 		vcpuid = target_vcpu;
1882 	/* TODO: Check from 0 to vm->maxcpus */
1883 	if (vcpuid < 0 || vcpuid >= vm_get_maxcpus(hyp->vm)) {
1884 		vgic_v3_release_irq(irq);
1885 		return (EINVAL);
1886 	}
1887 
1888 	hypctx = hyp->ctx[vcpuid];
1889 	if (hypctx == NULL) {
1890 		vgic_v3_release_irq(irq);
1891 		return (EINVAL);
1892 	}
1893 
1894 	notify = false;
1895 	vgic_cpu = hypctx->vgic_cpu;
1896 
1897 	mtx_lock_spin(&vgic_cpu->lr_mtx);
1898 
1899 	if (!vgic_v3_check_irq(irq, level)) {
1900 		goto out;
1901 	}
1902 
1903 	if ((irq->config & VGIC_CONFIG_MASK) == VGIC_CONFIG_LEVEL)
1904 		irq->level = level;
1905 	else /* VGIC_CONFIG_EDGE */
1906 		irq->pending = true;
1907 
1908 	notify = vgic_v3_queue_irq(hyp, vgic_cpu, vcpuid, irq);
1909 
1910 out:
1911 	mtx_unlock_spin(&vgic_cpu->lr_mtx);
1912 	vgic_v3_release_irq(irq);
1913 
1914 	if (notify)
1915 		vcpu_notify_event(vm_vcpu(hyp->vm, vcpuid));
1916 
1917 	return (0);
1918 }
1919 
1920 static int
vgic_v3_inject_msi(device_t dev,struct hyp * hyp,uint64_t msg,uint64_t addr)1921 vgic_v3_inject_msi(device_t dev, struct hyp *hyp, uint64_t msg, uint64_t addr)
1922 {
1923 	struct vgic_v3 *vgic;
1924 	uint64_t reg;
1925 
1926 	vgic = hyp->vgic;
1927 
1928 	/* This is a 4 byte register */
1929 	if (addr < vgic->dist_start || addr + 4 > vgic->dist_end) {
1930 		return (EINVAL);
1931 	}
1932 
1933 	reg = addr - vgic->dist_start;
1934 	if (reg != GICD_SETSPI_NSR)
1935 		return (EINVAL);
1936 
1937 	return (INJECT_IRQ(hyp, -1, msg, true));
1938 }
1939 
1940 static void
vgic_v3_flush_hwstate(device_t dev,struct hypctx * hypctx)1941 vgic_v3_flush_hwstate(device_t dev, struct hypctx *hypctx)
1942 {
1943 	struct vgic_v3_cpu *vgic_cpu;
1944 	struct vgic_v3_irq *irq;
1945 	int i;
1946 
1947 	vgic_cpu = hypctx->vgic_cpu;
1948 
1949 	/*
1950 	 * All Distributor writes have been executed at this point, do not
1951 	 * protect Distributor reads with a mutex.
1952 	 *
1953 	 * This is callled with all interrupts disabled, so there is no need for
1954 	 * a List Register spinlock either.
1955 	 */
1956 	mtx_lock_spin(&vgic_cpu->lr_mtx);
1957 
1958 	*hypctx_sys_reg(hypctx, HOST_ICH_HCR_EL2) &= ~ICH_HCR_EL2_UIE;
1959 
1960 	/* Exit early if there are no buffered interrupts */
1961 	if (TAILQ_EMPTY(&vgic_cpu->irq_act_pend))
1962 		goto out;
1963 
1964 	KASSERT(vgic_cpu->ich_lr_used == 0, ("%s: Used LR count not zero %u",
1965 	    __func__, vgic_cpu->ich_lr_used));
1966 
1967 	i = 0;
1968 	hypctx_write_sys_reg(hypctx, HOST_ICH_ELRSR_EL2,
1969 	    (1u << hypctx->vgic_v3.ich_lr_num) - 1);
1970 	TAILQ_FOREACH(irq, &vgic_cpu->irq_act_pend, act_pend_list) {
1971 		/* No free list register, stop searching for IRQs */
1972 		if (i == hypctx->vgic_v3.ich_lr_num)
1973 			break;
1974 
1975 		/*
1976 		 * NB: Disabled active interrupts are kept around for EOI to
1977 		 * make them inactive, since we don't enable maintenace
1978 		 * interrupts to intercept EOIs for interrupts not in a list
1979 		 * register.
1980 		 */
1981 		if (!irq->enabled && !irq->active)
1982 			continue;
1983 
1984 		hypctx_write_sys_reg(hypctx, HOST_ICH_LR_EL2(i),
1985 		    ICH_LR_EL2_GROUP1 |
1986 			((uint64_t)irq->priority << ICH_LR_EL2_PRIO_SHIFT) |
1987 				irq->irq);
1988 
1989 		if (irq->active) {
1990 			*hypctx_sys_reg(hypctx, HOST_ICH_LR_EL2(i)) |=
1991 			    ICH_LR_EL2_STATE_ACTIVE;
1992 		}
1993 
1994 #ifdef notyet
1995 		/* TODO: Check why this is needed */
1996 		if ((irq->config & _MASK) == LEVEL)
1997 			*hypctx_sys_reg(hypctx, HOST_ICH_LR_EL2(i)) |= ICH_LR_EL2_EOI;
1998 #endif
1999 
2000 		if (!irq->active && vgic_v3_irq_pending(irq)) {
2001 			*hypctx_sys_reg(hypctx, HOST_ICH_LR_EL2(i)) |=
2002 			    ICH_LR_EL2_STATE_PENDING;
2003 
2004 			/*
2005 			 * This IRQ is now pending on the guest. Allow for
2006 			 * another edge that could cause the interrupt to
2007 			 * be raised again.
2008 			 */
2009 			if ((irq->config & VGIC_CONFIG_MASK) ==
2010 			    VGIC_CONFIG_EDGE) {
2011 				irq->pending = false;
2012 			}
2013 		}
2014 
2015 		i++;
2016 	}
2017 	vgic_cpu->ich_lr_used = i;
2018 
2019 out:
2020 	mtx_unlock_spin(&vgic_cpu->lr_mtx);
2021 }
2022 
2023 static void
vgic_v3_sync_hwstate(device_t dev,struct hypctx * hypctx)2024 vgic_v3_sync_hwstate(device_t dev, struct hypctx *hypctx)
2025 {
2026 	struct vgic_v3_cpu *vgic_cpu;
2027 	struct vgic_v3_irq *irq;
2028 	uint64_t lr;
2029 	int i;
2030 
2031 	vgic_cpu = hypctx->vgic_cpu;
2032 
2033 	/* Exit early if there are no buffered interrupts */
2034 	if (vgic_cpu->ich_lr_used == 0)
2035 		return;
2036 
2037 	/*
2038 	 * Check on the IRQ state after running the guest. ich_lr_used and
2039 	 * ich_lr_el2 are only ever used within this thread so is safe to
2040 	 * access unlocked.
2041 	 */
2042 	for (i = 0; i < vgic_cpu->ich_lr_used; i++) {
2043 		lr = hypctx_read_sys_reg(hypctx, HOST_ICH_LR_EL2(i));
2044 		hypctx_write_sys_reg(hypctx, HOST_ICH_LR_EL2(i), 0);
2045 
2046 		irq = vgic_v3_get_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu),
2047 		    ICH_LR_EL2_VINTID(lr));
2048 		if (irq == NULL)
2049 			continue;
2050 
2051 		irq->active = (lr & ICH_LR_EL2_STATE_ACTIVE) != 0;
2052 
2053 		if ((irq->config & VGIC_CONFIG_MASK) == VGIC_CONFIG_EDGE) {
2054 			/*
2055 			 * If we have an edge triggered IRQ preserve the
2056 			 * pending bit until the IRQ has been handled.
2057 			 */
2058 			if ((lr & ICH_LR_EL2_STATE_PENDING) != 0) {
2059 				irq->pending = true;
2060 			}
2061 		} else {
2062 			/*
2063 			 * If we have a level triggerend IRQ remove the
2064 			 * pending bit if the IRQ has been handled.
2065 			 * The level is separate, so may still be high
2066 			 * triggering another IRQ.
2067 			 */
2068 			if ((lr & ICH_LR_EL2_STATE_PENDING) == 0) {
2069 				irq->pending = false;
2070 			}
2071 		}
2072 
2073 		/* Lock to update irq_act_pend */
2074 		mtx_lock_spin(&vgic_cpu->lr_mtx);
2075 		if (irq->active) {
2076 			/* Ensure the active IRQ is at the head of the list */
2077 			TAILQ_REMOVE(&vgic_cpu->irq_act_pend, irq,
2078 			    act_pend_list);
2079 			TAILQ_INSERT_HEAD(&vgic_cpu->irq_act_pend, irq,
2080 			    act_pend_list);
2081 		} else if (!vgic_v3_irq_pending(irq)) {
2082 			/* If pending or active remove from the list */
2083 			TAILQ_REMOVE(&vgic_cpu->irq_act_pend, irq,
2084 			    act_pend_list);
2085 			irq->on_aplist = false;
2086 		}
2087 		mtx_unlock_spin(&vgic_cpu->lr_mtx);
2088 		vgic_v3_release_irq(irq);
2089 	}
2090 
2091 	*hypctx_sys_reg(hypctx, HOST_ICH_HCR_EL2) &= ~ICH_HCR_EL2_EOICOUNT_MASK;
2092 	vgic_cpu->ich_lr_used = 0;
2093 }
2094 
2095 static void
vgic_v3_init(device_t dev)2096 vgic_v3_init(device_t dev)
2097 {
2098 	uint64_t ich_vtr_el2;
2099 	uint32_t pribits, prebits;
2100 
2101 	ich_vtr_el2 = vmm_read_reg(HYP_REG_ICH_VTR);
2102 
2103 	/* TODO: These fields are common with the vgicv2 driver */
2104 	pribits = ICH_VTR_EL2_PRIBITS(ich_vtr_el2);
2105 	switch (pribits) {
2106 	default:
2107 	case 5:
2108 		virt_features.min_prio = 0xf8;
2109 		break;
2110 	case 6:
2111 		virt_features.min_prio = 0xfc;
2112 		break;
2113 	case 7:
2114 		virt_features.min_prio = 0xfe;
2115 		break;
2116 	case 8:
2117 		virt_features.min_prio = 0xff;
2118 		break;
2119 	}
2120 
2121 	prebits = ICH_VTR_EL2_PREBITS(ich_vtr_el2);
2122 	switch (prebits) {
2123 	default:
2124 	case 5:
2125 		virt_features.ich_apr_num = 1;
2126 		break;
2127 	case 6:
2128 		virt_features.ich_apr_num = 2;
2129 		break;
2130 	case 7:
2131 		virt_features.ich_apr_num = 4;
2132 		break;
2133 	}
2134 
2135 	virt_features.ich_lr_num = ICH_VTR_EL2_LISTREGS(ich_vtr_el2);
2136 }
2137 
2138 static int
vgic_v3_probe(device_t dev)2139 vgic_v3_probe(device_t dev)
2140 {
2141 	if (!gic_get_vgic(dev))
2142 		return (EINVAL);
2143 
2144 	/* We currently only support the GICv3 */
2145 	if (gic_get_hw_rev(dev) < 3)
2146 		return (EINVAL);
2147 
2148 	device_set_desc(dev, "Virtual GIC v3");
2149 	return (BUS_PROBE_DEFAULT);
2150 }
2151 
2152 static int
vgic_v3_attach(device_t dev)2153 vgic_v3_attach(device_t dev)
2154 {
2155 	vgic_dev = dev;
2156 	return (0);
2157 }
2158 
2159 static int
vgic_v3_detach(device_t dev)2160 vgic_v3_detach(device_t dev)
2161 {
2162 	vgic_dev = NULL;
2163 	return (0);
2164 }
2165 
2166 static device_method_t vgic_v3_methods[] = {
2167 	/* Device interface */
2168 	DEVMETHOD(device_probe,		vgic_v3_probe),
2169 	DEVMETHOD(device_attach,	vgic_v3_attach),
2170 	DEVMETHOD(device_detach,	vgic_v3_detach),
2171 
2172 	/* VGIC interface */
2173 	DEVMETHOD(vgic_init,		vgic_v3_init),
2174 	DEVMETHOD(vgic_attach_to_vm,	vgic_v3_attach_to_vm),
2175 	DEVMETHOD(vgic_detach_from_vm,	vgic_v3_detach_from_vm),
2176 	DEVMETHOD(vgic_vminit,		vgic_v3_vminit),
2177 	DEVMETHOD(vgic_cpuinit,		vgic_v3_cpuinit),
2178 	DEVMETHOD(vgic_cpucleanup,	vgic_v3_cpucleanup),
2179 	DEVMETHOD(vgic_vmcleanup,	vgic_v3_vmcleanup),
2180 	DEVMETHOD(vgic_max_cpu_count,	vgic_v3_max_cpu_count),
2181 	DEVMETHOD(vgic_has_pending_irq,	vgic_v3_has_pending_irq),
2182 	DEVMETHOD(vgic_inject_irq,	vgic_v3_inject_irq),
2183 	DEVMETHOD(vgic_inject_msi,	vgic_v3_inject_msi),
2184 	DEVMETHOD(vgic_flush_hwstate,	vgic_v3_flush_hwstate),
2185 	DEVMETHOD(vgic_sync_hwstate,	vgic_v3_sync_hwstate),
2186 
2187 	/* End */
2188 	DEVMETHOD_END
2189 };
2190 
2191 /* TODO: Create a vgic base class? */
2192 DEFINE_CLASS_0(vgic, vgic_v3_driver, vgic_v3_methods, 0);
2193 
2194 DRIVER_MODULE(vgic_v3, gic, vgic_v3_driver, 0, 0);
2195