/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <net/ip.h>
#include <arch/io.h>
#include <acpi.h>
#include <trap.h>

/* Rbus chains, one for each device bus: each rbus matches a device to an rdt */
struct Rbus {
	struct Rbus *next;
	int devno;
	struct Rdt *rdt;
};

/* Each rdt describes an ioapic input pin (intin, from the bus/device) */
struct Rdt {
	struct apic *apic;
	int intin;
	uint32_t lo;				/* matches the lo in the intin, incl Im */
	uint32_t hi;				/* matches the hi in the intin, incl routing */

	int ref;					/* could map to multiple busses */
	int enabled;				/* times enabled */
};

enum {							/* IOAPIC registers */
	Ioregsel = 0x00,			/* indirect register address */
	Iowin = 0x10,	/* indirect register data */
	Ioipa = 0x08,	/* IRQ Pin Assertion */
	Ioeoi = 0x10,	/* EOI */

	Ioapicid = 0x00,	/* Identification */
	Ioapicver = 0x01,	/* Version */
	Ioapicarb = 0x02,	/* Arbitration */
	Ioabcfg = 0x03,	/* Boot Coniguration */
	Ioredtbl = 0x10,	/* Redirection Table */
};

static struct Rdt rdtarray[Nrdt];
static int nrdtarray;
static struct Rbus *rdtbus[Nbus];
/* reverse mapping of IDT vector to the RDT/IOAPIC entry triggering vector */
static struct Rdt *rdtvecno[IdtMAX + 1];

static spinlock_t idtnolock;
static int idtno = IdtIOAPIC;

struct apic xioapic[Napic];

static bool ioapic_exists(void)
{
	/* not foolproof, if we called this before parsing */
	for (int i = 0; i < Napic; i++)
		if (xioapic[i].useable)
			return TRUE;
	return FALSE;
}

static void rtblget(struct apic *apic, int sel, uint32_t * hi, uint32_t * lo)
{
	sel = Ioredtbl + 2 * sel;

	write_mmreg32(apic->addr + Ioregsel, sel + 1);
	*hi = read_mmreg32(apic->addr + Iowin);
	write_mmreg32(apic->addr + Ioregsel, sel);
	*lo = read_mmreg32(apic->addr + Iowin);
}

static void rtblput(struct apic *apic, int sel, uint32_t hi, uint32_t lo)
{
	sel = Ioredtbl + 2 * sel;

	write_mmreg32(apic->addr + Ioregsel, sel + 1);
	write_mmreg32(apic->addr + Iowin, hi);
	write_mmreg32(apic->addr + Ioregsel, sel);
	write_mmreg32(apic->addr + Iowin, lo);
}

struct Rdt *rdtlookup(struct apic *apic, int intin)
{
	int i;
	struct Rdt *r;

	for (i = 0; i < nrdtarray; i++) {
		r = rdtarray + i;
		if (apic == r->apic && intin == r->intin)
			return r;
	}
	return NULL;
}

struct Rdt *rbus_get_rdt(int busno, int devno)
{
	struct Rbus *rbus;
	for (rbus = rdtbus[busno]; rbus != NULL; rbus = rbus->next) {
		if (rbus->devno == devno)
			return rbus->rdt;
	}
	return 0;
}

/* builds RDT and Rbus entries, given the wiring of bus:dev to ioapicno:intin.
 * - busno is the source bus
 * - devno is the device number in the style of a PCI Interrupt Assignment
 * Entry.  Which is the irq << 2 (check MP spec D.3).
 * - ioapic is the ioapic the device is connected to
 * - intin is the INTIN pin on the ioapic
 * - lo is the lower part of the IOAPIC apic-message, which has the polarity and
 * trigger mode flags. */
