/* 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 <vfs.h>
#include <kfs.h>
#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/mptables.h>
#include <arch/ioapic.h>

/*
 * MultiProcessor Specification Version 1.[14].
 */
typedef struct {				/* MP Floating Pointer */
	uint8_t signature[4];		/* "_MP_" */
	uint8_t addr[4];			/* PCMP */
	uint8_t length;				/* 1 */
	uint8_t revision;			/* [14] */
	uint8_t checksum;
	uint8_t feature[5];
} _MP_;

typedef struct {				/* MP Configuration Table */
	uint8_t signature[4];		/* "PCMP" */
	uint8_t length[2];
	uint8_t revision;			/* [14] */
	uint8_t checksum;
	uint8_t string[20];			/* OEM + Product ID */
	uint8_t oaddr[4];			/* OEM table pointer */
	uint8_t olength[2];			/* OEM table length */
	uint8_t entry[2];			/* entry count */
	uint8_t apicpa[4];			/* local APIC address */
	uint8_t xlength[2];			/* extended table length */
	uint8_t xchecksum;			/* extended table checksum */
	uint8_t reserved;

	uint8_t entries[];
} PCMP;

typedef struct {
	char type[6];
	int polarity;				/* default for this bus */
	int trigger;				/* default for this bus */
} Mpbus;

static Mpbus mpbusdef[] = {
	{"PCI   ", IPlow, TMlevel,},
	{"ISA   ", IPhigh, TMedge,},
};

static Mpbus *mpbus[Nbus];
int mpisabusno = -1;
#define MP_VERBOSE_DEBUG 0

static void mpintrprint(char *s, uint8_t * p)
{
	char buf[128], *b, *e;
	char format[] = " type %d flags %p bus %d IRQ %d APIC %d INTIN %d\n";

	b = buf;
	e = b + sizeof(buf);
/* can't use seprintf yet!
	b = seprintf(b, e, "mpparse: intr:");
	if(s != NULL)
		b = seprintf(b, e, " %s:", s);
	seprintf(b, e, format, p[1], l16get(p+2), p[4], p[5], p[6], p[7]);
	printd(buf);
*/
	printk("mpparse: intr:");
	if (s != NULL)
		printk(" %s:", s);
	printk(format, p[1], l16get(p + 2), p[4], p[5], p[6], p[7]);
}

static uint32_t mpmkintr(uint8_t * p)
{
	uint32_t v;
	struct apic *apic;
	int n, polarity, trigger;

	/*
	 * Check valid bus, interrupt input pin polarity
	 * and trigger mode. If the APIC ID is 0xff it means
	 * all APICs of this type so those checks for useable
	 * APIC and valid INTIN must also be done later in
	 * the appropriate init routine in that case. It's hard
	 * to imagine routing a signal to all IOAPICs, the
	 * usual case is routing NMI and ExtINT to all LAPICs.
	 */
	if (mpbus[p[4]] == NULL) {
		mpintrprint("no source bus", p);
		return 0;
	}
	if (p[6] != 0xff) {
		if (Napic < 256 && p[6] >= Napic) {
			mpintrprint("APIC ID out of range", p);
			return 0;
		}
		switch (p[0]) {
			default:
				mpintrprint("INTIN botch", p);
				return 0;
			case 3:	/* IOINTR */
				apic = &xioapic[p[6]];
				if (!apic->useable) {
					mpintrprint("unuseable ioapic", p);
					return 0;
				}
				if (p[7] >= apic->nrdt) {
					mpintrprint("IO INTIN out of range", p);
					return 0;
				}
				break;
			case 4:	/* LINTR */
				apic = &xlapic[p[6]];
				if (!apic->useable) {
					mpintrprint("unuseable lapic", p);
					return 0;
				}
				if (p[7] >= ARRAY_SIZE(apic->lvt)) {
					mpintrprint("LOCAL INTIN out of range", p);
					return 0;
				}
				break;
		}
	}
	n = l16get(p + 2);
	if ((polarity = (n & 0x03)) == 2 || (trigger = ((n >> 2) & 0x03)) == 2) {
		mpintrprint("invalid polarity/trigger", p);
		return 0;
	}

	/*
	 * Create the low half of the vector table entry (LVT or RDT).
	 * For the NMI, SMI and ExtINT cases, the polarity and trigger
	 * are fixed (but are not always consistent over IA-32 generations).
	 * For the INT case, either the polarity/trigger are given or
	 * it defaults to that of the source bus;
	 * whether INT is Fixed or Lowest Priority is left until later.
	 */
	v = Im;
	switch (p[1]) {
		default:
			mpintrprint("invalid type", p);
			return 0;
		case 0:	/* INT */
			switch (polarity) {
				case 0:
					v |= mpbus[p[4]]->polarity;
					break;
				case 1:
					v |= IPhigh;
					break;
				case 3:
					v |= IPlow;
					break;
			}
			switch (trigger) {
				case 0:
					v |= mpbus[p[4]]->trigger;
					break;
				case 1:
					v |= TMedge;
					break;
				case 3:
					v |= TMlevel;
					break;
			}
			break;
		case 1:	/* NMI */
			v |= TMedge | IPhigh | MTnmi;
			break;
		case 2:	/* SMI */
			v |= TMedge | IPhigh | MTsmi;
			break;
		case 3:	/* ExtINT */
			v |= TMedge | IPhigh | MTei;
			break;
	}

	return v;
}

