/*
 * GIC tests
 *
 * GICv2
 *   + test sending/receiving IPIs
 *   + MMIO access tests
 * GICv3
 *   + test sending/receiving IPIs
 *
 * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.
 */
#include <libcflat.h>
#include <errata.h>
#include <asm/setup.h>
#include <asm/processor.h>
#include <asm/delay.h>
#include <asm/gic.h>
#include <asm/gic-v3-its.h>
#include <asm/smp.h>
#include <asm/barrier.h>
#include <asm/io.h>

#define IPI_SENDER	1
#define IPI_IRQ		1

struct gic {
	struct {
		void (*send_self)(void);
		void (*send_broadcast)(void);
	} ipi;
};

static struct gic *gic;
static int acked[NR_CPUS], spurious[NR_CPUS];
static int bad_sender[NR_CPUS], bad_irq[NR_CPUS];
static cpumask_t ready;

static void nr_cpu_check(int nr)
{
	if (nr_cpus < nr)
		report_abort("At least %d cpus required", nr);
}

static void wait_on_ready(void)
{
	cpumask_set_cpu(smp_processor_id(), &ready);
	while (!cpumask_full(&ready))
		cpu_relax();
}

static void stats_reset(void)
{
	int i;

	for (i = 0; i < nr_cpus; ++i) {
		acked[i] = 0;
		bad_sender[i] = -1;
		bad_irq[i] = -1;
	}
	smp_wmb();
}

static void check_acked(const char *testname, cpumask_t *mask)
{
	int missing = 0, extra = 0, unexpected = 0;
	int nr_pass, cpu, i;
	bool bad = false;

	/* Wait up to 5s for all interrupts to be delivered */
	for (i = 0; i < 50; ++i) {
		mdelay(100);
		nr_pass = 0;
		for_each_present_cpu(cpu) {
			smp_rmb();
			nr_pass += cpumask_test_cpu(cpu, mask) ?
				acked[cpu] == 1 : acked[cpu] == 0;

			if (bad_sender[cpu] != -1) {
				printf("cpu%d received IPI from wrong sender %d\n",
					cpu, bad_sender[cpu]);
				bad = true;
			}

			if (bad_irq[cpu] != -1) {
				printf("cpu%d received wrong irq %d\n",
					cpu, bad_irq[cpu]);
				bad = true;
			}
		}
		if (nr_pass == nr_cpus) {
			report(!bad, "%s", testname);
			if (i)
				report_info("took more than %d ms", i * 100);
			return;
		}
	}

	for_each_present_cpu(cpu) {
		if (cpumask_test_cpu(cpu, mask)) {
			if (!acked[cpu])
				++missing;
			else if (acked[cpu] > 1)
				++extra;
		} else {
			if (acked[cpu])
				++unexpected;
		}
	}

	report(false, "%s", testname);
	report_info("Timed-out (5s). ACKS: missing=%d extra=%d unexpected=%d",
		    missing, extra, unexpected);
}

static void check_spurious(void)
{
	int cpu;

	smp_rmb();
	for_each_present_cpu(cpu) {
		if (spurious[cpu])
			report_info("WARN: cpu%d got %d spurious interrupts",
				cpu, spurious[cpu]);
	}
}

static void check_ipi_sender(u32 irqstat)
{
	if (gic_version() == 2) {
		int src = (irqstat >> 10) & 7;

		if (src != IPI_SENDER)
			bad_sender[smp_processor_id()] = src;
	}
}

static void check_irqnr(u32 irqnr)
{
	if (irqnr != IPI_IRQ)
		bad_irq[smp_processor_id()] = irqnr;
}