void ioapicintrinit(int busno, int ioapicno, int intin, int devno, int lo)
{
	struct Rbus *rbus;
	struct Rdt *rdt;
	struct apic *ioapic;

	if (busno >= Nbus || ioapicno >= Napic || nrdtarray >= Nrdt) {
		printk("Bad bus %d ioapic %d or nrdtarray %d too big\n", busno,
		       ioapicno, nrdtarray);
		return;
	}
	ioapic = &xioapic[ioapicno];
	if (!ioapic->useable || intin >= ioapic->nrdt) {
		printk("IOAPIC unusable (%d) or not enough nrdt (%d) for %d\n",
		       ioapic->useable, ioapic->nrdt, intin);
		return;
	}

	rdt = rdtlookup(ioapic, intin);
	if (rdt == NULL) {
		rdt = &rdtarray[nrdtarray++];
		rdt->apic = ioapic;
		rdt->intin = intin;
		rdt->lo = lo;
		rdt->hi = 0;
	} else {
		/* Polarity/trigger check.  Stored lo also has the vector in 0xff */
		if (lo != (rdt->lo & ~0xff)) {
			printk("multiple irq botch bus %d %d/%d/%d lo %d vs %d\n",
				   busno, ioapicno, intin, devno, lo, rdt->lo);
			return;
		}
	}
	/* TODO: this shit is racy.  (refcnt, linked list addition) */
	rdt->ref++;
	rbus = kzmalloc(sizeof *rbus, 0);
	rbus->rdt = rdt;
	rbus->devno = devno;
	rbus->next = rdtbus[busno];
	rdtbus[busno] = rbus;
}

static int map_polarity[4] = {
	-1, IPhigh, -1, IPlow
};

static int map_edge_level[4] = {
	-1, TMedge, -1, TMlevel
};

static int acpi_irq2ioapic(int irq)
{
	int ioapic_idx = 0;
	struct apic *ioapic;
	/* with acpi, the ioapics map a global interrupt space.  each covers a
	 * window of the space from [ibase, ibase + nrdt). */
	for (ioapic = xioapic; ioapic < &xioapic[Napic]; ioapic++, ioapic_idx++) {
		/* addr check is just for sanity */
		if (!ioapic->useable || !ioapic->addr)
			continue;
		if ((ioapic->ibase <= irq) && (irq < ioapic->ibase + ioapic->nrdt))
			return ioapic_idx;
	}
	return -1;
}

/* Build an RDT route, like we would have had from the MP tables had they been
 * parsed, via ACPI.
 *
 * This only really deals with the ISA IRQs and maybe PCI ones that happen to
 * have an override.  FWIW, on qemu the PCI NIC shows up as an ACPI intovr.
 *
 * From Brendan http://f.osdev.org/viewtopic.php?f=1&t=25951:
 *
 * 		Before parsing the MADT you should begin by assuming that redirection
 * 		entries 0 to 15 are used for ISA IRQs 0 to 15. The MADT's "Interrupt
 * 		Source Override Structures" will tell you when this initial/default
 * 		assumption is wrong. For example, the MADT might tell you that ISA IRQ 9
 * 		is connected to IO APIC 44 and is level triggered; and (in this case)
 * 		it'd be silly to assume that ISA IRQ 9 is also connected to IO APIC
 * 		input 9 just because IO APIC input 9 is not listed.
 *
 *		For PCI IRQs, the MADT tells you nothing and you can't assume anything
 *		at all. Sadly, you have to interpret the ACPI AML to determine how PCI
 *		IRQs are connected to IO APIC inputs (or find some other work-around;
 *		like implementing a motherboard driver for each different motherboard,
 *		or some complex auto-detection scheme, or just configure PCI devices to
 *		use MSI instead). */
static int acpi_make_rdt(int tbdf, int irq, int busno, int devno)
{
	struct Atable *at;
	struct Apicst *st, *lst;
	uint32_t lo;
	int pol, edge_level, ioapic_nr, gsi_irq;

	at = apics;
	st = NULL;
	for (int i = 0; i < at->nchildren; i++) {
		lst = at->children[i]->tbl;
		if (lst->type == ASintovr) {
			if (lst->intovr.irq == irq) {
				st = lst;
				break;
			}
		}
	}
	if (st) {
		pol = map_polarity[st->intovr.flags & AFpmask];
		if (pol < 0) {
			printk("ACPI override had bad polarity\n");
			return -1;
		}
		edge_level = map_edge_level[(st->intovr.flags & AFlevel) >> 2];
		if (edge_level < 0) {
			printk("ACPI override had bad edge/level\n");
			return -1;
		}
		lo = pol | edge_level;
		gsi_irq = st->intovr.intr;
	} else {
		if (BUSTYPE(tbdf) == BusISA) {
			lo = IPhigh | TMedge;
			gsi_irq = irq;
		} else {
			/* Need to query ACPI at some point to handle this */
			printk("Non-ISA IRQ %d not found in MADT, aborting\n", irq);
			return -1;
		}
	}
	ioapic_nr = acpi_irq2ioapic(gsi_irq);
	if (ioapic_nr < 0) {
		printk("Could not find an IOAPIC for global irq %d!\n", gsi_irq);
		return -1;
	}
	ioapicintrinit(busno, ioapic_nr, gsi_irq - xioapic[ioapic_nr].ibase,
	               devno, lo);
	return 0;
}

