xref: /kvm-unit-tests/arm/gic.c (revision 64260a5fb31b8b91a76f85ee156c265e5dfa0b1b)
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 setup_irq(irq_handler_fn handler)
163 {
164 	gic_enable_defaults();
165 #ifdef __arm__
166 	install_exception_handler(EXCPTN_IRQ, handler);
167 #else
168 	install_irq_handler(EL1H_IRQ, handler);
169 #endif
170 	local_irq_enable();
171 }
172 
173 #if defined(__aarch64__)
174 struct its_event {
175 	int cpu_id;
176 	int lpi_id;
177 };
178 
179 struct its_stats {
180 	struct its_event expected;
181 	struct its_event observed;
182 };
183 
184 static struct its_stats lpi_stats;
185 
186 static void lpi_handler(struct pt_regs *regs __unused)
187 {
188 	u32 irqstat = gic_read_iar();
189 	int irqnr = gic_iar_irqnr(irqstat);
190 
191 	gic_write_eoir(irqstat);
192 	assert(irqnr >= 8192);
193 	smp_rmb(); /* pairs with wmb in lpi_stats_expect */
194 	lpi_stats.observed.cpu_id = smp_processor_id();
195 	lpi_stats.observed.lpi_id = irqnr;
196 	smp_wmb(); /* pairs with rmb in check_lpi_stats */
197 }
198 
199 static void lpi_stats_expect(int exp_cpu_id, int exp_lpi_id)
200 {
201 	lpi_stats.expected.cpu_id = exp_cpu_id;
202 	lpi_stats.expected.lpi_id = exp_lpi_id;
203 	lpi_stats.observed.cpu_id = -1;
204 	lpi_stats.observed.lpi_id = -1;
205 	smp_wmb(); /* pairs with rmb in handler */
206 }
207 
208 static void check_lpi_stats(const char *msg)
209 {
210 	int i;
211 
212 	for (i = 0; i < 50; i++) {
213 		mdelay(100);
214 		smp_rmb(); /* pairs with wmb in lpi_handler */
215 		if (lpi_stats.observed.cpu_id == lpi_stats.expected.cpu_id &&
216 		    lpi_stats.observed.lpi_id == lpi_stats.expected.lpi_id) {
217 			report(true, "%s", msg);
218 			return;
219 		}
220 	}
221 
222 	if (lpi_stats.observed.cpu_id == -1 && lpi_stats.observed.lpi_id == -1) {
223 		report_info("No LPI received whereas (cpuid=%d, intid=%d) "
224 			    "was expected", lpi_stats.expected.cpu_id,
225 			    lpi_stats.expected.lpi_id);
226 	} else {
227 		report_info("Unexpected LPI (cpuid=%d, intid=%d)",
228 			    lpi_stats.observed.cpu_id,
229 			    lpi_stats.observed.lpi_id);
230 	}
231 	report(false, "%s", msg);
232 }
233 
234 static void secondary_lpi_test(void)
235 {
236 	setup_irq(lpi_handler);
237 	cpumask_set_cpu(smp_processor_id(), &ready);
238 	while (1)
239 		wfi();
240 }
241 #endif
242 
243 static void gicv2_ipi_send_self(void)
244 {
245 	writel(2 << 24 | IPI_IRQ, gicv2_dist_base() + GICD_SGIR);
246 }
247 
248 static void gicv2_ipi_send_broadcast(void)
249 {
250 	writel(1 << 24 | IPI_IRQ, gicv2_dist_base() + GICD_SGIR);
251 }
252 
253 static void gicv3_ipi_send_self(void)
254 {
255 	gic_ipi_send_single(IPI_IRQ, smp_processor_id());
256 }
257 
258 static void gicv3_ipi_send_broadcast(void)
259 {
260 	gicv3_write_sgi1r(1ULL << 40 | IPI_IRQ << 24);
261 	isb();
262 }
263 
264 static void ipi_test_self(void)
265 {
266 	cpumask_t mask;
267 
268 	report_prefix_push("self");
269 	stats_reset();
270 	cpumask_clear(&mask);
271 	cpumask_set_cpu(smp_processor_id(), &mask);
272 	gic->ipi.send_self();
273 	check_acked("IPI: self", &mask);
274 	report_prefix_pop();
275 }
276 
277 static void ipi_test_smp(void)
278 {
279 	cpumask_t mask;
280 	int i;
281 
282 	report_prefix_push("target-list");
283 	stats_reset();
284 	cpumask_copy(&mask, &cpu_present_mask);
285 	for (i = smp_processor_id() & 1; i < nr_cpus; i += 2)
286 		cpumask_clear_cpu(i, &mask);
287 	gic_ipi_send_mask(IPI_IRQ, &mask);
288 	check_acked("IPI: directed", &mask);
289 	report_prefix_pop();
290 
291 	report_prefix_push("broadcast");
292 	stats_reset();
293 	cpumask_copy(&mask, &cpu_present_mask);
294 	cpumask_clear_cpu(smp_processor_id(), &mask);
295 	gic->ipi.send_broadcast();
296 	check_acked("IPI: broadcast", &mask);
297 	report_prefix_pop();
298 }
299 
300 static void ipi_send(void)
301 {
302 	setup_irq(ipi_handler);
303 	wait_on_ready();
304 	ipi_test_self();
305 	ipi_test_smp();
306 	check_spurious();
307 	exit(report_summary());
308 }
309 
310 static void ipi_recv(void)
311 {
312 	setup_irq(ipi_handler);
313 	cpumask_set_cpu(smp_processor_id(), &ready);
314 	while (1)
315 		wfi();
316 }
317 
318 static void ipi_test(void *data __unused)
319 {
320 	if (smp_processor_id() == IPI_SENDER)
321 		ipi_send();
322 	else
323 		ipi_recv();
324 }
325 
326 static struct gic gicv2 = {
327 	.ipi = {
328 		.send_self = gicv2_ipi_send_self,
329 		.send_broadcast = gicv2_ipi_send_broadcast,
330 	},
331 };
332 
333 static struct gic gicv3 = {
334 	.ipi = {
335 		.send_self = gicv3_ipi_send_self,
336 		.send_broadcast = gicv3_ipi_send_broadcast,
337 	},
338 };
339 
340 static void ipi_clear_active_handler(struct pt_regs *regs __unused)
341 {
342 	u32 irqstat = gic_read_iar();
343 	u32 irqnr = gic_iar_irqnr(irqstat);
344 
345 	if (irqnr != GICC_INT_SPURIOUS) {
346 		void *base;
347 		u32 val = 1 << IPI_IRQ;
348 
349 		if (gic_version() == 2)
350 			base = gicv2_dist_base();
351 		else
352 			base = gicv3_sgi_base();
353 
354 		writel(val, base + GICD_ICACTIVER);
355 
356 		smp_rmb(); /* pairs with wmb in stats_reset */
357 		++acked[smp_processor_id()];
358 		check_irqnr(irqnr);
359 		smp_wmb(); /* pairs with rmb in check_acked */
360 	} else {
361 		++spurious[smp_processor_id()];
362 		smp_wmb();
363 	}
364 }
365 
366 static void run_active_clear_test(void)
367 {
368 	report_prefix_push("active");
369 	setup_irq(ipi_clear_active_handler);
370 	ipi_test_self();
371 	report_prefix_pop();
372 }
373 
374 static bool test_ro_pattern_32(void *address, u32 pattern, u32 orig)
375 {
376 	u32 reg;
377 
378 	writel(pattern, address);
379 	reg = readl(address);
380 
381 	if (reg != orig)
382 		writel(orig, address);
383 
384 	return reg == orig;
385 }
386 
387 static bool test_readonly_32(void *address, bool razwi)
388 {
389 	u32 orig, pattern;
390 
391 	orig = readl(address);
392 	if (razwi && orig)
393 		return false;
394 
395 	pattern = 0xffffffff;
396 	if (orig != pattern) {
397 		if (!test_ro_pattern_32(address, pattern, orig))
398 			return false;
399 	}
400 
401 	pattern = 0xa5a55a5a;
402 	if (orig != pattern) {
403 		if (!test_ro_pattern_32(address, pattern, orig))
404 			return false;
405 	}
406 
407 	pattern = 0;
408 	if (orig != pattern) {
409 		if (!test_ro_pattern_32(address, pattern, orig))
410 			return false;
411 	}
412 
413 	return true;
414 }
415 
416 static void test_typer_v2(uint32_t reg)
417 {
418 	int nr_gic_cpus = ((reg >> 5) & 0x7) + 1;
419 
420 	report_info("nr_cpus=%d", nr_cpus);
421 	report(nr_cpus == nr_gic_cpus, "all CPUs have interrupts");
422 }
423 
424 #define BYTE(reg32, byte) (((reg32) >> ((byte) * 8)) & 0xff)
425 #define REPLACE_BYTE(reg32, byte, new) (((reg32) & ~(0xff << ((byte) * 8))) |\
426 					((new) << ((byte) * 8)))
427 
428 /*
429  * Some registers are byte accessible, do a byte-wide read and write of known
430  * content to check for this.
431  * Apply a @mask to cater for special register properties.
432  * @pattern contains the value already in the register.
433  */
434 static void test_byte_access(void *base_addr, u32 pattern, u32 mask)
435 {
436 	u32 reg = readb(base_addr + 1);
437 	bool res;
438 
439 	res = (reg == (BYTE(pattern, 1) & (mask >> 8)));
440 	report(res, "byte reads successful");
441 	if (!res)
442 		report_info("byte 1 of 0x%08x => 0x%02x", pattern & mask, reg);
443 
444 	pattern = REPLACE_BYTE(pattern, 2, 0x1f);
445 	writeb(BYTE(pattern, 2), base_addr + 2);
446 	reg = readl(base_addr);
447 	res = (reg == (pattern & mask));
448 	report(res, "byte writes successful");
449 	if (!res)
450 		report_info("writing 0x%02x into bytes 2 => 0x%08x",
451 			    BYTE(pattern, 2), reg);
452 }
453 
454 static void test_priorities(int nr_irqs, void *priptr)
455 {
456 	u32 orig_prio, reg, pri_bits;
457 	u32 pri_mask, pattern;
458 	void *first_spi = priptr + GIC_FIRST_SPI;
459 
460 	orig_prio = readl(first_spi);
461 	report_prefix_push("IPRIORITYR");
462 
463 	/*
464 	 * Determine implemented number of priority bits by writing all 1's
465 	 * and checking the number of cleared bits in the value read back.
466 	 */
467 	writel(0xffffffff, first_spi);
468 	pri_mask = readl(first_spi);
469 
470 	reg = ~pri_mask;
471 	report((((reg >> 16) == (reg & 0xffff)) &&
472 	        ((reg & 0xff) == ((reg >> 8) & 0xff))),
473 	       "consistent priority masking");
474 	report_info("priority mask is 0x%08x", pri_mask);
475 
476 	reg = reg & 0xff;
477 	for (pri_bits = 8; reg & 1; reg >>= 1, pri_bits--)
478 		;
479 	report(pri_bits >= 4, "implements at least 4 priority bits");
480 	report_info("%d priority bits implemented", pri_bits);
481 
482 	pattern = 0;
483 	writel(pattern, first_spi);
484 	report(readl(first_spi) == pattern, "clearing priorities");
485 
486 	/* setting all priorities to their max valus was tested above */
487 
488 	report(test_readonly_32(priptr + nr_irqs, true),
489 	       "accesses beyond limit RAZ/WI");
490 
491 	writel(pattern, priptr + nr_irqs - 4);
492 	report(readl(priptr + nr_irqs - 4) == (pattern & pri_mask),
493 	       "accessing last SPIs");
494 
495 	pattern = 0xff7fbf3f;
496 	writel(pattern, first_spi);
497 	report(readl(first_spi) == (pattern & pri_mask),
498 	       "priorities are preserved");
499 
500 	/* The PRIORITY registers are byte accessible. */
501 	test_byte_access(first_spi, pattern, pri_mask);
502 
503 	report_prefix_pop();
504 	writel(orig_prio, first_spi);
505 }
506 
507 /* GICD_ITARGETSR is only used by GICv2. */
508 static void test_targets(int nr_irqs)
509 {
510 	void *targetsptr = gicv2_dist_base() + GICD_ITARGETSR;
511 	u32 orig_targets;
512 	u32 cpu_mask;
513 	u32 pattern, reg;
514 
515 	orig_targets = readl(targetsptr + GIC_FIRST_SPI);
516 	report_prefix_push("ITARGETSR");
517 
518 	cpu_mask = (1 << nr_cpus) - 1;
519 	cpu_mask |= cpu_mask << 8;
520 	cpu_mask |= cpu_mask << 16;
521 
522 	/* Check that bits for non implemented CPUs are RAZ/WI. */
523 	if (nr_cpus < 8) {
524 		writel(0xffffffff, targetsptr + GIC_FIRST_SPI);
525 		report(!(readl(targetsptr + GIC_FIRST_SPI) & ~cpu_mask),
526 		       "bits for non-existent CPUs masked");
527 		report_info("%d non-existent CPUs", 8 - nr_cpus);
528 	} else {
529 		report_skip("CPU masking (all CPUs implemented)");
530 	}
531 
532 	report(test_readonly_32(targetsptr + nr_irqs, true),
533 	       "accesses beyond limit RAZ/WI");
534 
535 	pattern = 0x0103020f;
536 	writel(pattern, targetsptr + GIC_FIRST_SPI);
537 	reg = readl(targetsptr + GIC_FIRST_SPI);
538 	report(reg == (pattern & cpu_mask), "register content preserved");
539 	if (reg != (pattern & cpu_mask))
540 		report_info("writing %08x reads back as %08x",
541 			    pattern & cpu_mask, reg);
542 
543 	/* The TARGETS registers are byte accessible. */
544 	test_byte_access(targetsptr + GIC_FIRST_SPI, pattern, cpu_mask);
545 
546 	writel(orig_targets, targetsptr + GIC_FIRST_SPI);
547 
548 	report_prefix_pop();
549 }
550 
551 static void gic_test_mmio(void)
552 {
553 	u32 reg;
554 	int nr_irqs;
555 	void *gic_dist_base, *idreg;
556 
557 	switch(gic_version()) {
558 	case 0x2:
559 		gic_dist_base = gicv2_dist_base();
560 		idreg = gic_dist_base + GICD_ICPIDR2;
561 		break;
562 	case 0x3:
563 		report_abort("GICv3 MMIO tests NYI");
564 	default:
565 		report_abort("GIC version %d not supported", gic_version());
566 	}
567 
568 	reg = readl(gic_dist_base + GICD_TYPER);
569 	nr_irqs = GICD_TYPER_IRQS(reg);
570 	report_info("number of implemented SPIs: %d", nr_irqs - GIC_FIRST_SPI);
571 
572 	test_typer_v2(reg);
573 
574 	report_info("IIDR: 0x%08x", readl(gic_dist_base + GICD_IIDR));
575 
576 	report(test_readonly_32(gic_dist_base + GICD_TYPER, false),
577                "GICD_TYPER is read-only");
578 	report(test_readonly_32(gic_dist_base + GICD_IIDR, false),
579                "GICD_IIDR is read-only");
580 
581 	reg = readl(idreg);
582 	report(test_readonly_32(idreg, false), "ICPIDR2 is read-only");
583 	report_info("value of ICPIDR2: 0x%08x", reg);
584 
585 	test_priorities(nr_irqs, gic_dist_base + GICD_IPRIORITYR);
586 
587 	if (gic_version() == 2)
588 		test_targets(nr_irqs);
589 }
590 
591 #if defined(__arm__)
592 
593 static void test_its_introspection(void) {}
594 static void test_its_trigger(void) {}
595 static void test_its_migration(void) {}
596 
597 #else /* __aarch64__ */
598 
599 static void test_its_introspection(void)
600 {
601 	struct its_baser *dev_baser = &its_data.device_baser;
602 	struct its_baser *coll_baser = &its_data.coll_baser;
603 	struct its_typer *typer = &its_data.typer;
604 
605 	if (!gicv3_its_base()) {
606 		report_skip("No ITS, skip ...");
607 		return;
608 	}
609 
610 	/* IIDR */
611 	report(test_readonly_32(gicv3_its_base() + GITS_IIDR, false),
612 	       "GITS_IIDR is read-only"),
613 
614 	/* TYPER */
615 	report(test_readonly_32(gicv3_its_base() + GITS_TYPER, false),
616 	       "GITS_TYPER is read-only");
617 
618 	report(typer->phys_lpi, "ITS supports physical LPIs");
619 	report_info("vLPI support: %s", typer->virt_lpi ? "yes" : "no");
620 	report_info("ITT entry size = 0x%x", typer->ite_size);
621 	report_info("Bit Count: EventID=%d DeviceId=%d CollId=%d",
622 		    typer->eventid_bits, typer->deviceid_bits,
623 		    typer->collid_bits);
624 	report(typer->eventid_bits && typer->deviceid_bits &&
625 	       typer->collid_bits, "ID spaces");
626 	report_info("Target address format %s",
627 			typer->pta ? "Redist base address" : "PE #");
628 
629 	report(dev_baser && coll_baser, "detect device and collection BASER");
630 	report_info("device table entry_size = 0x%x", dev_baser->esz);
631 	report_info("collection table entry_size = 0x%x", coll_baser->esz);
632 }
633 
634 static int its_prerequisites(int nb_cpus)
635 {
636 	int cpu;
637 
638 	if (!gicv3_its_base()) {
639 		report_skip("No ITS, skip ...");
640 		return -1;
641 	}
642 
643 	if (nr_cpus < nb_cpus) {
644 		report_skip("Test requires at least %d vcpus", nb_cpus);
645 		return -1;
646 	}
647 
648 	stats_reset();
649 
650 	setup_irq(lpi_handler);
651 
652 	for_each_present_cpu(cpu) {
653 		if (cpu == 0)
654 			continue;
655 		smp_boot_secondary(cpu, secondary_lpi_test);
656 	}
657 	wait_on_ready();
658 
659 	its_enable_defaults();
660 
661 	return 0;
662 }
663 
664 /*
665  * Setup the configuration for those mappings:
666  * dev_id=2 event=20 -> vcpu 3, intid=8195
667  * dev_id=7 event=255 -> vcpu 2, intid=8196
668  * LPIs ready to hit
669  */
670 static int its_setup1(void)
671 {
672 	struct its_collection *col3, *col2;
673 	struct its_device *dev2, *dev7;
674 
675 	if (its_prerequisites(4))
676 		return -1;
677 
678 	dev2 = its_create_device(2 /* dev id */, 8 /* nb_ites */);
679 	dev7 = its_create_device(7 /* dev id */, 8 /* nb_ites */);
680 
681 	col3 = its_create_collection(3 /* col id */, 3/* target PE */);
682 	col2 = its_create_collection(2 /* col id */, 2/* target PE */);
683 
684 	gicv3_lpi_set_config(8195, LPI_PROP_DEFAULT);
685 	gicv3_lpi_set_config(8196, LPI_PROP_DEFAULT);
686 
687 	/*
688 	 * dev=2, eventid=20  -> lpi= 8195, col=3
689 	 * dev=7, eventid=255 -> lpi= 8196, col=2
690 	 */
691 	its_send_mapd(dev2, true);
692 	its_send_mapd(dev7, true);
693 
694 	its_send_mapc(col3, true);
695 	its_send_mapc(col2, true);
696 
697 	its_send_invall(col2);
698 	its_send_invall(col3);
699 
700 	its_send_mapti(dev2, 8195 /* lpi id */, 20 /* event id */, col3);
701 	its_send_mapti(dev7, 8196 /* lpi id */, 255 /* event id */, col2);
702 	return 0;
703 }
704 
705 static void test_its_trigger(void)
706 {
707 	struct its_collection *col3;
708 	struct its_device *dev2, *dev7;
709 
710 	if (its_setup1())
711 		return;
712 
713 	col3 = its_get_collection(3);
714 	dev2 = its_get_device(2);
715 	dev7 = its_get_device(7);
716 
717 	report_prefix_push("int");
718 
719 	lpi_stats_expect(3, 8195);
720 	its_send_int(dev2, 20);
721 	check_lpi_stats("dev=2, eventid=20  -> lpi= 8195, col=3");
722 
723 	lpi_stats_expect(2, 8196);
724 	its_send_int(dev7, 255);
725 	check_lpi_stats("dev=7, eventid=255 -> lpi= 8196, col=2");
726 
727 	report_prefix_pop();
728 
729 	report_prefix_push("inv/invall");
730 
731 	/*
732 	 * disable 8195, check dev2/eventid=20 does not trigger the
733 	 * corresponding LPI
734 	 */
735 	gicv3_lpi_set_config(8195, LPI_PROP_DEFAULT & ~LPI_PROP_ENABLED);
736 	its_send_inv(dev2, 20);
737 
738 	lpi_stats_expect(-1, -1);
739 	its_send_int(dev2, 20);
740 	check_lpi_stats("dev2/eventid=20 does not trigger any LPI");
741 
742 	/*
743 	 * re-enable the LPI but willingly do not call invall
744 	 * so the change in config is not taken into account.
745 	 * The LPI should not hit
746 	 */
747 	gicv3_lpi_set_config(8195, LPI_PROP_DEFAULT);
748 	lpi_stats_expect(-1, -1);
749 	its_send_int(dev2, 20);
750 	check_lpi_stats("dev2/eventid=20 still does not trigger any LPI");
751 
752 	/* Now call the invall and check the LPI hits */
753 	its_send_invall(col3);
754 	lpi_stats_expect(3, 8195);
755 	its_send_int(dev2, 20);
756 	check_lpi_stats("dev2/eventid=20 now triggers an LPI");
757 
758 	report_prefix_pop();
759 
760 	report_prefix_push("mapd valid=false");
761 	/*
762 	 * Unmap device 2 and check the eventid 20 formerly
763 	 * attached to it does not hit anymore
764 	 */
765 
766 	its_send_mapd(dev2, false);
767 	lpi_stats_expect(-1, -1);
768 	its_send_int(dev2, 20);
769 	check_lpi_stats("no LPI after device unmap");
770 	report_prefix_pop();
771 }
772 
773 static void test_its_migration(void)
774 {
775 	struct its_device *dev2, *dev7;
776 	bool test_skipped = false;
777 
778 	if (its_setup1()) {
779 		test_skipped = true;
780 		goto do_migrate;
781 	}
782 
783 	dev2 = its_get_device(2);
784 	dev7 = its_get_device(7);
785 
786 do_migrate:
787 	puts("Now migrate the VM, then press a key to continue...\n");
788 	(void)getchar();
789 	report_info("Migration complete");
790 	if (test_skipped)
791 		return;
792 
793 	lpi_stats_expect(3, 8195);
794 	its_send_int(dev2, 20);
795 	check_lpi_stats("dev2/eventid=20 triggers LPI 8195 on PE #3 after migration");
796 
797 	lpi_stats_expect(2, 8196);
798 	its_send_int(dev7, 255);
799 	check_lpi_stats("dev7/eventid=255 triggers LPI 8196 on PE #2 after migration");
800 }
801 #endif
802 
803 int main(int argc, char **argv)
804 {
805 	if (!gic_init()) {
806 		printf("No supported gic present, skipping tests...\n");
807 		return report_summary();
808 	}
809 
810 	report_prefix_pushf("gicv%d", gic_version());
811 
812 	switch (gic_version()) {
813 	case 2:
814 		gic = &gicv2;
815 		break;
816 	case 3:
817 		gic = &gicv3;
818 		break;
819 	}
820 
821 	if (argc < 2)
822 		report_abort("no test specified");
823 
824 	if (strcmp(argv[1], "ipi") == 0) {
825 		report_prefix_push(argv[1]);
826 		nr_cpu_check(2);
827 		on_cpus(ipi_test, NULL);
828 	} else if (strcmp(argv[1], "active") == 0) {
829 		run_active_clear_test();
830 	} else if (strcmp(argv[1], "mmio") == 0) {
831 		report_prefix_push(argv[1]);
832 		gic_test_mmio();
833 		report_prefix_pop();
834 	} else if (!strcmp(argv[1], "its-trigger")) {
835 		report_prefix_push(argv[1]);
836 		test_its_trigger();
837 		report_prefix_pop();
838 	} else if (!strcmp(argv[1], "its-migration")) {
839 		report_prefix_push(argv[1]);
840 		test_its_migration();
841 		report_prefix_pop();
842 	} else if (strcmp(argv[1], "its-introspection") == 0) {
843 		report_prefix_push(argv[1]);
844 		test_its_introspection();
845 		report_prefix_pop();
846 	} else {
847 		report_abort("Unknown subtest '%s'", argv[1]);
848 	}
849 
850 	return report_summary();
851 }
852