static void ipi_handler(struct pt_regs *regs __unused)
{
	u32 irqstat = gic_read_iar();
	u32 irqnr = gic_iar_irqnr(irqstat);

	if (irqnr != GICC_INT_SPURIOUS) {
		gic_write_eoir(irqstat);
		smp_rmb(); /* pairs with wmb in stats_reset */
		++acked[smp_processor_id()];
		check_ipi_sender(irqstat);
		check_irqnr(irqnr);
		smp_wmb(); /* pairs with rmb in check_acked */
	} else {
		++spurious[smp_processor_id()];
		smp_wmb();
	}
}

static void setup_irq(irq_handler_fn handler)
{
	gic_enable_defaults();
#ifdef __arm__
	install_exception_handler(EXCPTN_IRQ, handler);
#else
	install_irq_handler(EL1H_IRQ, handler);
#endif
	local_irq_enable();
}

#if defined(__aarch64__)
struct its_event {
	int cpu_id;
	int lpi_id;
};

struct its_stats {
	struct its_event expected;
	struct its_event observed;
};

static struct its_stats lpi_stats;

static void lpi_handler(struct pt_regs *regs __unused)
{
	u32 irqstat = gic_read_iar();
	int irqnr = gic_iar_irqnr(irqstat);

	gic_write_eoir(irqstat);
	assert(irqnr >= 8192);
	smp_rmb(); /* pairs with wmb in lpi_stats_expect */
	lpi_stats.observed.cpu_id = smp_processor_id();
	lpi_stats.observed.lpi_id = irqnr;
	acked[lpi_stats.observed.cpu_id]++;
	smp_wmb(); /* pairs with rmb in check_lpi_stats */
}

static void lpi_stats_expect(int exp_cpu_id, int exp_lpi_id)
{
	lpi_stats.expected.cpu_id = exp_cpu_id;
	lpi_stats.expected.lpi_id = exp_lpi_id;
	lpi_stats.observed.cpu_id = -1;
	lpi_stats.observed.lpi_id = -1;
	smp_wmb(); /* pairs with rmb in handler */
}

static void check_lpi_stats(const char *msg)
{
	int i;

	for (i = 0; i < 50; i++) {
		mdelay(100);
		smp_rmb(); /* pairs with wmb in lpi_handler */
		if (lpi_stats.observed.cpu_id == lpi_stats.expected.cpu_id &&
		    lpi_stats.observed.lpi_id == lpi_stats.expected.lpi_id) {
			report(true, "%s", msg);
			return;
		}
	}

	if (lpi_stats.observed.cpu_id == -1 && lpi_stats.observed.lpi_id == -1) {
		report_info("No LPI received whereas (cpuid=%d, intid=%d) "
			    "was expected", lpi_stats.expected.cpu_id,
			    lpi_stats.expected.lpi_id);
	} else {
		report_info("Unexpected LPI (cpuid=%d, intid=%d)",
			    lpi_stats.observed.cpu_id,
			    lpi_stats.observed.lpi_id);
	}
	report(false, "%s", msg);
}

static void secondary_lpi_test(void)
{
	setup_irq(lpi_handler);
	cpumask_set_cpu(smp_processor_id(), &ready);
	while (1)
		wfi();
}

static void check_lpi_hits(int *expected, const char *msg)
{
	bool pass = true;
	int i;

	for_each_present_cpu(i) {
		if (acked[i] != expected[i]) {
			report_info("expected %d LPIs on PE #%d, %d observed",
				    expected[i], i, acked[i]);
			pass = false;
			break;
		}
	}
	report(pass, "%s", msg);
}
#endif

static void gicv2_ipi_send_self(void)
{
	writel(2 << 24 | IPI_IRQ, gicv2_dist_base() + GICD_SGIR);
}

static void gicv2_ipi_send_broadcast(void)
{
	writel(1 << 24 | IPI_IRQ, gicv2_dist_base() + GICD_SGIR);
}

static void gicv3_ipi_send_self(void)
{
	gic_ipi_send_single(IPI_IRQ, smp_processor_id());
}

static void gicv3_ipi_send_broadcast(void)
{
	gicv3_write_sgi1r(1ULL << 40 | IPI_IRQ << 24);
	isb();
}