void ioapicinit(int id, int ibase, uintptr_t pa)
{
	struct apic *apic;
	static int base;

	assert((IOAPIC_PBASE <= pa) && (pa + PGSIZE <= IOAPIC_PBASE + APIC_SIZE));
	/*
	 * Mark the IOAPIC useable if it has a good ID
	 * and the registers can be mapped.
	 */
	if (id >= Napic)
		return;

	apic = &xioapic[id];
	apic->addr = IOAPIC_BASE + (pa - IOAPIC_PBASE);
	if (apic->useable)
		return;
	apic->useable = 1;
	apic->paddr = pa;

	/*
	 * Initialise the I/O APIC.
	 * The MultiProcessor Specification says it is the
	 * responsibility of the O/S to set the APIC ID.
	 */
	spin_lock(&apic->lock);
	write_mmreg32(apic->addr + Ioregsel, Ioapicver);
	apic->nrdt = ((read_mmreg32(apic->addr + Iowin) >> 16) & 0xff) + 1;
	/* the ibase is the global system interrupt base, told to us by ACPI.  if
	 * it's -1, we're called from mpparse, and just guess/make up our own
	 * assignments. */
	if (ibase != -1)
		apic->ibase = ibase;
	else {
		apic->ibase = base;
		base += apic->nrdt;
	}
	write_mmreg32(apic->addr + Ioregsel, Ioapicid);
	write_mmreg32(apic->addr + Iowin, id << 24);
	spin_unlock(&apic->lock);
	printk("IOAPIC initialized at %p\n", apic->addr);
}

char *ioapicdump(char *start, char *end)
{
	int i, n;
	struct Rbus *rbus;
	struct Rdt *rdt;
	struct apic *apic;
	uint32_t hi, lo;

	if (!2)
		return start;
	for (i = 0; i < Napic; i++) {
		apic = &xioapic[i];
		if (!apic->useable || apic->addr == 0)
			continue;
		start = seprintf(start, end, "ioapic %d addr %p nrdt %d ibase %d\n",
						 i, apic->addr, apic->nrdt, apic->ibase);
		for (n = 0; n < apic->nrdt; n++) {
			spin_lock(&apic->lock);
			rtblget(apic, n, &hi, &lo);
			spin_unlock(&apic->lock);
			start = seprintf(start, end, " rdt %2.2d %p %p\n", n, hi, lo);
		}
	}
	for (i = 0; i < Nbus; i++) {
		if ((rbus = rdtbus[i]) == NULL)
			continue;
		start = seprintf(start, end, "iointr bus %d:\n", i);
		for (; rbus != NULL; rbus = rbus->next) {
			rdt = rbus->rdt;
			start = seprintf(start, end,
							 " apic %ld devno %p(%d %d) intin %d hi %p lo %p\n",
							 rdt->apic - xioapic, rbus->devno, rbus->devno >> 2,
							 rbus->devno & 0x03, rdt->intin, rdt->hi, rdt->lo);
		}
	}
	return start;
}

/* Zeros and masks every redirect entry in every IOAPIC */
void ioapiconline(void)
{
	int i;
	struct apic *apic;

	for (apic = xioapic; apic < &xioapic[Napic]; apic++) {
		if (!apic->useable || !apic->addr)
			continue;
		for (i = 0; i < apic->nrdt; i++) {
			spin_lock(&apic->lock);
			rtblput(apic, i, 0, Im);
			spin_unlock(&apic->lock);
		}
	}
}

