xref: /kvm-unit-tests/arm/gic.c (revision ba74b1063d21003ff7de7a84af121af2d3663c1f)
1 /*
2  * GIC tests
3  *
4  * GICv2
5  *   + test sending/receiving IPIs
6  *   + MMIO access tests
7  * GICv3
8  *   + test sending/receiving IPIs
9  *
10  * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
11  *
12  * This work is licensed under the terms of the GNU LGPL, version 2.
13  */
14 #include <libcflat.h>
15 #include <asm/setup.h>
16 #include <asm/processor.h>
17 #include <asm/delay.h>
18 #include <asm/gic.h>
19 #include <asm/gic-v3-its.h>
20 #include <asm/smp.h>
21 #include <asm/barrier.h>
22 #include <asm/io.h>
23 
24 #define IPI_SENDER	1
25 #define IPI_IRQ		1
26 
27 struct gic {
28 	struct {
29 		void (*send_self)(void);
30 		void (*send_broadcast)(void);
31 	} ipi;
32 };
33 
34 static struct gic *gic;
35 static int acked[NR_CPUS], spurious[NR_CPUS];
36 static int bad_sender[NR_CPUS], bad_irq[NR_CPUS];
37 static cpumask_t ready;
38 
39 static void nr_cpu_check(int nr)
40 {
41 	if (nr_cpus < nr)
42 		report_abort("At least %d cpus required", nr);
43 }
44 
45 static void wait_on_ready(void)
46 {
47 	cpumask_set_cpu(smp_processor_id(), &ready);
48 	while (!cpumask_full(&ready))
49 		cpu_relax();
50 }
51 
52 static void stats_reset(void)
53 {
54 	int i;
55 
56 	for (i = 0; i < nr_cpus; ++i) {
57 		acked[i] = 0;
58 		bad_sender[i] = -1;
59 		bad_irq[i] = -1;
60 	}
61 	smp_wmb();
62 }
63 
64 static void check_acked(const char *testname, cpumask_t *mask)
65 {
66 	int missing = 0, extra = 0, unexpected = 0;
67 	int nr_pass, cpu, i;
68 	bool bad = false;
69 
70 	/* Wait up to 5s for all interrupts to be delivered */
71 	for (i = 0; i < 50; ++i) {
72 		mdelay(100);
73 		nr_pass = 0;
74 		for_each_present_cpu(cpu) {
75 			smp_rmb();
76 			nr_pass += cpumask_test_cpu(cpu, mask) ?
77 				acked[cpu] == 1 : acked[cpu] == 0;
78 
79 			if (bad_sender[cpu] != -1) {
80 				printf("cpu%d received IPI from wrong sender %d\n",
81 					cpu, bad_sender[cpu]);
82 				bad = true;
83 			}
84 
85 			if (bad_irq[cpu] != -1) {
86 				printf("cpu%d received wrong irq %d\n",
87 					cpu, bad_irq[cpu]);
88 				bad = true;
89 			}
90 		}
91 		if (nr_pass == nr_cpus) {
92 			report(!bad, "%s", testname);
93 			if (i)
94 				report_info("took more than %d ms", i * 100);
95 			return;
96 		}
97 	}
98 
99 	for_each_present_cpu(cpu) {
100 		if (cpumask_test_cpu(cpu, mask)) {
101 			if (!acked[cpu])
102 				++missing;
103 			else if (acked[cpu] > 1)
104 				++extra;
105 		} else {
106 			if (acked[cpu])
107 				++unexpected;
108 		}
109 	}
110 
111 	report(false, "%s", testname);
112 	report_info("Timed-out (5s). ACKS: missing=%d extra=%d unexpected=%d",
113 		    missing, extra, unexpected);
114 }
115 
116 static void check_spurious(void)
117 {
118 	int cpu;
119 
120 	smp_rmb();
121 	for_each_present_cpu(cpu) {
122 		if (spurious[cpu])
123 			report_info("WARN: cpu%d got %d spurious interrupts",
124 				cpu, spurious[cpu]);
125 	}
126 }
127 
128 static void check_ipi_sender(u32 irqstat)
129 {
130 	if (gic_version() == 2) {
131 		int src = (irqstat >> 10) & 7;
132 
133 		if (src != IPI_SENDER)
134 			bad_sender[smp_processor_id()] = src;
135 	}
136 }
137 
138 static void check_irqnr(u32 irqnr)
139 {
140 	if (irqnr != IPI_IRQ)
141 		bad_irq[smp_processor_id()] = irqnr;
142 }
143 
144 static void ipi_handler(struct pt_regs *regs __unused)
145 {
146 	u32 irqstat = gic_read_iar();
147 	u32 irqnr = gic_iar_irqnr(irqstat);
148 
149 	if (irqnr != GICC_INT_SPURIOUS) {
150 		gic_write_eoir(irqstat);
151 		smp_rmb(); /* pairs with wmb in stats_reset */
152 		++acked[smp_processor_id()];
153 		check_ipi_sender(irqstat);
154 		check_irqnr(irqnr);
155 		smp_wmb(); /* pairs with rmb in check_acked */
156 	} else {
157 		++spurious[smp_processor_id()];
158 		smp_wmb();
159 	}
160 }
161 
162 static void gicv2_ipi_send_self(void)
163 {
164 	writel(2 << 24 | IPI_IRQ, gicv2_dist_base() + GICD_SGIR);
165 }
166 
167 static void gicv2_ipi_send_broadcast(void)
168 {
169 	writel(1 << 24 | IPI_IRQ, gicv2_dist_base() + GICD_SGIR);
170 }
171 
172 static void gicv3_ipi_send_self(void)
173 {
174 	gic_ipi_send_single(IPI_IRQ, smp_processor_id());
175 }
176 
177 static void gicv3_ipi_send_broadcast(void)
178 {
179 	gicv3_write_sgi1r(1ULL << 40 | IPI_IRQ << 24);
180 	isb();
181 }
182 
183 static void ipi_test_self(void)
184 {
185 	cpumask_t mask;
186 
187 	report_prefix_push("self");
188 	stats_reset();
189 	cpumask_clear(&mask);
190 	cpumask_set_cpu(smp_processor_id(), &mask);
191 	gic->ipi.send_self();
192 	check_acked("IPI: self", &mask);
193 	report_prefix_pop();
194 }
195 
196 static void ipi_test_smp(void)
197 {
198 	cpumask_t mask;
199 	int i;
200 
201 	report_prefix_push("target-list");
202 	stats_reset();
203 	cpumask_copy(&mask, &cpu_present_mask);
204 	for (i = smp_processor_id() & 1; i < nr_cpus; i += 2)
205 		cpumask_clear_cpu(i, &mask);
206 	gic_ipi_send_mask(IPI_IRQ, &mask);
207 	check_acked("IPI: directed", &mask);
208 	report_prefix_pop();
209 
210 	report_prefix_push("broadcast");
211 	stats_reset();
212 	cpumask_copy(&mask, &cpu_present_mask);
213 	cpumask_clear_cpu(smp_processor_id(), &mask);
214 	gic->ipi.send_broadcast();
215 	check_acked("IPI: broadcast", &mask);
216 	report_prefix_pop();
217 }
218 
219 static void setup_irq(irq_handler_fn handler)
220 {
221 	gic_enable_defaults();
222 #ifdef __arm__
223 	install_exception_handler(EXCPTN_IRQ, handler);
224 #else
225 	install_irq_handler(EL1H_IRQ, handler);
226 #endif
227 	local_irq_enable();
228 }
229 
230 static void ipi_send(void)
231 {
232 	setup_irq(ipi_handler);
233 	wait_on_ready();
234 	ipi_test_self();
235 	ipi_test_smp();
236 	check_spurious();
237 	exit(report_summary());
238 }
239 
240 static void ipi_recv(void)
241 {
242 	setup_irq(ipi_handler);
243 	cpumask_set_cpu(smp_processor_id(), &ready);
244 	while (1)
245 		wfi();
246 }
247 
248 static void ipi_test(void *data __unused)
249 {
250 	if (smp_processor_id() == IPI_SENDER)
251 		ipi_send();
252 	else
253 		ipi_recv();
254 }
255 
256 static struct gic gicv2 = {
257 	.ipi = {
258 		.send_self = gicv2_ipi_send_self,
259 		.send_broadcast = gicv2_ipi_send_broadcast,
260 	},
261 };
262 
263 static struct gic gicv3 = {
264 	.ipi = {
265 		.send_self = gicv3_ipi_send_self,
266 		.send_broadcast = gicv3_ipi_send_broadcast,
267 	},
268 };
269 
270 static void ipi_clear_active_handler(struct pt_regs *regs __unused)
271 {
272 	u32 irqstat = gic_read_iar();
273 	u32 irqnr = gic_iar_irqnr(irqstat);
274 
275 	if (irqnr != GICC_INT_SPURIOUS) {
276 		void *base;
277 		u32 val = 1 << IPI_IRQ;
278 
279 		if (gic_version() == 2)
280 			base = gicv2_dist_base();
281 		else
282 			base = gicv3_sgi_base();
283 
284 		writel(val, base + GICD_ICACTIVER);
285 
286 		smp_rmb(); /* pairs with wmb in stats_reset */
287 		++acked[smp_processor_id()];
288 		check_irqnr(irqnr);
289 		smp_wmb(); /* pairs with rmb in check_acked */
290 	} else {
291 		++spurious[smp_processor_id()];
292 		smp_wmb();
293 	}
294 }
295 
296 static void run_active_clear_test(void)
297 {
298 	report_prefix_push("active");
299 	setup_irq(ipi_clear_active_handler);
300 	ipi_test_self();
301 	report_prefix_pop();
302 }
303 
304 static bool test_ro_pattern_32(void *address, u32 pattern, u32 orig)
305 {
306 	u32 reg;
307 
308 	writel(pattern, address);
309 	reg = readl(address);
310 
311 	if (reg != orig)
312 		writel(orig, address);
313 
314 	return reg == orig;
315 }
316 
317 static bool test_readonly_32(void *address, bool razwi)
318 {
319 	u32 orig, pattern;
320 
321 	orig = readl(address);
322 	if (razwi && orig)
323 		return false;
324 
325 	pattern = 0xffffffff;
326 	if (orig != pattern) {
327 		if (!test_ro_pattern_32(address, pattern, orig))
328 			return false;
329 	}
330 
331 	pattern = 0xa5a55a5a;
332 	if (orig != pattern) {
333 		if (!test_ro_pattern_32(address, pattern, orig))
334 			return false;
335 	}
336 
337 	pattern = 0;
338 	if (orig != pattern) {
339 		if (!test_ro_pattern_32(address, pattern, orig))
340 			return false;
341 	}
342 
343 	return true;
344 }
345 
346 static void test_typer_v2(uint32_t reg)
347 {
348 	int nr_gic_cpus = ((reg >> 5) & 0x7) + 1;
349 
350 	report_info("nr_cpus=%d", nr_cpus);
351 	report(nr_cpus == nr_gic_cpus, "all CPUs have interrupts");
352 }
353 
354 #define BYTE(reg32, byte) (((reg32) >> ((byte) * 8)) & 0xff)
355 #define REPLACE_BYTE(reg32, byte, new) (((reg32) & ~(0xff << ((byte) * 8))) |\
356 					((new) << ((byte) * 8)))
357 
358 /*
359  * Some registers are byte accessible, do a byte-wide read and write of known
360  * content to check for this.
361  * Apply a @mask to cater for special register properties.
362  * @pattern contains the value already in the register.
363  */
364 static void test_byte_access(void *base_addr, u32 pattern, u32 mask)
365 {
366 	u32 reg = readb(base_addr + 1);
367 	bool res;
368 
369 	res = (reg == (BYTE(pattern, 1) & (mask >> 8)));
370 	report(res, "byte reads successful");
371 	if (!res)
372 		report_info("byte 1 of 0x%08x => 0x%02x", pattern & mask, reg);
373 
374 	pattern = REPLACE_BYTE(pattern, 2, 0x1f);
375 	writeb(BYTE(pattern, 2), base_addr + 2);
376 	reg = readl(base_addr);
377 	res = (reg == (pattern & mask));
378 	report(res, "byte writes successful");
379 	if (!res)
380 		report_info("writing 0x%02x into bytes 2 => 0x%08x",
381 			    BYTE(pattern, 2), reg);
382 }
383 
384 static void test_priorities(int nr_irqs, void *priptr)
385 {
386 	u32 orig_prio, reg, pri_bits;
387 	u32 pri_mask, pattern;
388 	void *first_spi = priptr + GIC_FIRST_SPI;
389 
390 	orig_prio = readl(first_spi);
391 	report_prefix_push("IPRIORITYR");
392 
393 	/*
394 	 * Determine implemented number of priority bits by writing all 1's
395 	 * and checking the number of cleared bits in the value read back.
396 	 */
397 	writel(0xffffffff, first_spi);
398 	pri_mask = readl(first_spi);
399 
400 	reg = ~pri_mask;
401 	report((((reg >> 16) == (reg & 0xffff)) &&
402 	        ((reg & 0xff) == ((reg >> 8) & 0xff))),
403 	       "consistent priority masking");
404 	report_info("priority mask is 0x%08x", pri_mask);
405 
406 	reg = reg & 0xff;
407 	for (pri_bits = 8; reg & 1; reg >>= 1, pri_bits--)
408 		;
409 	report(pri_bits >= 4, "implements at least 4 priority bits");
410 	report_info("%d priority bits implemented", pri_bits);
411 
412 	pattern = 0;
413 	writel(pattern, first_spi);
414 	report(readl(first_spi) == pattern, "clearing priorities");
415 
416 	/* setting all priorities to their max valus was tested above */
417 
418 	report(test_readonly_32(priptr + nr_irqs, true),
419 	       "accesses beyond limit RAZ/WI");
420 
421 	writel(pattern, priptr + nr_irqs - 4);
422 	report(readl(priptr + nr_irqs - 4) == (pattern & pri_mask),
423 	       "accessing last SPIs");
424 
425 	pattern = 0xff7fbf3f;
426 	writel(pattern, first_spi);
427 	report(readl(first_spi) == (pattern & pri_mask),
428 	       "priorities are preserved");
429 
430 	/* The PRIORITY registers are byte accessible. */
431 	test_byte_access(first_spi, pattern, pri_mask);
432 
433 	report_prefix_pop();
434 	writel(orig_prio, first_spi);
435 }
436 
437 /* GICD_ITARGETSR is only used by GICv2. */
438 static void test_targets(int nr_irqs)
439 {
440 	void *targetsptr = gicv2_dist_base() + GICD_ITARGETSR;
441 	u32 orig_targets;
442 	u32 cpu_mask;
443 	u32 pattern, reg;
444 
445 	orig_targets = readl(targetsptr + GIC_FIRST_SPI);
446 	report_prefix_push("ITARGETSR");
447 
448 	cpu_mask = (1 << nr_cpus) - 1;
449 	cpu_mask |= cpu_mask << 8;
450 	cpu_mask |= cpu_mask << 16;
451 
452 	/* Check that bits for non implemented CPUs are RAZ/WI. */
453 	if (nr_cpus < 8) {
454 		writel(0xffffffff, targetsptr + GIC_FIRST_SPI);
455 		report(!(readl(targetsptr + GIC_FIRST_SPI) & ~cpu_mask),
456 		       "bits for non-existent CPUs masked");
457 		report_info("%d non-existent CPUs", 8 - nr_cpus);
458 	} else {
459 		report_skip("CPU masking (all CPUs implemented)");
460 	}
461 
462 	report(test_readonly_32(targetsptr + nr_irqs, true),
463 	       "accesses beyond limit RAZ/WI");
464 
465 	pattern = 0x0103020f;
466 	writel(pattern, targetsptr + GIC_FIRST_SPI);
467 	reg = readl(targetsptr + GIC_FIRST_SPI);
468 	report(reg == (pattern & cpu_mask), "register content preserved");
469 	if (reg != (pattern & cpu_mask))
470 		report_info("writing %08x reads back as %08x",
471 			    pattern & cpu_mask, reg);
472 
473 	/* The TARGETS registers are byte accessible. */
474 	test_byte_access(targetsptr + GIC_FIRST_SPI, pattern, cpu_mask);
475 
476 	writel(orig_targets, targetsptr + GIC_FIRST_SPI);
477 
478 	report_prefix_pop();
479 }
480 
481 static void gic_test_mmio(void)
482 {
483 	u32 reg;
484 	int nr_irqs;
485 	void *gic_dist_base, *idreg;
486 
487 	switch(gic_version()) {
488 	case 0x2:
489 		gic_dist_base = gicv2_dist_base();
490 		idreg = gic_dist_base + GICD_ICPIDR2;
491 		break;
492 	case 0x3:
493 		report_abort("GICv3 MMIO tests NYI");
494 	default:
495 		report_abort("GIC version %d not supported", gic_version());
496 	}
497 
498 	reg = readl(gic_dist_base + GICD_TYPER);
499 	nr_irqs = GICD_TYPER_IRQS(reg);
500 	report_info("number of implemented SPIs: %d", nr_irqs - GIC_FIRST_SPI);
501 
502 	test_typer_v2(reg);
503 
504 	report_info("IIDR: 0x%08x", readl(gic_dist_base + GICD_IIDR));
505 
506 	report(test_readonly_32(gic_dist_base + GICD_TYPER, false),
507                "GICD_TYPER is read-only");
508 	report(test_readonly_32(gic_dist_base + GICD_IIDR, false),
509                "GICD_IIDR is read-only");
510 
511 	reg = readl(idreg);
512 	report(test_readonly_32(idreg, false), "ICPIDR2 is read-only");
513 	report_info("value of ICPIDR2: 0x%08x", reg);
514 
515 	test_priorities(nr_irqs, gic_dist_base + GICD_IPRIORITYR);
516 
517 	if (gic_version() == 2)
518 		test_targets(nr_irqs);
519 }
520 
521 #if defined(__arm__)
522 
523 static void test_its_introspection(void) {}
524 
525 #else /* __aarch64__ */
526 
527 static void test_its_introspection(void)
528 {
529 	struct its_baser *dev_baser = &its_data.device_baser;
530 	struct its_baser *coll_baser = &its_data.coll_baser;
531 	struct its_typer *typer = &its_data.typer;
532 
533 	if (!gicv3_its_base()) {
534 		report_skip("No ITS, skip ...");
535 		return;
536 	}
537 
538 	/* IIDR */
539 	report(test_readonly_32(gicv3_its_base() + GITS_IIDR, false),
540 	       "GITS_IIDR is read-only"),
541 
542 	/* TYPER */
543 	report(test_readonly_32(gicv3_its_base() + GITS_TYPER, false),
544 	       "GITS_TYPER is read-only");
545 
546 	report(typer->phys_lpi, "ITS supports physical LPIs");
547 	report_info("vLPI support: %s", typer->virt_lpi ? "yes" : "no");
548 	report_info("ITT entry size = 0x%x", typer->ite_size);
549 	report_info("Bit Count: EventID=%d DeviceId=%d CollId=%d",
550 		    typer->eventid_bits, typer->deviceid_bits,
551 		    typer->collid_bits);
552 	report(typer->eventid_bits && typer->deviceid_bits &&
553 	       typer->collid_bits, "ID spaces");
554 	report_info("Target address format %s",
555 			typer->pta ? "Redist base address" : "PE #");
556 
557 	report(dev_baser && coll_baser, "detect device and collection BASER");
558 	report_info("device table entry_size = 0x%x", dev_baser->esz);
559 	report_info("collection table entry_size = 0x%x", coll_baser->esz);
560 }
561 
562 #endif
563 
564 int main(int argc, char **argv)
565 {
566 	if (!gic_init()) {
567 		printf("No supported gic present, skipping tests...\n");
568 		return report_summary();
569 	}
570 
571 	report_prefix_pushf("gicv%d", gic_version());
572 
573 	switch (gic_version()) {
574 	case 2:
575 		gic = &gicv2;
576 		break;
577 	case 3:
578 		gic = &gicv3;
579 		break;
580 	}
581 
582 	if (argc < 2)
583 		report_abort("no test specified");
584 
585 	if (strcmp(argv[1], "ipi") == 0) {
586 		report_prefix_push(argv[1]);
587 		nr_cpu_check(2);
588 		on_cpus(ipi_test, NULL);
589 	} else if (strcmp(argv[1], "active") == 0) {
590 		run_active_clear_test();
591 	} else if (strcmp(argv[1], "mmio") == 0) {
592 		report_prefix_push(argv[1]);
593 		gic_test_mmio();
594 		report_prefix_pop();
595 	} else if (strcmp(argv[1], "its-introspection") == 0) {
596 		report_prefix_push(argv[1]);
597 		test_its_introspection();
598 		report_prefix_pop();
599 	} else {
600 		report_abort("Unknown subtest '%s'", argv[1]);
601 	}
602 
603 	return report_summary();
604 }
605