static void ipi_test_self(void)
{
	cpumask_t mask;

	report_prefix_push("self");
	stats_reset();
	cpumask_clear(&mask);
	cpumask_set_cpu(smp_processor_id(), &mask);
	gic->ipi.send_self();
	check_acked("IPI: self", &mask);
	report_prefix_pop();
}

static void ipi_test_smp(void)
{
	cpumask_t mask;
	int i;

	report_prefix_push("target-list");
	stats_reset();
	cpumask_copy(&mask, &cpu_present_mask);
	for (i = smp_processor_id() & 1; i < nr_cpus; i += 2)
		cpumask_clear_cpu(i, &mask);
	gic_ipi_send_mask(IPI_IRQ, &mask);
	check_acked("IPI: directed", &mask);
	report_prefix_pop();

	report_prefix_push("broadcast");
	stats_reset();
	cpumask_copy(&mask, &cpu_present_mask);
	cpumask_clear_cpu(smp_processor_id(), &mask);
	gic->ipi.send_broadcast();
	check_acked("IPI: broadcast", &mask);
	report_prefix_pop();
}

static void ipi_send(void)
{
	setup_irq(ipi_handler);
	wait_on_ready();
	ipi_test_self();
	ipi_test_smp();
	check_spurious();
	exit(report_summary());
}

static void ipi_recv(void)
{
	setup_irq(ipi_handler);
	cpumask_set_cpu(smp_processor_id(), &ready);
	while (1)
		wfi();
}

static void ipi_test(void *data __unused)
{
	if (smp_processor_id() == IPI_SENDER)
		ipi_send();
	else
		ipi_recv();
}

static struct gic gicv2 = {
	.ipi = {
		.send_self = gicv2_ipi_send_self,
		.send_broadcast = gicv2_ipi_send_broadcast,
	},
};

static struct gic gicv3 = {
	.ipi = {
		.send_self = gicv3_ipi_send_self,
		.send_broadcast = gicv3_ipi_send_broadcast,
	},
};

static void ipi_clear_active_handler(struct pt_regs *regs __unused)
{
	u32 irqstat = gic_read_iar();
	u32 irqnr = gic_iar_irqnr(irqstat);

	if (irqnr != GICC_INT_SPURIOUS) {
		void *base;
		u32 val = 1 << IPI_IRQ;

		if (gic_version() == 2)
			base = gicv2_dist_base();
		else
			base = gicv3_sgi_base();

		writel(val, base + GICD_ICACTIVER);

		smp_rmb(); /* pairs with wmb in stats_reset */
		++acked[smp_processor_id()];
		check_irqnr(irqnr);
		smp_wmb(); /* pairs with rmb in check_acked */
	} else {
		++spurious[smp_processor_id()];
		smp_wmb();
	}
}

static void run_active_clear_test(void)
{
	report_prefix_push("active");
	setup_irq(ipi_clear_active_handler);
	ipi_test_self();
	report_prefix_pop();
}

static bool test_ro_pattern_32(void *address, u32 pattern, u32 orig)
{
	u32 reg;

	writel(pattern, address);
	reg = readl(address);

	if (reg != orig)
		writel(orig, address);

	return reg == orig;
}

static bool test_readonly_32(void *address, bool razwi)
{
	u32 orig, pattern;

	orig = readl(address);
	if (razwi && orig)
		return false;

	pattern = 0xffffffff;
	if (orig != pattern) {
		if (!test_ro_pattern_32(address, pattern, orig))
			return false;
	}

	pattern = 0xa5a55a5a;
	if (orig != pattern) {
		if (!test_ro_pattern_32(address, pattern, orig))
			return false;
	}

	pattern = 0;
	if (orig != pattern) {
		if (!test_ro_pattern_32(address, pattern, orig))
			return false;
	}

	return true;
}