static int mpparse(PCMP * pcmp, int maxcores)
{
	uint32_t lo;
	uint8_t *e, *p;
	int devno, i, n;

	p = pcmp->entries;
	e = ((uint8_t *) pcmp) + l16get(pcmp->length);
	while (p < e)
		switch (*p) {
			default:
				printd("mpparse: unknown PCMP type %d (e-p %#ld)\n", *p, e - p);
				for (i = 0; p < e; i++) {
					if (i && ((i & 0x0f) == 0))
						printd("\n");
					printd(" 0x%#2.2x", *p);
					p++;
				}
				printd("\n");
				break;
			case 0:	/* processor */
				/*
				 * Initialise the APIC if it is enabled (p[3] & 0x01).
				 * p[1] is the APIC ID, the memory mapped address comes
				 * from the PCMP structure as the addess is local to the
				 * CPU and identical for all. Indicate whether this is
				 * the bootstrap processor (p[3] & 0x02).
				 */
				printd("mpparse: cpu %d pa %p bp %d\n",
					   p[1], l32get(pcmp->apicpa), p[3] & 0x02);
				if ((p[3] & 0x01) != 0 && maxcores > 0) {
					maxcores--;
					apicinit(p[1], l32get(pcmp->apicpa), p[3] & 0x02);
				}
				p += 20;
				break;
			case 1:	/* bus */
				printd("mpparse: bus: %d type %6.6s\n", p[1], (char *)p + 2);
				if (p[1] >= Nbus) {
					printk("mpparse: bus %d out of range\n", p[1]);
					p += 8;
					break;
				}
				if (mpbus[p[1]] != NULL) {
					printk("mpparse: bus %d already allocated\n", p[1]);
					p += 8;
					break;
				}
				for (i = 0; i < ARRAY_SIZE(mpbusdef); i++) {
					if (memcmp(p + 2, mpbusdef[i].type, 6) != 0)
						continue;
					if (memcmp(p + 2, "ISA   ", 6) == 0) {
						if (mpisabusno != -1) {
							printk("mpparse: bus %d already have ISA bus %d\n",
								   p[1], mpisabusno);
							continue;
						}
						mpisabusno = p[1];
					}
					mpbus[p[1]] = &mpbusdef[i];
					break;
				}
				if (mpbus[p[1]] == NULL)
					printk("mpparse: bus %d type %6.6s unknown\n",
						   p[1], (char *)p + 2);

				p += 8;
				break;
			case 2:	/* IOAPIC */
				/*
				 * Initialise the IOAPIC if it is enabled (p[3] & 0x01).
				 * p[1] is the APIC ID, p[4-7] is the memory mapped address.
				 */
				if (p[3] & 0x01)
					ioapicinit(p[1], -1, l32get(p + 4));

				p += 8;
				break;
			case 3:	/* IOINTR */
				/*
				 * p[1] is the interrupt type;
				 * p[2-3] contains the polarity and trigger mode;
				 * p[4] is the source bus;
				 * p[5] is the IRQ on the source bus;
				 * p[6] is the destination IOAPIC;
				 * p[7] is the INITIN pin on the destination IOAPIC.
				 */
				if (p[6] == 0xff) {
					mpintrprint("routed to all IOAPICs", p);
					p += 8;
					break;
				}
				if ((lo = mpmkintr(p)) == 0) {
					if (MP_VERBOSE_DEBUG)
						mpintrprint("iointr skipped", p);
					p += 8;
					break;
				}
				if (MP_VERBOSE_DEBUG)
					mpintrprint("iointr", p);

				/*
				 * Always present the device number in the style
				 * of a PCI Interrupt Assignment Entry. For the ISA
				 * bus the IRQ is the device number but unencoded.
				 * May need to handle other buses here in the future
				 * (but unlikely).
				 *
				 * For PCI devices, this field's lowest two bits are INT#A == 0,
				 * INT#B == 1, etc.  Bits 2-6 are the PCI device number.
				 */
				devno = p[5];
				if (memcmp(mpbus[p[4]]->type, "PCI   ", 6) != 0)
					devno <<= 2;
				ioapicintrinit(p[4], p[6], p[7], devno, lo);

				p += 8;
				break;
			case 4:	/* LINTR */
				/*
				 * Format is the same as IOINTR above.
				 */
				if ((lo = mpmkintr(p)) == 0) {
					p += 8;
					break;
				}
				if (MP_VERBOSE_DEBUG)
					mpintrprint("LINTR", p);

				/*
				 * Everything was checked in mpmkintr above.
				 */
				if (p[6] == 0xff) {
					for (i = 0; i < Napic; i++) {
						if (!xlapic[i].useable || xlapic[i].addr)
							continue;
						xlapic[i].lvt[p[7]] = lo;
					}
				} else
					xlapic[p[6]].lvt[p[7]] = lo;
				p += 8;
				break;
		}

	/*
	 * There's nothing of interest in the extended table,
	 * but check it for consistency.
	 */
	p = e;
	e = p + l16get(pcmp->xlength);
	while (p < e)
		switch (*p) {
			default:
				n = p[1];
				printd("mpparse: unknown extended entry %d length %d\n", *p, n);
				for (i = 0; i < n; i++) {
					if (i && ((i & 0x0f) == 0))
						printd("\n");
					printd(" %#2.2ux", *p);
					p++;
				}
				printd("\n");
				break;
			case 128:
				printd("address space mapping\n");
				printd(" bus %d type %d base %#llux length %#llux\n",
					   p[2], p[3], l64get(p + 4), l64get(p + 12));
				p += p[1];
				break;
			case 129:
				printd("bus hierarchy descriptor\n");
				printd(" bus %d sd %d parent bus %d\n", p[2], p[3], p[4]);
				p += p[1];
				break;
			case 130:
				printd("compatibility bus address space modifier\n");
				printd(" bus %d pr %d range list %d\n",
					   p[2], p[3], l32get(p + 4));
				p += p[1];
				break;
		}
	return maxcores;
}