int nextvec(void)
{
	unsigned int vecno;

	/* TODO: half-way decent integer service (vmem) */
	spin_lock(&idtnolock);
	vecno = idtno;
	idtno = (idtno + 1) % IdtMAX;
	if (idtno < IdtIOAPIC)
		idtno += IdtIOAPIC;
	spin_unlock(&idtnolock);

	return vecno;
}

static void msi_mask_irq(struct irq_handler *irq_h, int apic_vector)
{
	pci_msi_mask(irq_h->dev_private);
}

static void msi_unmask_irq(struct irq_handler *irq_h, int apic_vector)
{
	pci_msi_unmask(irq_h->dev_private);
}

static void msi_route_irq(struct irq_handler *irq_h, int apic_vector, int dest)
{
	pci_msi_route(irq_h->dev_private, dest);
}

static void msix_mask_irq(struct irq_handler *irq_h, int apic_vector)
{
	pci_msix_mask_vector(irq_h->dev_private);
}

static void msix_unmask_irq(struct irq_handler *irq_h, int apic_vector)
{
	pci_msix_unmask_vector(irq_h->dev_private);
}

static void msix_route_irq(struct irq_handler *irq_h, int apic_vector, int dest)
{
	pci_msix_route_vector(irq_h->dev_private, dest);
}

static int msi_irq_enable(struct irq_handler *irq_h, struct pci_device *p)
{
	unsigned int vno, lo, hi = 0;
	uint64_t msivec;
	struct msix_irq_vector *linkage;

	vno = nextvec();

	/* routing the IRQ to core 0 (hi = 0) in physical mode (Pm) */
	lo = IPlow | TMedge | Pm | vno;

	msivec = (uint64_t) hi << 32 | lo;
	irq_h->dev_private = pci_msix_enable(p, msivec);
	if (!irq_h->dev_private) {
		if (pci_msi_enable(p, msivec) == -1) {
			/* TODO: should free vno here */
			return -1;
		}
		irq_h->dev_private = p;
		irq_h->check_spurious = lapic_check_spurious;
		irq_h->eoi = lapic_send_eoi;
		irq_h->mask = msi_mask_irq;
		irq_h->unmask = msi_unmask_irq;
		irq_h->route_irq = msi_route_irq;
		irq_h->type = "msi";
		printk("MSI irq: (%x,%x,%x): enabling %p %s vno %d\n",
			   p->bus, p->dev, p->func, msivec, irq_h->name, vno);
		return vno;
	}
	irq_h->check_spurious = lapic_check_spurious;
	irq_h->eoi = lapic_send_eoi;
	irq_h->mask = msix_mask_irq;
	irq_h->unmask = msix_unmask_irq;
	irq_h->route_irq = msix_route_irq;
	irq_h->type = "msi-x";
	printk("MSI-X irq: (%x,%x,%x): enabling %p %s vno %d\n",
	       p->bus, p->dev, p->func, msivec, irq_h->name, vno);
	return vno;
}

static struct Rdt *ioapic_vector2rdt(int apic_vector)
{
	struct Rdt *rdt;
	if (apic_vector < IdtIOAPIC || apic_vector > MaxIdtIOAPIC) {
		warn("ioapic vector %d out of range", apic_vector);
		return 0;
	}
	/* Fortunately rdtvecno[vecno] is static once assigned. o/w, we'll need some
	 * global sync for the callers, both for lookup and keeping rdt valid. */
	rdt = rdtvecno[apic_vector];
	if (!rdt) {
		warn("vector %d has no RDT! (did you enable it?)", apic_vector);
		return 0;
	}
	return rdt;
}

/* Routes the IRQ to the hw_coreid.  Will take effect immediately.  Route
 * masking from rdt->lo will take effect.  The early return cases are probably
 * bugs in IOAPIC irq_h setup. */