static void test_typer_v2(uint32_t reg)
{
	int nr_gic_cpus = ((reg >> 5) & 0x7) + 1;

	report_info("nr_cpus=%d", nr_cpus);
	report(nr_cpus == nr_gic_cpus, "all CPUs have interrupts");
}

#define BYTE(reg32, byte) (((reg32) >> ((byte) * 8)) & 0xff)
#define REPLACE_BYTE(reg32, byte, new) (((reg32) & ~(0xff << ((byte) * 8))) |\
					((new) << ((byte) * 8)))

/*
 * Some registers are byte accessible, do a byte-wide read and write of known
 * content to check for this.
 * Apply a @mask to cater for special register properties.
 * @pattern contains the value already in the register.
 */
static void test_byte_access(void *base_addr, u32 pattern, u32 mask)
{
	u32 reg = readb(base_addr + 1);
	bool res;

	res = (reg == (BYTE(pattern, 1) & (mask >> 8)));
	report(res, "byte reads successful");
	if (!res)
		report_info("byte 1 of 0x%08"PRIx32" => 0x%02"PRIx32, pattern & mask, reg);

	pattern = REPLACE_BYTE(pattern, 2, 0x1f);
	writeb(BYTE(pattern, 2), base_addr + 2);
	reg = readl(base_addr);
	res = (reg == (pattern & mask));
	report(res, "byte writes successful");
	if (!res)
		report_info("writing 0x%02"PRIx32" into bytes 2 => 0x%08"PRIx32,
			    BYTE(pattern, 2), reg);
}

static void test_priorities(int nr_irqs, void *priptr)
{
	u32 orig_prio, reg, pri_bits;
	u32 pri_mask, pattern;
	void *first_spi = priptr + GIC_FIRST_SPI;

	orig_prio = readl(first_spi);
	report_prefix_push("IPRIORITYR");

	/*
	 * Determine implemented number of priority bits by writing all 1's
	 * and checking the number of cleared bits in the value read back.
	 */
	writel(0xffffffff, first_spi);
	pri_mask = readl(first_spi);

	reg = ~pri_mask;
	report((((reg >> 16) == (reg & 0xffff)) &&
	        ((reg & 0xff) == ((reg >> 8) & 0xff))),
	       "consistent priority masking");
	report_info("priority mask is 0x%08"PRIx32, pri_mask);

	reg = reg & 0xff;
	for (pri_bits = 8; reg & 1; reg >>= 1, pri_bits--)
		;
	report(pri_bits >= 4, "implements at least 4 priority bits");
	report_info("%"PRIu32" priority bits implemented", pri_bits);

	pattern = 0;
	writel(pattern, first_spi);
	report(readl(first_spi) == pattern, "clearing priorities");

	/* setting all priorities to their max valus was tested above */

	report(test_readonly_32(priptr + nr_irqs, true),
	       "accesses beyond limit RAZ/WI");

	writel(pattern, priptr + nr_irqs - 4);
	report(readl(priptr + nr_irqs - 4) == (pattern & pri_mask),
	       "accessing last SPIs");

	pattern = 0xff7fbf3f;
	writel(pattern, first_spi);
	report(readl(first_spi) == (pattern & pri_mask),
	       "priorities are preserved");

	/* The PRIORITY registers are byte accessible. */
	test_byte_access(first_spi, pattern, pri_mask);

	report_prefix_pop();
	writel(orig_prio, first_spi);
}

