/*
 * Intel IOMMU unit test.
 *
 * Copyright (C) 2016 Red Hat, Inc.
 *
 * Authors:
 *   Peter Xu <peterx@redhat.com>,
 *
 * This work is licensed under the terms of the GNU LGPL, version 2 or
 * later.
 */

#include "intel-iommu.h"
#include "pci-edu.h"
#include "x86/apic.h"
#include "vm.h"
#include "alloc_page.h"

#define VTD_TEST_DMAR_4B ("DMAR 4B memcpy test")
#define VTD_TEST_IR_MSI ("IR MSI")
#define VTD_TEST_IR_IOAPIC ("IR IOAPIC")

static struct pci_edu_dev edu_dev;

static void vtd_test_dmar(void)
{
	struct pci_edu_dev *dev = &edu_dev;
	void *page = alloc_page();

	report_prefix_push("vtd_dmar");

#define DMA_TEST_WORD (0x12345678)
	/* Modify the first 4 bytes of the page */
	*(uint32_t *)page = DMA_TEST_WORD;

	/*
	 * Map the newly allocated page into IOVA address 0 (size 4K)
	 * of the device address space. Root entry and context entry
	 * will be automatically created when needed.
	 */
	vtd_map_range(dev->pci_dev.bdf, 0, virt_to_phys(page), PAGE_SIZE);

	/*
	 * DMA the first 4 bytes of the page to EDU device buffer
	 * offset 0.
	 */
	edu_dma(dev, 0, 4, 0, false);

	/*
	 * DMA the first 4 bytes of EDU device buffer into the page
	 * with offset 4 (so it'll be using 4-7 bytes).
	 */
	edu_dma(dev, 4, 4, 0, true);

	/*
	 * Check data match between 0-3 bytes and 4-7 bytes of the
	 * page.
	 */
	report(*((uint32_t *)page + 1) == DMA_TEST_WORD, VTD_TEST_DMAR_4B);

	free_page(page);

	report_prefix_pop();
}

static volatile bool edu_intr_recved;

static void edu_isr(isr_regs_t *regs)
{
	edu_intr_recved = true;
	eoi();
	edu_reg_writel(&edu_dev, EDU_REG_INTR_ACK,
			edu_reg_readl(&edu_dev, EDU_REG_INTR_STATUS));
}

static void vtd_test_ir(void)
{
#define VTD_TEST_VECTOR_IOAPIC (0xed)
#define VTD_TEST_VECTOR_MSI (0xee)
	struct pci_edu_dev *dev = &edu_dev;
	struct pci_dev *pci_dev = &dev->pci_dev;

	report_prefix_push("vtd_ir");

	sti();

	/* This will enable INTx */
	pci_msi_set_enable(pci_dev, false);
	vtd_setup_ioapic_irq(pci_dev, VTD_TEST_VECTOR_IOAPIC,
			     0, TRIGGER_EDGE);
	handle_irq(VTD_TEST_VECTOR_IOAPIC, edu_isr);

	edu_intr_recved = false;
	wmb();
	/* Manually trigger INTR */
	edu_reg_writel(dev, EDU_REG_INTR_RAISE, 1);

	while (!edu_intr_recved)
		cpu_relax();

	/* Clear INTR bits */
	edu_reg_writel(dev, EDU_REG_INTR_RAISE, 0);

	/* We are good as long as we reach here */
	report(edu_intr_recved == true, VTD_TEST_IR_IOAPIC);

	/*
	 * Setup EDU PCI device MSI, using interrupt remapping. By
	 * default, EDU device is using INTx.
	 */
	if (!vtd_setup_msi(pci_dev, VTD_TEST_VECTOR_MSI, 0)) {
		printf("edu device does not support MSI, skip test\n");
		report_skip(VTD_TEST_IR_MSI);
		return;
	}

	handle_irq(VTD_TEST_VECTOR_MSI, edu_isr);

	edu_intr_recved = false;
	wmb();
	/* Manually trigger INTR */
	edu_reg_writel(dev, EDU_REG_INTR_RAISE, 1);

	while (!edu_intr_recved)
		cpu_relax();

	/* We are good as long as we reach here */
	report(edu_intr_recved == true, VTD_TEST_IR_MSI);

	report_prefix_pop();
}

int main(int argc, char *argv[])
{
	setup_vm();

	vtd_init();

	report_prefix_push("vtd_init");

	report(vtd_readl(DMAR_FSTS_REG) == 0, "fault status check");
	report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_QI, "QI enablement");
	report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_ROOT, "DMAR table setup");
	report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_IR_TABLE, "IR table setup");
	report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_DMAR, "DMAR enablement");
	report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_IR, "IR enablement");
	report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW,
	       "DMAR support 39 bits address width");
	report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SLLPS,
	       "DMAR support huge pages");

	report_prefix_pop();

	if (!edu_init(&edu_dev)) {
		printf("Please specify \"-device edu\" to do "
		       "further IOMMU tests.\n");
		report_skip(VTD_TEST_DMAR_4B);
		report_skip(VTD_TEST_IR_IOAPIC);
		report_skip(VTD_TEST_IR_MSI);
	} else {
		printf("Found EDU device:\n");
		pci_dev_print(&edu_dev.pci_dev);
		vtd_test_dmar();
		vtd_test_ir();
	}

	return report_summary();
}