static void ioapic_route_irq(struct irq_handler *unused, int apic_vector,
                             int hw_coreid)
{
	struct Rdt *rdt = ioapic_vector2rdt(apic_vector);
	if (!rdt) {
		printk("Missing IOAPIC route for vector!\n", apic_vector);
		return;
	}
	spin_lock(&rdt->apic->lock);
	/* this bit gets set in apicinit, only if we found it via MP or ACPI */
	if (!xlapic[hw_coreid].useable) {
		printk("Can't route to uninitialized LAPIC %d!\n", hw_coreid);
		spin_unlock(&rdt->apic->lock);
		return;
	}
	rdt->hi = hw_coreid << 24;
	rdt->lo |= Pm | MTf;
	rtblput(rdt->apic, rdt->intin, rdt->hi, rdt->lo);
	spin_unlock(&rdt->apic->lock);
}

static void ioapic_mask_irq(struct irq_handler *unused, int apic_vector)
{
	/* could store the rdt in the irq_h */
	struct Rdt *rdt = ioapic_vector2rdt(apic_vector);
	if (!rdt)
		return;
	spin_lock(&rdt->apic->lock);
	/* don't allow shared vectors to be masked.  whatever. */
	if (rdt->enabled > 1) {
		spin_unlock(&rdt->apic->lock);
		return;
	}
	rdt->lo |= Im;
	rtblput(rdt->apic, rdt->intin, rdt->hi, rdt->lo);
	spin_unlock(&rdt->apic->lock);
}

static void ioapic_unmask_irq(struct irq_handler *unused, int apic_vector)
{
	struct Rdt *rdt = ioapic_vector2rdt(apic_vector);
	if (!rdt)
		return;
	spin_lock(&rdt->apic->lock);
	rdt->lo &= ~Im;
	rtblput(rdt->apic, rdt->intin, rdt->hi, rdt->lo);
	spin_unlock(&rdt->apic->lock);
}

/* Attempts to init a bus interrupt, initializes irq_h, and returns the IDT
 * vector to use (-1 on error).  If routable, the IRQ will route to core 0.  The
 * IRQ will be masked, if possible.  Call irq_h->unmask() when you're ready.
 *
 * This will determine the type of bus the device is on (LAPIC, IOAPIC, PIC,
 * etc), and set the appropriate fields in isr_h.  If applicable, it'll also
 * allocate an IDT vector, such as for an IOAPIC, and route the IOAPIC entries
 * appropriately.
 *
 * Callers init irq_h->dev_irq and ->tbdf.  tbdf encodes the bus type and the
 * classic PCI bus:dev:func.  dev_irq may be ignored based on the bus type (e.g.
 * PCI, esp MSI).
 *
 * In plan9, this was ioapicintrenable(), which also unmasked.  We don't have a
 * deinit/disable method that would tear down the route yet.  All the plan9 one
 * did was dec enabled and mask the entry. */