/* GICD_ITARGETSR is only used by GICv2. */
static void test_targets(int nr_irqs)
{
	void *targetsptr = gicv2_dist_base() + GICD_ITARGETSR;
	u32 orig_targets;
	u32 cpu_mask;
	u32 pattern, reg;

	orig_targets = readl(targetsptr + GIC_FIRST_SPI);
	report_prefix_push("ITARGETSR");

	cpu_mask = (1 << nr_cpus) - 1;
	cpu_mask |= cpu_mask << 8;
	cpu_mask |= cpu_mask << 16;

	/* Check that bits for non implemented CPUs are RAZ/WI. */
	if (nr_cpus < 8) {
		writel(0xffffffff, targetsptr + GIC_FIRST_SPI);
		report(!(readl(targetsptr + GIC_FIRST_SPI) & ~cpu_mask),
		       "bits for non-existent CPUs masked");
		report_info("%d non-existent CPUs", 8 - nr_cpus);
	} else {
		report_skip("CPU masking (all CPUs implemented)");
	}

	report(test_readonly_32(targetsptr + nr_irqs, true),
	       "accesses beyond limit RAZ/WI");

	pattern = 0x0103020f;
	writel(pattern, targetsptr + GIC_FIRST_SPI);
	reg = readl(targetsptr + GIC_FIRST_SPI);
	report(reg == (pattern & cpu_mask), "register content preserved");
	if (reg != (pattern & cpu_mask))
		report_info("writing %08"PRIx32" reads back as %08"PRIx32,
			    pattern & cpu_mask, reg);

	/* The TARGETS registers are byte accessible. */
	test_byte_access(targetsptr + GIC_FIRST_SPI, pattern, cpu_mask);

	writel(orig_targets, targetsptr + GIC_FIRST_SPI);

	report_prefix_pop();
}

static void gic_test_mmio(void)
{
	u32 reg;
	int nr_irqs;
	void *gic_dist_base, *idreg;

	switch(gic_version()) {
	case 0x2:
		gic_dist_base = gicv2_dist_base();
		idreg = gic_dist_base + GICD_ICPIDR2;
		break;
	case 0x3:
		report_abort("GICv3 MMIO tests NYI");
	default:
		report_abort("GIC version %d not supported", gic_version());
	}

	reg = readl(gic_dist_base + GICD_TYPER);
	nr_irqs = GICD_TYPER_IRQS(reg);
	report_info("number of implemented SPIs: %d", nr_irqs - GIC_FIRST_SPI);

	test_typer_v2(reg);

	report_info("IIDR: 0x%08"PRIx32, readl(gic_dist_base + GICD_IIDR));

	report(test_readonly_32(gic_dist_base + GICD_TYPER, false),
               "GICD_TYPER is read-only");
	report(test_readonly_32(gic_dist_base + GICD_IIDR, false),
               "GICD_IIDR is read-only");

	reg = readl(idreg);
	report(test_readonly_32(idreg, false), "ICPIDR2 is read-only");
	report_info("value of ICPIDR2: 0x%08"PRIx32, reg);

	test_priorities(nr_irqs, gic_dist_base + GICD_IPRIORITYR);

	if (gic_version() == 2)
		test_targets(nr_irqs);
}

#if defined(__arm__)

static void test_its_introspection(void) {}
static void test_its_trigger(void) {}
static void test_its_migration(void) {}
static void test_its_pending_migration(void) {}
static void test_migrate_unmapped_collection(void) {}

#else /* __aarch64__ */

static void test_its_introspection(void)
{
	struct its_baser *dev_baser = &its_data.device_baser;
	struct its_baser *coll_baser = &its_data.coll_baser;
	struct its_typer *typer = &its_data.typer;

	if (!gicv3_its_base()) {
		report_skip("No ITS, skip ...");
		return;
	}

	/* IIDR */
	report(test_readonly_32(gicv3_its_base() + GITS_IIDR, false),
	       "GITS_IIDR is read-only"),

	/* TYPER */
	report(test_readonly_32(gicv3_its_base() + GITS_TYPER, false),
	       "GITS_TYPER is read-only");

	report(typer->phys_lpi, "ITS supports physical LPIs");
	report_info("vLPI support: %s", typer->virt_lpi ? "yes" : "no");
	report_info("ITT entry size = 0x%x", typer->ite_size);
	report_info("Bit Count: EventID=%d DeviceId=%d CollId=%d",
		    typer->eventid_bits, typer->deviceid_bits,
		    typer->collid_bits);
	report(typer->eventid_bits && typer->deviceid_bits &&
	       typer->collid_bits, "ID spaces");
	report_info("Target address format %s",
			typer->pta ? "Redist base address" : "PE #");

	report(dev_baser && coll_baser, "detect device and collection BASER");
	report_info("device table entry_size = 0x%x", dev_baser->esz);
	report_info("collection table entry_size = 0x%x", coll_baser->esz);
}