static void *sigsearch(char *signature)
{
	uintptr_t p;
	uint8_t *bda;
	void *r;
#if 0
	/*
	 * Search for the data structure:
	 * 1) in the first KB of the EBDA;
	 * 2) in the last KB of system base memory;
	 * 3) in the BIOS ROM between 0xe0000 and 0xfffff.
	 */
	bda = BIOSSEG(0x40);
	if (memcmp(KADDR(0xfffd9), "EISA", 4) == 0) {
		if ((p = (bda[0x0f] << 8) | bda[0x0e])) {
			if ((r = sigscan(BIOSSEG(p), 1024, signature)) != NULL)
				return r;
		}
	}

	p = ((bda[0x14] << 8) | bda[0x13]) * 1024;
	if ((r = sigscan(KADDR(p - 1024), 1024, signature)) != NULL)
		return r;
#endif
	r = sigscan(KADDR(0xe0000), 0x20000, signature);
	printk("Found MP table at %p\n", r);
	if (r != NULL)
		return r;

	return NULL;
	/* and virtualbox hidden mp tables... */
//  return sigscan(KADDR(0xa0000 - 1024), 1024, signature);
}

int mpsinit(int maxcores)
{
	uint8_t *p;
	int i, n;
	_MP_ *mp;
	PCMP *pcmp;

	if ((mp = sigsearch("_MP_")) == NULL) {
		printk("No mp tables found, might have issues!\n");
		return maxcores;
	}
	/* TODO: if an IMCR exists, we should set it to 1, though i've heard that
	 * ACPI-capable HW doesn't have the IMCR anymore. */

	if (MP_VERBOSE_DEBUG) {
		printk("_MP_ @ %#p, addr %p length %ud rev %d",
			   mp, l32get(mp->addr), mp->length, mp->revision);
		for (i = 0; i < sizeof(mp->feature); i++)
			printk(" %2.2p", mp->feature[i]);
		printk("\n");
	}
	if (mp->revision != 1 && mp->revision != 4)
		return maxcores;
	if (sigchecksum(mp, mp->length * 16) != 0)
		return maxcores;
	if ((pcmp = KADDR_NOCHECK(l32get(mp->addr))) == NULL)
		return maxcores;
	if (pcmp->revision != 1 && pcmp->revision != 4) {
		return maxcores;
	}
	n = l16get(pcmp->length) + l16get(pcmp->xlength);
	if ((pcmp = KADDR_NOCHECK(l32get(mp->addr))) == NULL)
		return maxcores;
	if (sigchecksum(pcmp, l16get(pcmp->length)) != 0) {
		return maxcores;
	}
	if (MP_VERBOSE_DEBUG) {
		printk("PCMP @ %#p length %p revision %d\n",
			   pcmp, l16get(pcmp->length), pcmp->revision);
		printk(" %20.20s oaddr %p olength %p\n",
			   (char *)pcmp->string, l32get(pcmp->oaddr),
			   l16get(pcmp->olength));
		printk(" entry %d apicpa %p\n",
			   l16get(pcmp->entry), l32get(pcmp->apicpa));

		printk(" xlength %p xchecksum %p\n",
			   l16get(pcmp->xlength), pcmp->xchecksum);
	}
	if (pcmp->xchecksum != 0) {
		p = ((uint8_t *) pcmp) + l16get(pcmp->length);
		i = sigchecksum(p, l16get(pcmp->xlength));
		if (((i + pcmp->xchecksum) & 0xff) != 0) {
			printd("extended table checksums to %p\n", i);
			return maxcores;
		}
	}

	/*
	 * Parse the PCMP table and set up the datastructures
	 * for later interrupt enabling and application processor
	 * startup.
	 */
	return mpparse(pcmp, maxcores);
}