int bus_irq_setup(struct irq_handler *irq_h)
{
	struct Rbus *rbus;
	struct Rdt *rdt;
	int busno, devno, vecno;
	struct pci_device *pcidev;

	if (!ioapic_exists()) {
		switch (BUSTYPE(irq_h->tbdf)) {
			case BusLAPIC:
			case BusIPI:
				break;
			default:
				irq_h->check_spurious = pic_check_spurious;
				irq_h->eoi = pic_send_eoi;
				irq_h->mask = pic_mask_irq;
				irq_h->unmask = pic_unmask_irq;
				irq_h->route_irq = 0;
				irq_h->type = "pic";
				/* PIC devices have vector = irq + 32 */
				return irq_h->dev_irq + IdtPIC;
		}
	}
	switch (BUSTYPE(irq_h->tbdf)) {
		case BusLAPIC:
			/* nxm used to set the initial 'isr' method (i think equiv to our
			 * check_spurious) to apiceoi for non-spurious lapic vectors.  in
			 * effect, i think they were sending the EOI early, and their eoi
			 * method was 0.  we're not doing that (unless we have to). */
			irq_h->check_spurious = lapic_check_spurious;
			irq_h->eoi = lapic_send_eoi;
			irq_h->mask = lapic_mask_irq;
			irq_h->unmask = lapic_unmask_irq;
			irq_h->route_irq = 0;
			irq_h->type = "lapic";
			/* For the LAPIC, irq == vector */
			return irq_h->dev_irq;
		case BusIPI:
			/* similar to LAPIC, but we don't actually have LVT entries */
			irq_h->check_spurious = lapic_check_spurious;
			irq_h->eoi = lapic_send_eoi;
			irq_h->mask = 0;
			irq_h->unmask = 0;
			irq_h->route_irq = 0;
			irq_h->type = "IPI";
			return irq_h->dev_irq;
		case BusISA:
			if (mpisabusno == -1)
				panic("No ISA bus allocated");
			busno = mpisabusno;
			/* need to track the irq in devno in PCI interrupt assignment entry
			 * format (see mp.c or MP spec D.3). */
			devno = irq_h->dev_irq << 2;
			break;
		case BusPCI:
			pcidev = pci_match_tbdf(irq_h->tbdf);
			if (!pcidev) {
				warn("No PCI dev for tbdf %p!", irq_h->tbdf);
				return -1;
			}
			if ((vecno = msi_irq_enable(irq_h, pcidev)) != -1)
				return vecno;
			busno = BUSBNO(irq_h->tbdf);
			assert(busno == pcidev->bus);
			devno = pcidev_read8(pcidev, PciINTP);

			/* this might not be a big deal - some PCI devices have no INTP.  if
			 * so, change our devno - 1 below. */
			if (devno == 0)
				panic("no INTP for tbdf %p", irq_h->tbdf);
			/* remember, devno is the device shifted with irq pin in bits 0-1.
			 * we subtract 1, since the PCI intp maps 1 -> INTA, 2 -> INTB, etc,
			 * and the MP spec uses 0 -> INTA, 1 -> INTB, etc. */
			devno = BUSDNO(irq_h->tbdf) << 2 | (devno - 1);
			break;
		default:
			panic("Unknown bus type, TBDF %p", irq_h->tbdf);
	}
	/* busno and devno are set, regardless of the bustype, enough to find rdt.
	 * these may differ from the values in tbdf. */
	rdt = rbus_get_rdt(busno, devno);
	if (!rdt) {
		/* second chance.  if we didn't find the item the first time, then (if
		 * it exists at all), it wasn't in the MP tables (or we had no tables).
		 * So maybe we can figure it out via ACPI. */
		acpi_make_rdt(irq_h->tbdf, irq_h->dev_irq, busno, devno);
		rdt = rbus_get_rdt(busno, devno);
	}
	if (!rdt) {
		printk("Unable to build IOAPIC route for irq %d\n", irq_h->dev_irq);
		return -1;
	}
	/*
	 * what to do about devices that intrenable/intrdisable frequently?
	 * 1) there is no ioapicdisable yet;
	 * 2) it would be good to reuse freed vectors.
	 * Oh bugger.
	 * brho: plus the diff btw mask/unmask and enable/disable is unclear
	 */
	/*
	 * This is a low-frequency event so just lock
	 * the whole IOAPIC to initialise the RDT entry
	 * rather than putting a Lock in each entry.
	 */
	spin_lock(&rdt->apic->lock);
	/* if a destination has already been picked, we store it in the lo.  this
	 * stays around regardless of enabled/disabled, since we don't reap vectors
	 * yet.  nor do we really mess with enabled... */
	if ((rdt->lo & 0xff) == 0) {
		vecno = nextvec();
		rdt->lo |= vecno;
		rdtvecno[vecno] = rdt;
	} else {
		printd("%p: mutiple irq bus %d dev %d\n", irq_h->tbdf, busno, devno);
	}
	rdt->enabled++;
	rdt->hi = 0;			/* route to 0 by default */
	rdt->lo |= Pm | MTf;
	rtblput(rdt->apic, rdt->intin, rdt->hi, rdt->lo);
	vecno = rdt->lo & 0xff;
	spin_unlock(&rdt->apic->lock);

	irq_h->check_spurious = lapic_check_spurious;
	irq_h->eoi = lapic_send_eoi;
	irq_h->mask = ioapic_mask_irq;
	irq_h->unmask = ioapic_unmask_irq;
	irq_h->route_irq = ioapic_route_irq;
	irq_h->type = "ioapic";

	return vecno;
}