static int its_prerequisites(int nb_cpus)
{
	int cpu;

	if (!gicv3_its_base()) {
		report_skip("No ITS, skip ...");
		return -1;
	}

	if (nr_cpus < nb_cpus) {
		report_skip("Test requires at least %d vcpus", nb_cpus);
		return -1;
	}

	stats_reset();

	setup_irq(lpi_handler);

	for_each_present_cpu(cpu) {
		if (cpu == 0)
			continue;
		smp_boot_secondary(cpu, secondary_lpi_test);
	}
	wait_on_ready();

	its_enable_defaults();

	return 0;
}

/*
 * Setup the configuration for those mappings:
 * dev_id=2 event=20 -> vcpu 3, intid=8195
 * dev_id=7 event=255 -> vcpu 2, intid=8196
 * LPIs ready to hit
 */
static int its_setup1(void)
{
	struct its_collection *col3, *col2;
	struct its_device *dev2, *dev7;

	if (its_prerequisites(4))
		return -1;

	dev2 = its_create_device(2 /* dev id */, 8 /* nb_ites */);
	dev7 = its_create_device(7 /* dev id */, 8 /* nb_ites */);

	col3 = its_create_collection(3 /* col id */, 3/* target PE */);
	col2 = its_create_collection(2 /* col id */, 2/* target PE */);

	gicv3_lpi_set_config(8195, LPI_PROP_DEFAULT);
	gicv3_lpi_set_config(8196, LPI_PROP_DEFAULT);

	/*
	 * dev=2, eventid=20  -> lpi= 8195, col=3
	 * dev=7, eventid=255 -> lpi= 8196, col=2
	 */
	its_send_mapd(dev2, true);
	its_send_mapd(dev7, true);

	its_send_mapc(col3, true);
	its_send_mapc(col2, true);

	its_send_invall(col2);
	its_send_invall(col3);

	its_send_mapti(dev2, 8195 /* lpi id */, 20 /* event id */, col3);
	its_send_mapti(dev7, 8196 /* lpi id */, 255 /* event id */, col2);
	return 0;
}

static void test_its_trigger(void)
{
	struct its_collection *col3;
	struct its_device *dev2, *dev7;

	if (its_setup1())
		return;

	col3 = its_get_collection(3);
	dev2 = its_get_device(2);
	dev7 = its_get_device(7);

	report_prefix_push("int");

	lpi_stats_expect(3, 8195);
	its_send_int(dev2, 20);
	check_lpi_stats("dev=2, eventid=20  -> lpi= 8195, col=3");

	lpi_stats_expect(2, 8196);
	its_send_int(dev7, 255);
	check_lpi_stats("dev=7, eventid=255 -> lpi= 8196, col=2");

	report_prefix_pop();

	report_prefix_push("inv/invall");

	/*
	 * disable 8195, check dev2/eventid=20 does not trigger the
	 * corresponding LPI
	 */
	gicv3_lpi_set_config(8195, LPI_PROP_DEFAULT & ~LPI_PROP_ENABLED);
	its_send_inv(dev2, 20);

	lpi_stats_expect(-1, -1);
	its_send_int(dev2, 20);
	check_lpi_stats("dev2/eventid=20 does not trigger any LPI");

	/*
	 * re-enable the LPI but willingly do not call invall
	 * so the change in config is not taken into account.
	 * The LPI should not hit
	 */
	gicv3_lpi_set_config(8195, LPI_PROP_DEFAULT);
	lpi_stats_expect(-1, -1);
	its_send_int(dev2, 20);
	check_lpi_stats("dev2/eventid=20 still does not trigger any LPI");

	/* Now call the invall and check the LPI hits */
	its_send_invall(col3);
	lpi_stats_expect(3, 8195);
	its_send_int(dev2, 20);
	check_lpi_stats("dev2/eventid=20 now triggers an LPI");

	report_prefix_pop();

	report_prefix_push("mapd valid=false");
	/*
	 * Unmap device 2 and check the eventid 20 formerly
	 * attached to it does not hit anymore
	 */

	its_send_mapd(dev2, false);
	lpi_stats_expect(-1, -1);
	its_send_int(dev2, 20);
	check_lpi_stats("no LPI after device unmap");
	report_prefix_pop();
}

