/*
 * 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%08x => 0x%02x", 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%02x into bytes 2 => 0x%08x",
			    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%08x", 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("%d 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 %08x reads back as %08x",
			    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%08x", 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%08x", 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();
}