static void test_its_migration(void)
{
	struct its_device *dev2, *dev7;
	bool test_skipped = false;

	if (its_setup1()) {
		test_skipped = true;
		goto do_migrate;
	}

	dev2 = its_get_device(2);
	dev7 = its_get_device(7);

do_migrate:
	puts("Now migrate the VM, then press a key to continue...\n");
	(void)getchar();
	report_info("Migration complete");
	if (test_skipped)
		return;

	lpi_stats_expect(3, 8195);
	its_send_int(dev2, 20);
	check_lpi_stats("dev2/eventid=20 triggers LPI 8195 on PE #3 after migration");

	lpi_stats_expect(2, 8196);
	its_send_int(dev7, 255);
	check_lpi_stats("dev7/eventid=255 triggers LPI 8196 on PE #2 after migration");
}

#define ERRATA_UNMAPPED_COLLECTIONS "ERRATA_8c58be34494b"

static void test_migrate_unmapped_collection(void)
{
	struct its_collection *col = NULL;
	struct its_device *dev2 = NULL, *dev7 = NULL;
	bool test_skipped = false;
	int pe0 = 0;
	u8 config;

	if (its_setup1()) {
		test_skipped = true;
		goto do_migrate;
	}

	if (!errata(ERRATA_UNMAPPED_COLLECTIONS)) {
		report_skip("Skipping test, as this test hangs without the fix. "
			    "Set %s=y to enable.", ERRATA_UNMAPPED_COLLECTIONS);
		test_skipped = true;
		goto do_migrate;
	}

	col = its_create_collection(pe0, pe0);
	dev2 = its_get_device(2);
	dev7 = its_get_device(7);

	/* MAPTI with the collection unmapped */
	its_send_mapti(dev2, 8192, 0, col);
	gicv3_lpi_set_config(8192, LPI_PROP_DEFAULT);

do_migrate:
	puts("Now migrate the VM, then press a key to continue...\n");
	(void)getchar();
	report_info("Migration complete");
	if (test_skipped)
		return;

	/* on the destination, map the collection */
	its_send_mapc(col, true);
	its_send_invall(col);

	lpi_stats_expect(2, 8196);
	its_send_int(dev7, 255);
	check_lpi_stats("dev7/eventid= 255 triggered LPI 8196 on PE #2");

	config = gicv3_lpi_get_config(8192);
	report(config == LPI_PROP_DEFAULT,
	       "Config of LPI 8192 was properly migrated");

	lpi_stats_expect(pe0, 8192);
	its_send_int(dev2, 0);
	check_lpi_stats("dev2/eventid = 0 triggered LPI 8192 on PE0");
}

static void test_its_pending_migration(void)
{
	struct its_device *dev;
	struct its_collection *collection[2];
	int *expected = calloc(nr_cpus, sizeof(int));
	int pe0 = nr_cpus - 1, pe1 = nr_cpus - 2;
	bool test_skipped = false;
	u64 pendbaser;
	void *ptr;
	int i;

	if (its_prerequisites(4)) {
		test_skipped = true;
		goto do_migrate;
	}

	dev = its_create_device(2 /* dev id */, 8 /* nb_ites */);
	its_send_mapd(dev, true);

	collection[0] = its_create_collection(pe0, pe0);
	collection[1] = its_create_collection(pe1, pe1);
	its_send_mapc(collection[0], true);
	its_send_mapc(collection[1], true);

	/* disable lpi at redist level */
	gicv3_lpi_rdist_disable(pe0);
	gicv3_lpi_rdist_disable(pe1);

	/* lpis are interleaved inbetween the 2 PEs */
	for (i = 0; i < 256; i++) {
		struct its_collection *col = i % 2 ? collection[0] :
						     collection[1];
		int vcpu = col->target_address >> 16;

		its_send_mapti(dev, LPI(i), i, col);
		gicv3_lpi_set_config(LPI(i), LPI_PROP_DEFAULT);
		gicv3_lpi_set_clr_pending(vcpu, LPI(i), true);
	}
	its_send_invall(collection[0]);
	its_send_invall(collection[1]);

	/* Clear the PTZ bit on each pendbaser */

	expected[pe0] = 128;
	expected[pe1] = 128;

	ptr = gicv3_data.redist_base[pe0] + GICR_PENDBASER;
	pendbaser = readq(ptr);
	writeq(pendbaser & ~GICR_PENDBASER_PTZ, ptr);

	ptr = gicv3_data.redist_base[pe1] + GICR_PENDBASER;
	pendbaser = readq(ptr);
	writeq(pendbaser & ~GICR_PENDBASER_PTZ, ptr);

	gicv3_lpi_rdist_enable(pe0);
	gicv3_lpi_rdist_enable(pe1);

do_migrate:
	puts("Now migrate the VM, then press a key to continue...\n");
	(void)getchar();
	report_info("Migration complete");
	if (test_skipped)
		return;

	/* let's wait for the 256 LPIs to be handled */
	mdelay(1000);

	check_lpi_hits(expected, "128 LPIs on both PE0 and PE1 after migration");
}
#endif

int main(int argc, char **argv)
{
	if (!gic_init()) {
		printf("No supported gic present, skipping tests...\n");
		return report_summary();
	}

	report_prefix_pushf("gicv%d", gic_version());

	switch (gic_version()) {
	case 2:
		gic = &gicv2;
		break;
	case 3:
		gic = &gicv3;
		break;
	}

	if (argc < 2)
		report_abort("no test specified");

	if (strcmp(argv[1], "ipi") == 0) {
		report_prefix_push(argv[1]);
		nr_cpu_check(2);
		on_cpus(ipi_test, NULL);
	} else if (strcmp(argv[1], "active") == 0) {
		run_active_clear_test();
	} else if (strcmp(argv[1], "mmio") == 0) {
		report_prefix_push(argv[1]);
		gic_test_mmio();
		report_prefix_pop();
	} else if (!strcmp(argv[1], "its-trigger")) {
		report_prefix_push(argv[1]);
		test_its_trigger();
		report_prefix_pop();
	} else if (!strcmp(argv[1], "its-migration")) {
		report_prefix_push(argv[1]);
		test_its_migration();
		report_prefix_pop();
	} else if (!strcmp(argv[1], "its-pending-migration")) {
		report_prefix_push(argv[1]);
		test_its_pending_migration();
		report_prefix_pop();
	} else if (!strcmp(argv[1], "its-migrate-unmapped-collection")) {
		report_prefix_push(argv[1]);
		test_migrate_unmapped_collection();
		report_prefix_pop();
	} else if (strcmp(argv[1], "its-introspection") == 0) {
		report_prefix_push(argv[1]);
		test_its_introspection();
		report_prefix_pop();
	} else {
		report_abort("Unknown subtest '%s'", argv[1]);
	}

	return report_summary();
}
