/*
 * 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 <ns.h>
#include <acpi.h>
#include <slice.h>

#include "../timers/hpet.h"

#ifdef CONFIG_X86
#include <arch/pci.h>
#endif

/* -----------------------------------------------------------------------------
 * Basic ACPI device.
 *
 * The qid.Path will be made unique by incrementing lastpath. lastpath starts
 * at Qroot.
 *
 * Qtbl will return a pointer to the Atable, which includes the signature, OEM
 * data, and so on.
 *
 * Raw, at any level, dumps the raw table at that level, which by the ACPI
 * flattened tree layout will include all descendents.
 *
 * Qpretty, at any level, will print the pretty form for that level and all
 * descendants.
 */
enum {
	Qroot = 0,

	// The type is the qid.path mod NQtypes.
	Qdir = 0,
	Qpretty,
	Qraw,
	Qtbl,
	NQtypes,

	QIndexShift = 8,
	QIndexMask = (1 << QIndexShift) - 1,
};

#define ATABLEBUFSZ	ROUNDUP(sizeof(struct Atable), KMALLOC_ALIGNMENT)

static uint64_t lastpath;
static struct slice emptyslice;
static struct Atable **atableindex;
struct dev acpidevtab;

static char *devname(void)
{
	return acpidevtab.name;
}

/*
 * ACPI 4.0 Support.
 * Still WIP.
 *
 * This driver locates tables and parses only a small subset
 * of tables. All other tables are mapped and kept for the user-level
 * interpreter.
 */
static struct cmdtab ctls[] = {
	{CMregion, "region", 6},
	{CMgpe, "gpe", 3},
};

static struct Facs *facs;		/* Firmware ACPI control structure */
static struct Fadt *fadt;		/* Fixed ACPI description to reach ACPI regs */
static struct Atable *root;
static struct Xsdt *xsdt;		/* XSDT table */
static struct Atable *tfirst;	/* loaded DSDT/SSDT/... tables */
static struct Atable *tlast;	/* pointer to last table */
struct Atable *apics;			/* APIC info */
struct Atable *srat;			/* System resource affinity used by physalloc */
struct Atable *dmar;
static struct Slit *slit;		/* Sys locality info table used by scheduler */
static struct Atable *mscttbl;		/* Maximum system characteristics table */
static struct Reg *reg;			/* region used for I/O */
static struct Gpe *gpes;		/* General purpose events */
static int ngpes;

static char *regnames[] = {
	"mem", "io", "pcicfg", "embed",
	"smb", "cmos", "pcibar", "ipmi",
};

/*
 * Lists to store RAM that we copy ACPI tables into. When we map a new
 * ACPI list into the kernel, we copy it into a specifically RAM buffer
 * (to make sure it's not coming from e.g. slow device memory). We store
 * pointers to those buffers on these lists.
 */
struct Acpilist {
	struct Acpilist *next;
	size_t size;
	int8_t raw[];
};

static struct Acpilist *acpilists;

/*
 * Produces an Atable at some level in the tree. Note that Atables are
 * isomorphic to directories in the file system namespace; this code
 * ensures that invariant.
 */
struct Atable *mkatable(struct Atable *parent,
                        int type, char *name, uint8_t *raw,
                        size_t rawsize, size_t addsize)
{
	void *m;
	struct Atable *t;

	m = kzmalloc(ATABLEBUFSZ + addsize, MEM_WAIT);
	if (m == NULL)
		panic("no memory for more aml tables");
	t = m;
	t->parent = parent;
	t->tbl = NULL;
	if (addsize != 0)
		t->tbl = m + ATABLEBUFSZ;
	t->rawsize = rawsize;
	t->raw = raw;
	strlcpy(t->name, name, sizeof(t->name));
	mkqid(&t->qid,  (lastpath << QIndexShift) + Qdir, 0, QTDIR);
	mkqid(&t->rqid, (lastpath << QIndexShift) + Qraw, 0, 0);
	mkqid(&t->pqid, (lastpath << QIndexShift) + Qpretty, 0, 0);
	mkqid(&t->tqid, (lastpath << QIndexShift) + Qtbl, 0, 0);
	lastpath++;

	return t;
}

struct Atable *finatable(struct Atable *t, struct slice *slice)
{
	size_t n;
	struct Atable *tail;
	struct dirtab *dirs;

	n = slice_len(slice);
	t->nchildren = n;
	t->children = (struct Atable **)slice_finalize(slice);
	dirs = kreallocarray(NULL, n + NQtypes, sizeof(struct dirtab),
	                     MEM_WAIT);
	assert(dirs != NULL);
	dirs[0] = (struct dirtab){ ".",      t->qid,   0, 0555 };
	dirs[1] = (struct dirtab){ "pretty", t->pqid,  0, 0444 };
	dirs[2] = (struct dirtab){ "raw",    t->rqid,  0, 0444 };
	dirs[3] = (struct dirtab){ "table",  t->tqid,  0, 0444 };
	for (size_t i = 0; i < n; i++) {
		strlcpy(dirs[i + NQtypes].name, t->children[i]->name, KNAMELEN);
		dirs[i + NQtypes].qid = t->children[i]->qid;
		dirs[i + NQtypes].length = 0;
		dirs[i + NQtypes].perm = DMDIR | 0555;
	}
	t->cdirs = dirs;
	tail = NULL;
	while (n-- > 0) {
		t->children[n]->next = tail;
		tail = t->children[n];
	}

	return t;
}

struct Atable *finatable_nochildren(struct Atable *t)
{
	return finatable(t, &emptyslice);
}

static char *dumpGas(char *start, char *end, char *prefix, struct Gas *g);
static void dumpxsdt(void);

static char *acpiregstr(int id)
{
	static char buf[20];		/* BUG */

	if (id >= 0 && id < ARRAY_SIZE(regnames))
		return regnames[id];
	seprintf(buf, buf + sizeof(buf), "spc:%#x", id);
	return buf;
}

static int acpiregid(char *s)
{
	for (int i = 0; i < ARRAY_SIZE(regnames); i++)
		if (strcmp(regnames[i], s) == 0)
			return i;
	return -1;
}

/*
 * TODO(rminnich): Fix these if we're ever on a different-endian machine.
 * They are specific to little-endian processors and are not portable.
 */
static uint8_t mget8(uintptr_t p, void *unused)
{
	uint8_t *cp = (uint8_t *) p;
	return *cp;
}

static void mset8(uintptr_t p, uint8_t v, void *unused)
{
	uint8_t *cp = (uint8_t *) p;
	*cp = v;
}

static uint16_t mget16(uintptr_t p, void *unused)
{
	uint16_t *cp = (uint16_t *) p;
	return *cp;
}

static void mset16(uintptr_t p, uint16_t v, void *unused)
{
	uint16_t *cp = (uint16_t *) p;
	*cp = v;
}

static uint32_t mget32(uintptr_t p, void *unused)
{
	uint32_t *cp = (uint32_t *) p;
	return *cp;
}

static void mset32(uintptr_t p, uint32_t v, void *unused)
{
	uint32_t *cp = (uint32_t *) p;
	*cp = v;
}

static uint64_t mget64(uintptr_t p, void *unused)
{
	uint64_t *cp = (uint64_t *) p;
	return *cp;
}

static void mset64(uintptr_t p, uint64_t v, void *unused)
{
	uint64_t *cp = (uint64_t *) p;
	*cp = v;
}

static uint8_t ioget8(uintptr_t p, void *unused)
{
	return inb(p);
}

static void ioset8(uintptr_t p, uint8_t v, void *unused)
{
	outb(p, v);
}

static uint16_t ioget16(uintptr_t p, void *unused)
{
	return inw(p);
}

static void ioset16(uintptr_t p, uint16_t v, void *unused)
{
	outw(p, v);
}

static uint32_t ioget32(uintptr_t p, void *unused)
{
	return inl(p);
}

static void ioset32(uintptr_t p, uint32_t v, void *unused)
{
	outl(p, v);
}

/*
 * TODO(rminnich): these cfgs are hacky. Maybe all the struct Reg should have
 * struct pci_device or something?
 */
static uint8_t cfgget8(uintptr_t p, void *r)
{
	struct Reg *ro = r;
	struct pci_device pcidev;

	explode_tbdf(ro->tbdf);
	return pcidev_read8(&pcidev, p);
}

static void cfgset8(uintptr_t p, uint8_t v, void *r)
{
	struct Reg *ro = r;
	struct pci_device pcidev;

	explode_tbdf(ro->tbdf);
	pcidev_write8(&pcidev, p, v);
}

static uint16_t cfgget16(uintptr_t p, void *r)
{
	struct Reg *ro = r;
	struct pci_device pcidev;

	explode_tbdf(ro->tbdf);
	return pcidev_read16(&pcidev, p);
}

static void cfgset16(uintptr_t p, uint16_t v, void *r)
{
	struct Reg *ro = r;
	struct pci_device pcidev;

	explode_tbdf(ro->tbdf);
	pcidev_write16(&pcidev, p, v);
}

static uint32_t cfgget32(uintptr_t p, void *r)
{
	struct Reg *ro = r;
	struct pci_device pcidev;

	explode_tbdf(ro->tbdf);
	return pcidev_read32(&pcidev, p);
}

static void cfgset32(uintptr_t p, uint32_t v, void *r)
{
	struct Reg *ro = r;
	struct pci_device pcidev;

	explode_tbdf(ro->tbdf);
	pcidev_write32(&pcidev, p, v);
}

static struct Regio memio = {
	NULL,
	mget8, mset8, mget16, mset16,
	mget32, mset32, mget64, mset64
};

static struct Regio ioio = {
	NULL,
	ioget8, ioset8, ioget16, ioset16,
	ioget32, ioset32, NULL, NULL
};

static struct Regio cfgio = {
	NULL,
	cfgget8, cfgset8, cfgget16, cfgset16,
	cfgget32, cfgset32, NULL, NULL
};

/*
 * Copy memory, 1/2/4/8-bytes at a time, to/from a region.
 */
static long
regcpy(struct Regio *dio, uintptr_t da, struct Regio *sio,
	   uintptr_t sa, long len, int align)
{
	int n, i;

	printd("regcpy %#p %#p %#p %#p\n", da, sa, len, align);
	if ((len % align) != 0)
		printd("regcpy: bug: copy not aligned. truncated\n");
	n = len / align;
	for (i = 0; i < n; i++) {
		switch (align) {
			case 1:
				printd("cpy8 %#p %#p\n", da, sa);
				dio->set8(da, sio->get8(sa, sio->arg), dio->arg);
				break;
			case 2:
				printd("cpy16 %#p %#p\n", da, sa);
				dio->set16(da, sio->get16(sa, sio->arg), dio->arg);
				break;
			case 4:
				printd("cpy32 %#p %#p\n", da, sa);
				dio->set32(da, sio->get32(sa, sio->arg), dio->arg);
				break;
			case 8:
				printd("cpy64 %#p %#p\n", da, sa);
				warn("Not doing set64 for some reason, fix me!");
				//  dio->set64(da, sio->get64(sa, sio->arg), dio->arg);
				break;
			default:
				panic("regcpy: align bug");
		}
		da += align;
		sa += align;
	}
	return n * align;
}

/*
 * Perform I/O within region in access units of accsz bytes.
 * All units in bytes.
 */
static long regio(struct Reg *r, void *p, uint32_t len, uintptr_t off, int iswr)
{
	struct Regio rio;
	uintptr_t rp;

	printd("reg%s %s %#p %#p %#lx sz=%d\n",
		   iswr ? "out" : "in", r->name, p, off, len, r->accsz);
	rp = 0;
	if (off + len > r->len) {
		printd("regio: access outside limits");
		len = r->len - off;
	}
	if (len <= 0) {
		printd("regio: zero len\n");
		return 0;
	}
	switch (r->spc) {
		case Rsysmem:
			if (r->p == NULL)
				r->p = KADDR_NOCHECK(r->base);
			if (r->p == NULL)
				error(EFAIL, "regio: vmap/KADDR failed");
			rp = (uintptr_t) r->p + off;
			rio = memio;
			break;
		case Rsysio:
			rp = r->base + off;
			rio = ioio;
			break;
		case Rpcicfg:
			rp = r->base + off;
			rio = cfgio;
			rio.arg = r;
			break;
		case Rpcibar:
		case Rembed:
		case Rsmbus:
		case Rcmos:
		case Ripmi:
		case Rfixedhw:
			printd("regio: reg %s not supported\n", acpiregstr(r->spc));
			error(EFAIL, "region not supported");
	}
	if (iswr)
		regcpy(&rio, rp, &memio, (uintptr_t) p, len, r->accsz);
	else
		regcpy(&memio, (uintptr_t) p, &rio, rp, len, r->accsz);
	return len;
}

/*
 * Compute and return SDT checksum: '0' is a correct sum.
 */
static uint8_t sdtchecksum(void *addr, int len)
{
	uint8_t *p, sum;

	sum = 0;
	for (p = addr; len-- > 0; p++)
		sum += *p;

	return sum;
}

static void *sdtmap(uintptr_t pa, size_t *n, int cksum)
{
	struct Sdthdr *sdt;
	struct Acpilist *p;

	if (!pa) {
		printk("sdtmap: NULL pa\n");
		return NULL;
	}
	sdt = KADDR_NOCHECK(pa);
	if (sdt == NULL) {
		printk("acpi: vmap: NULL\n");
		return NULL;
	}
	*n = l32get(sdt->length);
	if (!*n) {
		printk("sdt has zero length: pa = %p, sig = %.4s\n", pa, sdt->sig);
		return NULL;
	}
	if (cksum != 0 && sdtchecksum(sdt, *n) != 0) {
		printk("acpi: SDT: bad checksum. pa = %p, len = %lu\n", pa, *n);
		return NULL;
	}
	p = kzmalloc(sizeof(struct Acpilist) + *n, MEM_WAIT);
	if (p == NULL)
		panic("sdtmap: memory allocation failed for %lu bytes", *n);
	memmove(p->raw, (void *)sdt, *n);
	p->size = *n;
	p->next = acpilists;
	acpilists = p;

	return p->raw;
}

static int loadfacs(uintptr_t pa)
{
	size_t n;

	facs = sdtmap(pa, &n, 0);
	if (facs == NULL)
		return -1;
	if (memcmp(facs->sig, "FACS", 4) != 0) {
		facs = NULL;
		return -1;
	}

	/* no unmap */
	printd("acpi: facs: hwsig: %#p\n", facs->hwsig);
	printd("acpi: facs: wakingv: %#p\n", facs->wakingv);
	printd("acpi: facs: flags: %#p\n", facs->flags);
	printd("acpi: facs: glock: %#p\n", facs->glock);
	printd("acpi: facs: xwakingv: %#p\n", facs->xwakingv);
	printd("acpi: facs: vers: %#p\n", facs->vers);
	printd("acpi: facs: ospmflags: %#p\n", facs->ospmflags);

	return 0;
}

static void loaddsdt(uintptr_t pa)
{
	size_t n;
	uint8_t *dsdtp;

	dsdtp = sdtmap(pa, &n, 1);
	if (dsdtp == NULL) {
		printk("acpi: Failed to map dsdtp.\n");
		return;
	}
}

static void gasget(struct Gas *gas, uint8_t *p)
{
	gas->spc = p[0];
	gas->len = p[1];
	gas->off = p[2];
	gas->accsz = p[3];
	gas->addr = l64get(p + 4);
}

static char *dumpfadt(char *start, char *end, struct Fadt *fp)
{
	if (fp == NULL)
		return start;

	start = seprintf(start, end, "acpi: FADT@%p\n", fp);
	start = seprintf(start, end, "acpi: fadt: facs: $%p\n", fp->facs);
	start = seprintf(start, end, "acpi: fadt: dsdt: $%p\n", fp->dsdt);
	start = seprintf(start, end, "acpi: fadt: pmprofile: $%p\n", fp->pmprofile);
	start = seprintf(start, end, "acpi: fadt: sciint: $%p\n", fp->sciint);
	start = seprintf(start, end, "acpi: fadt: smicmd: $%p\n", fp->smicmd);
	start =
		seprintf(start, end, "acpi: fadt: acpienable: $%p\n", fp->acpienable);
	start =
		seprintf(start, end, "acpi: fadt: acpidisable: $%p\n", fp->acpidisable);
	start = seprintf(start, end, "acpi: fadt: s4biosreq: $%p\n", fp->s4biosreq);
	start = seprintf(start, end, "acpi: fadt: pstatecnt: $%p\n", fp->pstatecnt);
	start =
		seprintf(start, end, "acpi: fadt: pm1aevtblk: $%p\n", fp->pm1aevtblk);
	start =
		seprintf(start, end, "acpi: fadt: pm1bevtblk: $%p\n", fp->pm1bevtblk);
	start =
		seprintf(start, end, "acpi: fadt: pm1acntblk: $%p\n", fp->pm1acntblk);
	start =
		seprintf(start, end, "acpi: fadt: pm1bcntblk: $%p\n", fp->pm1bcntblk);
	start = seprintf(start, end, "acpi: fadt: pm2cntblk: $%p\n", fp->pm2cntblk);
	start = seprintf(start, end, "acpi: fadt: pmtmrblk: $%p\n", fp->pmtmrblk);
	start = seprintf(start, end, "acpi: fadt: gpe0blk: $%p\n", fp->gpe0blk);
	start = seprintf(start, end, "acpi: fadt: gpe1blk: $%p\n", fp->gpe1blk);
	start = seprintf(start, end, "acpi: fadt: pm1evtlen: $%p\n", fp->pm1evtlen);
	start = seprintf(start, end, "acpi: fadt: pm1cntlen: $%p\n", fp->pm1cntlen);
	start = seprintf(start, end, "acpi: fadt: pm2cntlen: $%p\n", fp->pm2cntlen);
	start = seprintf(start, end, "acpi: fadt: pmtmrlen: $%p\n", fp->pmtmrlen);
	start =
		seprintf(start, end, "acpi: fadt: gpe0blklen: $%p\n", fp->gpe0blklen);
	start =
		seprintf(start, end, "acpi: fadt: gpe1blklen: $%p\n", fp->gpe1blklen);
	start = seprintf(start, end, "acpi: fadt: gp1base: $%p\n", fp->gp1base);
	start = seprintf(start, end, "acpi: fadt: cstcnt: $%p\n", fp->cstcnt);
	start = seprintf(start, end, "acpi: fadt: plvl2lat: $%p\n", fp->plvl2lat);
	start = seprintf(start, end, "acpi: fadt: plvl3lat: $%p\n", fp->plvl3lat);
	start = seprintf(start, end, "acpi: fadt: flushsz: $%p\n", fp->flushsz);
	start =
		seprintf(start, end, "acpi: fadt: flushstride: $%p\n", fp->flushstride);
	start = seprintf(start, end, "acpi: fadt: dutyoff: $%p\n", fp->dutyoff);
	start = seprintf(start, end, "acpi: fadt: dutywidth: $%p\n", fp->dutywidth);
	start = seprintf(start, end, "acpi: fadt: dayalrm: $%p\n", fp->dayalrm);
	start = seprintf(start, end, "acpi: fadt: monalrm: $%p\n", fp->monalrm);
	start = seprintf(start, end, "acpi: fadt: century: $%p\n", fp->century);
	start =
		seprintf(start, end, "acpi: fadt: iapcbootarch: $%p\n",
				 fp->iapcbootarch);
	start = seprintf(start, end, "acpi: fadt: flags: $%p\n", fp->flags);
	start = dumpGas(start, end, "acpi: fadt: resetreg: ", &fp->resetreg);
	start = seprintf(start, end, "acpi: fadt: resetval: $%p\n", fp->resetval);
	start = seprintf(start, end, "acpi: fadt: xfacs: %p\n", fp->xfacs);
	start = seprintf(start, end, "acpi: fadt: xdsdt: %p\n", fp->xdsdt);
	start = dumpGas(start, end, "acpi: fadt: xpm1aevtblk:", &fp->xpm1aevtblk);
	start = dumpGas(start, end, "acpi: fadt: xpm1bevtblk:", &fp->xpm1bevtblk);
	start = dumpGas(start, end, "acpi: fadt: xpm1acntblk:", &fp->xpm1acntblk);
	start = dumpGas(start, end, "acpi: fadt: xpm1bcntblk:", &fp->xpm1bcntblk);
	start = dumpGas(start, end, "acpi: fadt: xpm2cntblk:", &fp->xpm2cntblk);
	start = dumpGas(start, end, "acpi: fadt: xpmtmrblk:", &fp->xpmtmrblk);
	start = dumpGas(start, end, "acpi: fadt: xgpe0blk:", &fp->xgpe0blk);
	start = dumpGas(start, end, "acpi: fadt: xgpe1blk:", &fp->xgpe1blk);
	return start;
}

static struct Atable *parsefadt(struct Atable *parent,
								char *name, uint8_t *p, size_t rawsize)
{
	struct Atable *t;
	struct Fadt *fp;

	t = mkatable(parent, FADT, name, p, rawsize, sizeof(struct Fadt));

	if (rawsize < 116) {
		printk("ACPI: unusually short FADT, aborting!\n");
		return t;
	}
	/* for now, keep the globals. We'll get rid of them later. */
	fp = t->tbl;
	fadt = fp;
	fp->facs = l32get(p + 36);
	fp->dsdt = l32get(p + 40);
	fp->pmprofile = p[45];
	fp->sciint = l16get(p + 46);
	fp->smicmd = l32get(p + 48);
	fp->acpienable = p[52];
	fp->acpidisable = p[53];
	fp->s4biosreq = p[54];
	fp->pstatecnt = p[55];
	fp->pm1aevtblk = l32get(p + 56);
	fp->pm1bevtblk = l32get(p + 60);
	fp->pm1acntblk = l32get(p + 64);
	fp->pm1bcntblk = l32get(p + 68);
	fp->pm2cntblk = l32get(p + 72);
	fp->pmtmrblk = l32get(p + 76);
	fp->gpe0blk = l32get(p + 80);
	fp->gpe1blk = l32get(p + 84);
	fp->pm1evtlen = p[88];
	fp->pm1cntlen = p[89];
	fp->pm2cntlen = p[90];
	fp->pmtmrlen = p[91];
	fp->gpe0blklen = p[92];
	fp->gpe1blklen = p[93];
	fp->gp1base = p[94];
	fp->cstcnt = p[95];
	fp->plvl2lat = l16get(p + 96);
	fp->plvl3lat = l16get(p + 98);
	fp->flushsz = l16get(p + 100);
	fp->flushstride = l16get(p + 102);
	fp->dutyoff = p[104];
	fp->dutywidth = p[105];
	fp->dayalrm = p[106];
	fp->monalrm = p[107];
	fp->century = p[108];
	fp->iapcbootarch = l16get(p + 109);
	fp->flags = l32get(p + 112);

	/*
	 * qemu gives us a 116 byte fadt, though i haven't seen any HW do that.
	 * The right way to do this is to realloc the table and fake it out.
	 */
	if (rawsize < 244)
		return finatable_nochildren(t);

	gasget(&fp->resetreg, p + 116);
	fp->resetval = p[128];
	fp->xfacs = l64get(p + 132);
	fp->xdsdt = l64get(p + 140);
	gasget(&fp->xpm1aevtblk, p + 148);
	gasget(&fp->xpm1bevtblk, p + 160);
	gasget(&fp->xpm1acntblk, p + 172);
	gasget(&fp->xpm1bcntblk, p + 184);
	gasget(&fp->xpm2cntblk, p + 196);
	gasget(&fp->xpmtmrblk, p + 208);
	gasget(&fp->xgpe0blk, p + 220);
	gasget(&fp->xgpe1blk, p + 232);

	if (fp->xfacs != 0)
		loadfacs(fp->xfacs);
	else
		loadfacs(fp->facs);

	if (fp->xdsdt == (uint64_t)fp->dsdt)	/* acpica */
		loaddsdt(fp->xdsdt);
	else
		loaddsdt(fp->dsdt);

	return finatable_nochildren(t);
}

static char *dumpmsct(char *start, char *end, struct Atable *table)
{
	struct Msct *msct;

	if (!table)
		return start;

	msct = table->tbl;
	if (!msct)
		return start;

	start = seprintf(start, end, "acpi: msct: %d doms %d clkdoms %#p maxpa\n",
					 msct->ndoms, msct->nclkdoms, msct->maxpa);
	for (int i = 0; i < table->nchildren; i++) {
		struct Atable *domtbl = table->children[i]->tbl;
		struct Mdom *st = domtbl->tbl;

		start = seprintf(start, end, "\t[%d:%d] %d maxproc %#p maxmmem\n",
						 st->start, st->end, st->maxproc, st->maxmem);
	}
	start = seprintf(start, end, "\n");

	return start;
}

/*
 * XXX: should perhaps update our idea of available memory.
 * Else we should remove this code.
 */
static struct Atable *parsemsct(struct Atable *parent,
                                char *name, uint8_t *raw, size_t rawsize)
{
	struct Atable *t;
	uint8_t *r, *re;
	struct Msct *msct;
	struct Mdom **stl, *st;
	size_t off, nmdom;
	int i;

	re = raw + rawsize;
	off = l32get(raw + 36);
	nmdom = 0;
	for (r = raw + off, re = raw + rawsize; r < re; r += 22)
		nmdom++;
	t = mkatable(parent, MSCT, name, raw, rawsize,
	             sizeof(struct Msct) + nmdom * sizeof(struct Mdom));
	msct = t->tbl;
	msct->ndoms = l32get(raw + 40) + 1;
	msct->nclkdoms = l32get(raw + 44) + 1;
	msct->maxpa = l64get(raw + 48);
	msct->nmdom = nmdom;
	msct->dom = NULL;
	if (nmdom != 0)
		msct->dom = (void *)msct + sizeof(struct Msct);
	for (i = 0, r = raw; i < nmdom; i++, r += 22) {
		msct->dom[i].start = l32get(r + 2);
		msct->dom[i].end = l32get(r + 6);
		msct->dom[i].maxproc = l32get(r + 10);
		msct->dom[i].maxmem = l64get(r + 14);
	}
	mscttbl = finatable_nochildren(t);

	return mscttbl;
}

/* TODO(rminnich): only handles on IOMMU for now. */
static char *dumpdmar(char *start, char *end, struct Atable *dmar)
{
	struct Dmar *dt;

	if (dmar == NULL)
		return start;

	dt = dmar->tbl;
	start = seprintf(start, end, "acpi: DMAR addr %p:\n", dt);
	start = seprintf(start, end, "\tdmar: intr_remap %d haw %d\n",
	                 dt->intr_remap, dt->haw);
	for (int i = 0; i < dmar->nchildren; i++) {
		struct Atable *at = dmar->children[i];
		struct Drhd *drhd = at->tbl;

		start = seprintf(start, end, "\tDRHD: ");
		start = seprintf(start, end, "%s 0x%02x 0x%016x\n",
		                 drhd->all & 1 ? "INCLUDE_PCI_ALL" : "Scoped",
		                 drhd->segment, drhd->rba);
	}

	return start;
}

static char *dumpsrat(char *start, char *end, struct Atable *table)
{
	if (table == NULL)
		return seprintf(start, end, "NO SRAT\n");
	start = seprintf(start, end, "acpi: SRAT@%p:\n", table->tbl);
	for (; table != NULL; table = table->next) {
		struct Srat *st = table->tbl;

		if (st == NULL)
			continue;
		switch (st->type) {
			case SRlapic:
				start =
					seprintf(start, end,
							 "\tlapic: dom %d apic %d sapic %d clk %d\n",
							 st->lapic.dom, st->lapic.apic, st->lapic.sapic,
							 st->lapic.clkdom);
				break;
			case SRmem:
				start = seprintf(start, end, "\tmem: dom %d %#p %#p %c%c\n",
								 st->mem.dom, st->mem.addr, st->mem.len,
								 st->mem.hplug ? 'h' : '-',
								 st->mem.nvram ? 'n' : '-');
				break;
			case SRlx2apic:
				start =
					seprintf(start, end, "\tlx2apic: dom %d apic %d clk %d\n",
							 st->lx2apic.dom, st->lx2apic.apic,
							 st->lx2apic.clkdom);
				break;
			default:
				start = seprintf(start, end, "\t<unknown srat entry>\n");
		}
	}
	start = seprintf(start, end, "\n");
	return start;
}

static struct Atable *parsesrat(struct Atable *parent,
                                char *name, uint8_t *p, size_t rawsize)
{

	struct Atable *t, *tt, *tail;
	uint8_t *pe;
	int stlen, flags;
	struct slice slice;
	char buf[16];
	int i;
	struct Srat *st;

	/* TODO: Parse the second SRAT */
	if (srat != NULL) {
		warn("Multiple SRATs detected and ignored!");
		return NULL;
	}

	t = mkatable(parent, SRAT, name, p, rawsize, 0);
	slice_init(&slice);
	pe = p + rawsize;
	for (p += 48, i = 0; p < pe; p += stlen, i++) {
		snprintf(buf, sizeof(buf), "%d", i);
		stlen = p[1];
		tt = mkatable(t, SRAT, buf, p, stlen, sizeof(struct Srat));
		st = tt->tbl;
		st->type = p[0];
		switch (st->type) {
			case SRlapic:
				st->lapic.dom = p[2] | p[9] << 24 | p[10] << 16 | p[11] << 8;
				st->lapic.apic = p[3];
				st->lapic.sapic = p[8];
				st->lapic.clkdom = l32get(p + 12);
				if (l32get(p + 4) == 0) {
					kfree(tt);
					tt = NULL;
				}
				break;
			case SRmem:
				st->mem.dom = l32get(p + 2);
				st->mem.addr = l64get(p + 8);
				st->mem.len = l64get(p + 16);
				flags = l32get(p + 28);
				if ((flags & 1) == 0) {	/* not enabled */
					kfree(tt);
					tt = NULL;
				} else {
					st->mem.hplug = flags & 2;
					st->mem.nvram = flags & 4;
				}
				break;
			case SRlx2apic:
				st->lx2apic.dom = l32get(p + 4);
				st->lx2apic.apic = l32get(p + 8);
				st->lx2apic.clkdom = l32get(p + 16);
				if (l32get(p + 12) == 0) {
					kfree(tt);
					tt = NULL;
				}
				break;
			default:
				printd("unknown SRAT structure\n");
				kfree(tt);
				tt = NULL;
				break;
		}
		if (tt != NULL) {
			finatable_nochildren(tt);
			slice_append(&slice, tt);
		}
	}
	srat = finatable(t, &slice);

	return srat;
}

static char *dumpslit(char *start, char *end, struct Slit *sl)
{
	int i;

	if (sl == NULL)
		return start;
	start = seprintf(start, end, "acpi slit:\n");
	for (i = 0; i < sl->rowlen * sl->rowlen; i++) {
		start = seprintf(start, end,
						 "slit: %ux\n",
						 sl->e[i / sl->rowlen][i % sl->rowlen].dist);
	}
	start = seprintf(start, end, "\n");
	return start;
}

static int cmpslitent(void *v1, void *v2)
{
	struct SlEntry *se1, *se2;

	se1 = v1;
	se2 = v2;
	return se1->dist - se2->dist;
}

static struct Atable *parseslit(struct Atable *parent,
                                char *name, uint8_t *raw, size_t rawsize)
{
	struct Atable *t;
	uint8_t *r, *re;
	int i, j, k;
	struct SlEntry *se;
	size_t addsize, rowlen;
	void *p;

	addsize = sizeof(*slit);
	rowlen = l64get(raw + 36);
	addsize += rowlen * sizeof(struct SlEntry *);
	addsize += sizeof(struct SlEntry) * rowlen * rowlen;

	t = mkatable(parent, SLIT, name, raw, rawsize, addsize);
	slit = t->tbl;
	slit->rowlen = rowlen;
	p = (void *)slit + sizeof(*slit);
	slit->e = p;
	p += rowlen * sizeof(struct SlEntry *);
	for (i = 0; i < rowlen; i++) {
		slit->e[i] = p;
		p += sizeof(struct SlEntry) * rowlen;
	}
	for (i = 0, r = raw + 44, re = raw + rawsize; r < re; r++, i++) {
		int j = i / rowlen;
		int k = i % rowlen;

		se = &slit->e[j][k];
		se->dom = k;
		se->dist = *r;
	}

#if 0
	/* TODO: might need to sort this shit */
	for (i = 0; i < slit->rowlen; i++)
		qsort(slit->e[i], slit->rowlen, sizeof(slit->e[0][0]), cmpslitent);
#endif

	return finatable_nochildren(t);
}

int pickcore(int mycolor, int index)
{
	int color;
	int ncorepercol;

	if (slit == NULL)
		return 0;
	ncorepercol = num_cores / slit->rowlen;
	color = slit->e[mycolor][index / ncorepercol].dom;
	return color * ncorepercol + index % ncorepercol;
}

static char *polarity[4] = {
	"polarity/trigger like in ISA",
	"active high",
	"BOGUS POLARITY",
	"active low"
};

static char *trigger[] = {
	"BOGUS TRIGGER",
	"edge",
	"BOGUS TRIGGER",
	"level"
};

static char *printiflags(char *start, char *end, int flags)
{

	return seprintf(start, end, "[%s,%s]",
					polarity[flags & AFpmask], trigger[(flags & AFtmask) >> 2]);
}

static char *dumpmadt(char *start, char *end, struct Atable *apics)
{
	struct Madt *mt;

	if (apics == NULL)
		return start;

	mt = apics->tbl;
	if (mt == NULL)
		return seprintf(start, end, "acpi: no MADT");
	start = seprintf(start, end, "acpi: MADT@%p: lapic paddr %p pcat %d:\n",
	                 mt, mt->lapicpa, mt->pcat);
	for (int i = 0; i < apics->nchildren; i++) {
		struct Atable *apic = apics->children[i];
		struct Apicst *st = apic->tbl;

		switch (st->type) {
			case ASlapic:
				start =
					seprintf(start, end, "\tlapic pid %d id %d\n",
							 st->lapic.pid, st->lapic.id);
				break;
			case ASioapic:
			case ASiosapic:
				start =
					seprintf(start, end,
							 "\tioapic id %d addr %p ibase %d\n",
							 st->ioapic.id, st->ioapic.addr, st->ioapic.ibase);
				break;
			case ASintovr:
				start =
					seprintf(start, end, "\tintovr irq %d intr %d flags $%p",
							 st->intovr.irq, st->intovr.intr, st->intovr.flags);
				start = printiflags(start, end, st->intovr.flags);
				start = seprintf(start, end, "\n");
				break;
			case ASnmi:
				start = seprintf(start, end, "\tnmi intr %d flags $%p\n",
								 st->nmi.intr, st->nmi.flags);
				break;
			case ASlnmi:
				start =
					seprintf(start, end, "\tlnmi pid %d lint %d flags $%p\n",
							 st->lnmi.pid, st->lnmi.lint, st->lnmi.flags);
				break;
			case ASlsapic:
				start =
					seprintf(start, end,
							 "\tlsapic pid %d id %d eid %d puid %d puids %s\n",
							 st->lsapic.pid, st->lsapic.id, st->lsapic.eid,
							 st->lsapic.puid, st->lsapic.puids);
				break;
			case ASintsrc:
				start =
					seprintf(start, end,
							 "\tintr type %d pid %d peid %d iosv %d intr %d %#x\n",
							 st->type, st->intsrc.pid, st->intsrc.peid,
							 st->intsrc.iosv, st->intsrc.intr,
							 st->intsrc.flags);
				start = printiflags(start, end, st->intsrc.flags);
				start = seprintf(start, end, "\n");
				break;
			case ASlx2apic:
				start =
					seprintf(start, end, "\tlx2apic puid %d id %d\n",
							 st->lx2apic.puid, st->lx2apic.id);
				break;
			case ASlx2nmi:
				start =
					seprintf(start, end, "\tlx2nmi puid %d intr %d flags $%p\n",
							 st->lx2nmi.puid, st->lx2nmi.intr,
							 st->lx2nmi.flags);
				break;
			default:
				start = seprintf(start, end, "\t<unknown madt entry>\n");
		}
	}
	start = seprintf(start, end, "\n");
	return start;
}

static struct Atable *parsemadt(struct Atable *parent,
                                char *name, uint8_t *p, size_t size)
{
	struct Atable *t, *tt, *tail;
	uint8_t *pe;
	struct Madt *mt;
	struct Apicst *st, *l;
	int id;
	size_t stlen;
	char buf[16];
	int i;
	struct slice slice;

	slice_init(&slice);
	t = mkatable(parent, MADT, name, p, size, sizeof(struct Madt));
	mt = t->tbl;
	mt->lapicpa = l32get(p + 36);
	mt->pcat = l32get(p + 40);
	pe = p + size;
	for (p += 44, i = 0; p < pe; p += stlen, i++) {
		snprintf(buf, sizeof(buf), "%d", i);
		stlen = p[1];
		tt = mkatable(t, APIC, buf, p, stlen, sizeof(struct Apicst));
		st = tt->tbl;
		st->type = p[0];
		switch (st->type) {
			case ASlapic:
				st->lapic.pid = p[2];
				st->lapic.id = p[3];
				if (l32get(p + 4) == 0) {
					kfree(tt);
					tt = NULL;
				}
				break;
			case ASioapic:
				st->ioapic.id = id = p[2];
				st->ioapic.addr = l32get(p + 4);
				st->ioapic.ibase = l32get(p + 8);
				/* ioapic overrides any ioapic entry for the same id */
				for (int i = 0; i < slice_len(&slice); i++) {
					l = ((struct Atable *)slice_get(&slice, i))->tbl;
					if (l->type == ASiosapic && l->iosapic.id == id) {
						st->ioapic = l->iosapic;
						/* we leave it linked; could be removed */
						break;
					}
				}
				break;
			case ASintovr:
				st->intovr.irq = p[3];
				st->intovr.intr = l32get(p + 4);
				st->intovr.flags = l16get(p + 8);
				break;
			case ASnmi:
				st->nmi.flags = l16get(p + 2);
				st->nmi.intr = l32get(p + 4);
				break;
			case ASlnmi:
				st->lnmi.pid = p[2];
				st->lnmi.flags = l16get(p + 3);
				st->lnmi.lint = p[5];
				break;
			case ASladdr:
				/* This is for 64 bits, perhaps we should not
				 * honor it on 32 bits.
				 */
				mt->lapicpa = l64get(p + 8);
				break;
			case ASiosapic:
				id = st->iosapic.id = p[2];
				st->iosapic.ibase = l32get(p + 4);
				st->iosapic.addr = l64get(p + 8);
				/* iosapic overrides any ioapic entry for the same id */
				for (int i = 0; i < slice_len(&slice); i++) {
					l = ((struct Atable*)slice_get(&slice, i))->tbl;
					if (l->type == ASioapic && l->ioapic.id == id) {
						l->ioapic = st->iosapic;
						kfree(tt);
						tt = NULL;
						break;
					}
				}
				break;
			case ASlsapic:
				st->lsapic.pid = p[2];
				st->lsapic.id = p[3];
				st->lsapic.eid = p[4];
				st->lsapic.puid = l32get(p + 12);
				if (l32get(p + 8) == 0) {
					kfree(tt);
					tt = NULL;
				} else
					kstrdup(&st->lsapic.puids, (char *)p + 16);
				break;
			case ASintsrc:
				st->intsrc.flags = l16get(p + 2);
				st->type = p[4];
				st->intsrc.pid = p[5];
				st->intsrc.peid = p[6];
				st->intsrc.iosv = p[7];
				st->intsrc.intr = l32get(p + 8);
				st->intsrc.any = l32get(p + 12);
				break;
			case ASlx2apic:
				st->lx2apic.id = l32get(p + 4);
				st->lx2apic.puid = l32get(p + 12);
				if (l32get(p + 8) == 0) {
					kfree(tt);
					tt = NULL;
				}
				break;
			case ASlx2nmi:
				st->lx2nmi.flags = l16get(p + 2);
				st->lx2nmi.puid = l32get(p + 4);
				st->lx2nmi.intr = p[8];
				break;
			default:
				printd("unknown APIC structure\n");
				kfree(tt);
				tt = NULL;
		}
		if (tt != NULL) {
			finatable_nochildren(tt);
			slice_append(&slice, tt);
		}
	}
	apics = finatable(t, &slice);

	return apics;
}

static struct Atable *parsedmar(struct Atable *parent,
                                char *name, uint8_t *raw, size_t rawsize)
{
	struct Atable *t, *tt;
	int i;
	int baselen = MIN(rawsize, 38);
	int nentry, nscope, npath, off, dslen, dhlen, len, type, flags;
	void *pathp;
	char buf[16];
	struct slice drhds;
	struct Drhd *drhd;
	struct Dmar *dt;

	/* count the entries */
	for (nentry = 0, off = 48; off < rawsize; nentry++) {
		dslen = l16get(raw + off + 2);
		printk("acpi DMAR: entry %d is addr %p (0x%x/0x%x)\n",
		       nentry, raw + off, l16get(raw + off), dslen);
		off = off + dslen;
	}
	printk("DMAR: %d entries\n", nentry);

	t = mkatable(parent, DMAR, name, raw, rawsize, sizeof(*dmar));
	dt = t->tbl;
	/* The table can be only partly filled. */
	if (baselen >= 38 && raw[37] & 1)
		dt->intr_remap = 1;
	if (baselen >= 37)
		dt->haw = raw[36] + 1;

	/* Now we walk all the DMAR entries. */
	slice_init(&drhds);
	for (off = 48, i = 0; i < nentry; i++, off += dslen) {
		snprintf(buf, sizeof(buf), "%d", i);
		dslen = l16get(raw + off + 2);
		type = l16get(raw + off);
		// TODO(dcross): Introduce sensible symbolic constants
		// for DMAR entry types. For right now, type 0 => DRHD.
		// We skip everything else.
		if (type != 0)
			continue;
		npath = 0;
		nscope = 0;
		for (int o = off + 16; o < (off + dslen); o += dhlen) {
			nscope++;
			dhlen = *(raw + o + 1);	// Single byte length.
			npath += ((dhlen - 6) / 2);
		}
		tt = mkatable(t, DRHD, buf, raw + off, dslen,
		              sizeof(struct Drhd) + 2 * npath +
		              nscope * sizeof(struct DevScope));
		flags = *(raw + off + 4);
		drhd = tt->tbl;
		drhd->all = flags & 1;
		drhd->segment = l16get(raw + off + 6);
		drhd->rba = l64get(raw + off + 8);
		drhd->nscope = nscope;
		drhd->scopes = (void *)drhd + sizeof(struct Drhd);
		pathp = (void *)drhd +
		    sizeof(struct Drhd) + nscope * sizeof(struct DevScope);
		for (int i = 0, o = off + 16; i < nscope; i++) {
			struct DevScope *ds = &drhd->scopes[i];

			dhlen = *(raw + o + 1);
			ds->enumeration_id = *(raw + o + 4);
			ds->start_bus_number = *(raw + o + 5);
			ds->npath = (dhlen - 6) / 2;
			ds->paths = pathp;
			for (int j = 0; j < ds->npath; j++)
				ds->paths[j] = l16get(raw + o + 6 + 2*j);
			pathp += 2*ds->npath;
			o += dhlen;
		}
		/*
		 * NOTE: if all is set, there should be no scopes of type
		 * This being ACPI, where vendors randomly copy tables
		 * from one system to another, and creating breakage,
		 * anything is possible. But we'll warn them.
		 */
		finatable_nochildren(tt);
		slice_append(&drhds, tt);
	}
	dmar = finatable(t, &drhds);

	return dmar;
}

/*
 * Map the table and keep it there.
 */
static struct Atable *parsessdt(struct Atable *parent,
                                char *name, uint8_t *raw, size_t size)
{
	struct Atable *t;
	struct Sdthdr *h;

	/*
	 * We found it and it is too small.
	 * Simply return with no side effect.
	 */
	if (size < Sdthdrsz)
		return NULL;
	t = mkatable(parent, SSDT, name, raw, size, 0);
	h = (struct Sdthdr *)raw;
	memmove(t->name, h->sig, sizeof(h->sig));
	t->name[sizeof(h->sig)] = '\0';

	return finatable_nochildren(t);
}

static char *dumptable(char *start, char *end, char *sig, uint8_t *p, int l)
{
	int n, i;

	if (2 > 1) {
		start = seprintf(start, end, "%s @ %#p\n", sig, p);
		if (2 > 2)
			n = l;
		else
			n = 256;
		for (i = 0; i < n; i++) {
			if ((i % 16) == 0)
				start = seprintf(start, end, "%x: ", i);
			start = seprintf(start, end, " %2.2ux", p[i]);
			if ((i % 16) == 15)
				start = seprintf(start, end, "\n");
		}
		start = seprintf(start, end, "\n");
		start = seprintf(start, end, "\n");
	}
	return start;
}

static char *seprinttable(char *s, char *e, struct Atable *t)
{
	uint8_t *p;
	int i, n;

	p = (uint8_t *)t->tbl;	/* include header */
	n = t->rawsize;
	s = seprintf(s, e, "%s @ %#p\n", t->name, p);
	for (i = 0; i < n; i++) {
		if ((i % 16) == 0)
			s = seprintf(s, e, "%x: ", i);
		s = seprintf(s, e, " %2.2ux", p[i]);
		if ((i % 16) == 15)
			s = seprintf(s, e, "\n");
	}
	return seprintf(s, e, "\n\n");
}

static void *rsdsearch(char *signature)
{
	uintptr_t p;
	uint8_t *bda;
	void *rsd;

	/*
	 * Search for the data structure signature:
	 * 1) in the BIOS ROM between 0xE0000 and 0xFFFFF.
	 */
	return sigscan(KADDR_NOCHECK(0xE0000), 0x20000, signature);
}

/*
 * Note: some of this comment is from the unfinished user interpreter.
 *
 * The DSDT is always given to the user interpreter.
 * Tables listed here are also loaded from the XSDT:
 * MSCT, MADT, and FADT are processed by us, because they are
 * required to do early initialization before we have user processes.
 * Other tables are given to the user level interpreter for
 * execution.
 *
 * These historically returned a value to tell acpi whether or not it was okay
 * to unmap the table.  (return 0 means there was no table, meaning it was okay
 * to unmap).  We just use the kernbase mapping, so it's irrelevant.
 *
 * N.B. The intel source code defines the constants for ACPI in a
 * non-endian-independent manner. Rather than bring in the huge wad o' code
 * that represents, we just the names.
 */
struct Parser {
	char *sig;
	struct Atable *(*parse)(struct Atable *parent,
	                        char *name, uint8_t *raw, size_t rawsize);
};


static struct Parser ptable[] = {
	{"FACP", parsefadt},
	{"APIC", parsemadt},
	{"DMAR", parsedmar},
	{"SRAT", parsesrat},
	{"SLIT", parseslit},
	{"MSCT", parsemsct},
	{"SSDT", parsessdt},
	{"HPET", parsehpet},
};

/*
 * process xsdt table and load tables with sig, or all if NULL.
 * (XXX: should be able to search for sig, oemid, oemtblid)
 */
static void parsexsdt(struct Atable *root)
{
	ERRSTACK(1);
	struct Sdthdr *sdt;
	struct Atable *table;
	struct slice slice;
	size_t l, end;
	uintptr_t dhpa;
	struct Atable *n;
	uint8_t *tbl;

	slice_init(&slice);
	if (waserror()) {
		slice_destroy(&slice);
		return;
	}

	tbl = xsdt->p + sizeof(struct Sdthdr);
	end = xsdt->len - sizeof(struct Sdthdr);
	for (int i = 0; i < end; i += xsdt->asize) {
		dhpa = (xsdt->asize == 8) ? l64get(tbl + i) : l32get(tbl + i);
		sdt = sdtmap(dhpa, &l, 1);
		if (sdt == NULL)
			continue;
		printd("acpi: %s addr %#p\n", tsig, sdt);
		for (int j = 0; j < ARRAY_SIZE(ptable); j++) {
			if (memcmp(sdt->sig, ptable[j].sig, sizeof(sdt->sig)) == 0) {
				table = ptable[j].parse(root, ptable[j].sig, (void *)sdt, l);
				if (table != NULL)
					slice_append(&slice, table);
				break;
			}
		}
	}
	finatable(root, &slice);
}

void makeindex(struct Atable *root)
{
	uint64_t index;

	if (root == NULL)
		return;
	index = root->qid.path >> QIndexShift;
	atableindex[index] = root;
	for (int k = 0; k < root->nchildren; k++)
		makeindex(root->children[k]);
}

static void parsersdptr(void)
{
	struct Rsdp *rsd;
	int asize, cksum;
	uintptr_t sdtpa;

	static_assert(sizeof(struct Sdthdr) == 36);

	/* Find the root pointer. */
	rsd = rsdsearch("RSD PTR ");
	if (rsd == NULL) {
		printk("NO RSDP\n");
		return;
	}

	/*
	 * Initialize the root of ACPI parse tree.
	 */
	lastpath = Qroot;
	root = mkatable(NULL, XSDT, devname(), NULL, 0, sizeof(struct Xsdt));
	root->parent = root;

	printd("/* RSDP */ struct Rsdp = {%08c, %x, %06c, %x, %p, %d, %p, %x}\n",
		   rsd->signature, rsd->rchecksum, rsd->oemid, rsd->revision,
		   *(uint32_t *)rsd->raddr, *(uint32_t *)rsd->length,
		   *(uint32_t *)rsd->xaddr, rsd->xchecksum);

	printd("acpi: RSD PTR@ %#p, physaddr $%p length %ud %#llux rev %d\n",
		   rsd, l32get(rsd->raddr), l32get(rsd->length),
		   l64get(rsd->xaddr), rsd->revision);

	if (rsd->revision >= 2) {
		cksum = sdtchecksum(rsd, 36);
		if (cksum != 0) {
			printk("acpi: bad RSD checksum %d, 64 bit parser aborted\n", cksum);
			return;
		}
		sdtpa = l64get(rsd->xaddr);
		asize = 8;
	} else {
		cksum = sdtchecksum(rsd, 20);
		if (cksum != 0) {
			printk("acpi: bad RSD checksum %d, 32 bit parser aborted\n", cksum);
			return;
		}
		sdtpa = l32get(rsd->raddr);
		asize = 4;
	}

	/*
	 * process the RSDT or XSDT table.
	 */
	xsdt = root->tbl;
	xsdt->p = sdtmap(sdtpa, &xsdt->len, 1);
	if (xsdt->p == NULL) {
		printk("acpi: sdtmap failed\n");
		return;
	}
	if ((xsdt->p[0] != 'R' && xsdt->p[0] != 'X')
		|| memcmp(xsdt->p + 1, "SDT", 3) != 0) {
		printd("acpi: xsdt sig: %c%c%c%c\n",
		       xsdt->p[0], xsdt->p[1], xsdt->p[2], xsdt->p[3]);
		xsdt = NULL;
		return;
	}
	xsdt->asize = asize;
	printd("acpi: XSDT %#p\n", xsdt);
	parsexsdt(root);
	atableindex = kreallocarray(NULL, lastpath, sizeof(struct Atable *),
	                            MEM_WAIT);
	assert(atableindex != NULL);
	makeindex(root);
}

/* Given an xsdt, find the table matching 'sig', if any. */
static struct Sdthdr *xsdt_find_tbl(struct Sdthdr *xsdt, const char *sig,
                                    int addr_size)
{
	uint8_t *ptr_tbl;
	size_t ptr_tbl_len;
	physaddr_t sdt_pa;
	struct Sdthdr *sdt;

	ptr_tbl = (uint8_t*)xsdt + sizeof(struct Sdthdr);
	ptr_tbl_len = l32get(xsdt->length) - sizeof(struct Sdthdr);
	for (int i = 0; i < ptr_tbl_len; i += addr_size) {
		sdt_pa = (addr_size == 8) ? l64get(ptr_tbl + i) : l32get(ptr_tbl + i);
		sdt = KADDR_NOCHECK(sdt_pa);
		if (memcmp(sdt->sig, sig, sizeof(sdt->sig)) == 0)
			return sdt;
	}
	return NULL;
}

/* This may be an overestimate, if some LAPICS are present but disabled */
static int madt_get_nr_cores(struct Sdthdr *madt)
{
	uint8_t *p, *madt_end;
	size_t entry_len;
	int nr_cores = 0;

	p = (uint8_t*)madt;
	madt_end = p + l32get(madt->length);
	for (p += 44; p < madt_end; p += entry_len) {
		entry_len = p[1];
		switch (p[0]) {
		case ASlapic:
			nr_cores++;
			break;
		default:
			break;
		}
	}
	return nr_cores;
}

int get_early_num_cores(void)
{
	struct Rsdp *rsd;
	int asize;
	physaddr_t sdtpa;
	struct Sdthdr *xsdt, *madt;
	uint8_t *xsdt_buf;
	int nr_cores;

	rsd = rsdsearch("RSD PTR ");
	assert(rsd);
	if (rsd->revision >= 2) {
		sdtpa = l64get(rsd->xaddr);
		asize = 8;
	} else {
		sdtpa = l32get(rsd->raddr);
		asize = 4;
	}

	xsdt = KADDR_NOCHECK(sdtpa);
	xsdt_buf = (uint8_t*)xsdt;
	if ((xsdt_buf[0] != 'R' && xsdt_buf[0] != 'X')
		|| memcmp(xsdt_buf + 1, "SDT", 3) != 0) {
		panic("acpi: xsdt sig: %c%c%c%c\n",
		       xsdt_buf[0], xsdt_buf[1], xsdt_buf[2], xsdt_buf[3]);
	}
	madt = xsdt_find_tbl(xsdt, "APIC", asize);
	assert(madt);
	nr_cores = madt_get_nr_cores(madt);
	if (nr_cores == 0) {
		warn("MADT parsing found 0 cores!");
		nr_cores = 1;
	}
	return nr_cores;
}

/*
 * The invariant that each level in the tree has an associated
 * Atable implies that each chan can be mapped to an Atable.
 * The assertions here enforce that invariant.
 */
static struct Atable *genatable(struct chan *c)
{
	struct Atable *a;
	uint64_t ai;

	ai = c->qid.path >> QIndexShift;
	assert(ai < lastpath);
	a = atableindex[ai];
	assert(a != NULL);

	return a;
}

static int acpigen(struct chan *c, char *name, struct dirtab *tab, int ntab,
				   int i, struct dir *dp)
{
	struct Atable *a = genatable(c);

	if (i == DEVDOTDOT) {
		assert((c->qid.path & QIndexMask) == Qdir);
		devdir(c, a->parent->qid, a->parent->name, 0, eve.name, DMDIR | 0555,
		       dp);
		return 1;
	}
	return devgen(c, name, a->cdirs, a->nchildren + NQtypes, i, dp);
}

/*
 * Print the contents of the XSDT.
 */
static void dumpxsdt(void)
{
	printk("xsdt: len = %lu, asize = %lu, p = %p\n",
	       xsdt->len, xsdt->asize, xsdt->p);
}

static char *dumpGas(char *start, char *end, char *prefix, struct Gas *g)
{
	start = seprintf(start, end, "%s", prefix);

	switch (g->spc) {
		case Rsysmem:
		case Rsysio:
		case Rembed:
		case Rsmbus:
		case Rcmos:
		case Rpcibar:
		case Ripmi:
			start = seprintf(start, end, "[%s ", regnames[g->spc]);
			break;
		case Rpcicfg:
			start = seprintf(start, end, "[pci ");
			start =
				seprintf(start, end, "dev %#p ",
						 (uint32_t)(g->addr >> 32) & 0xFFFF);
			start =
				seprintf(start, end, "fn %#p ",
						 (uint32_t)(g->addr & 0xFFFF0000) >> 16);
			start =
				seprintf(start, end, "adr %#p ", (uint32_t)(g->addr & 0xFFFF));
			break;
		case Rfixedhw:
			start = seprintf(start, end, "[hw ");
			break;
		default:
			start = seprintf(start, end, "[spc=%#p ", g->spc);
	}
	start = seprintf(start, end, "off %d len %d addr %#p sz%d]",
					 g->off, g->len, g->addr, g->accsz);
	start = seprintf(start, end, "\n");
	return start;
}

static unsigned int getbanked(uintptr_t ra, uintptr_t rb, int sz)
{
	unsigned int r;

	r = 0;
	switch (sz) {
		case 1:
			if (ra != 0)
				r |= inb(ra);
			if (rb != 0)
				r |= inb(rb);
			break;
		case 2:
			if (ra != 0)
				r |= inw(ra);
			if (rb != 0)
				r |= inw(rb);
			break;
		case 4:
			if (ra != 0)
				r |= inl(ra);
			if (rb != 0)
				r |= inl(rb);
			break;
		default:
			printd("getbanked: wrong size\n");
	}
	return r;
}

static unsigned int setbanked(uintptr_t ra, uintptr_t rb, int sz, int v)
{
	unsigned int r;

	r = -1;
	switch (sz) {
		case 1:
			if (ra != 0)
				outb(ra, v);
			if (rb != 0)
				outb(rb, v);
			break;
		case 2:
			if (ra != 0)
				outw(ra, v);
			if (rb != 0)
				outw(rb, v);
			break;
		case 4:
			if (ra != 0)
				outl(ra, v);
			if (rb != 0)
				outl(rb, v);
			break;
		default:
			printd("setbanked: wrong size\n");
	}
	return r;
}

static unsigned int getpm1ctl(void)
{
	assert(fadt != NULL);
	return getbanked(fadt->pm1acntblk, fadt->pm1bcntblk, fadt->pm1cntlen);
}

static void setpm1sts(unsigned int v)
{
	assert(fadt != NULL);
	setbanked(fadt->pm1aevtblk, fadt->pm1bevtblk, fadt->pm1evtlen / 2, v);
}

static unsigned int getpm1sts(void)
{
	assert(fadt != NULL);
	return getbanked(fadt->pm1aevtblk, fadt->pm1bevtblk, fadt->pm1evtlen / 2);
}

static unsigned int getpm1en(void)
{
	int sz;

	assert(fadt != NULL);
	sz = fadt->pm1evtlen / 2;
	return getbanked(fadt->pm1aevtblk + sz, fadt->pm1bevtblk + sz, sz);
}

static int getgpeen(int n)
{
	return inb(gpes[n].enio) & 1 << gpes[n].enbit;
}

static void setgpeen(int n, unsigned int v)
{
	int old;

	old = inb(gpes[n].enio);
	if (v)
		outb(gpes[n].enio, old | 1 << gpes[n].enbit);
	else
		outb(gpes[n].enio, old & ~(1 << gpes[n].enbit));
}

static void clrgpests(int n)
{
	outb(gpes[n].stsio, 1 << gpes[n].stsbit);
}

static unsigned int getgpests(int n)
{
	return inb(gpes[n].stsio) & 1 << gpes[n].stsbit;
}

#if 0
static void acpiintr(Ureg *, void *)
{
	int i;
	unsigned int sts, en;

	printd("acpi: intr\n");

	for (i = 0; i < ngpes; i++)
		if (getgpests(i)) {
			printd("gpe %d on\n", i);
			en = getgpeen(i);
			setgpeen(i, 0);
			clrgpests(i);
			if (en != 0)
				printd("acpiitr: calling gpe %d\n", i);
			//  queue gpe for calling gpe->ho in the
			//  aml process.
			//  enable it again when it returns.
		}
	sts = getpm1sts();
	en = getpm1en();
	printd("acpiitr: pm1sts %#p pm1en %#p\n", sts, en);
	if (sts & en)
		printd("have enabled events\n");
	if (sts & 1)
		printd("power button\n");
	// XXX serve other interrupts here.
	setpm1sts(sts);
}
#endif

static void initgpes(void)
{
	int i, n0, n1;

	assert(fadt != NULL);
	n0 = fadt->gpe0blklen / 2;
	n1 = fadt->gpe1blklen / 2;
	ngpes = n0 + n1;
	gpes = kzmalloc(sizeof(struct Gpe) * ngpes, 1);
	for (i = 0; i < n0; i++) {
		gpes[i].nb = i;
		gpes[i].stsbit = i & 7;
		gpes[i].stsio = fadt->gpe0blk + (i >> 3);
		gpes[i].enbit = (n0 + i) & 7;
		gpes[i].enio = fadt->gpe0blk + ((n0 + i) >> 3);
	}
	for (i = 0; i + n0 < ngpes; i++) {
		gpes[i + n0].nb = fadt->gp1base + i;
		gpes[i + n0].stsbit = i & 7;
		gpes[i + n0].stsio = fadt->gpe1blk + (i >> 3);
		gpes[i + n0].enbit = (n1 + i) & 7;
		gpes[i + n0].enio = fadt->gpe1blk + ((n1 + i) >> 3);
	}
	for (i = 0; i < ngpes; i++) {
		setgpeen(i, 0);
		clrgpests(i);
	}
}

static void acpiioalloc(unsigned int addr, int len)
{
	if (addr != 0)
		printd("Just TAKING port %016lx to %016lx\n", addr, addr + len);
}

static void acpiinitonce(void)
{
	parsersdptr();
	if (root != NULL)
		printk("ACPI initialized\n");
}

int acpiinit(void)
{
	run_once(acpiinitonce());
	return (root == NULL) ? -1 : 0;
}

static struct chan *acpiattach(char *spec)
{
	int i;
	struct chan *c;
	/*
	 * This was written for the stock kernel.
	 * This code must use 64 registers to be acpi ready in nix.
	 */
	if (acpiinit() < 0)
		error(ENOSYS, "no acpi");

	/*
	 * should use fadt->xpm* and fadt->xgpe* registers for 64 bits.
	 * We are not ready in this kernel for that.
	 */
	assert(fadt != NULL);
	acpiioalloc(fadt->smicmd, 1);
	acpiioalloc(fadt->pm1aevtblk, fadt->pm1evtlen);
	acpiioalloc(fadt->pm1bevtblk, fadt->pm1evtlen);
	acpiioalloc(fadt->pm1acntblk, fadt->pm1cntlen);
	acpiioalloc(fadt->pm1bcntblk, fadt->pm1cntlen);
	acpiioalloc(fadt->pm2cntblk, fadt->pm2cntlen);
	acpiioalloc(fadt->pmtmrblk, fadt->pmtmrlen);
	acpiioalloc(fadt->gpe0blk, fadt->gpe0blklen);
	acpiioalloc(fadt->gpe1blk, fadt->gpe1blklen);

	initgpes();
#ifdef RON_SAYS_CONFIG_WE_ARE_NOT_WORTHY
	/* this is frightening. SMI: just say no. Although we will almost
	 * certainly find that we have no choice.
	 *
	 * This starts ACPI, which may require we handle
	 * power mgmt events ourselves. Use with care.
	 */
	outb(fadt->smicmd, fadt->acpienable);
	for (i = 0; i < 10; i++)
		if (getpm1ctl() & Pm1SciEn)
			break;
	if (i == 10)
		error(EFAIL, "acpi: failed to enable\n");
	if (fadt->sciint != 0)
		intrenable(fadt->sciint, acpiintr, 0, BUSUNKNOWN, "acpi");
#endif
	c = devattach(devname(), spec);

	return c;
}

static struct walkqid *acpiwalk(struct chan *c, struct chan *nc, char **name,
								unsigned int nname)
{
	/*
	 * Note that devwalk hard-codes a test against the location of 'devgen',
	 * so we pretty much have to not pass it here.
	 */
	return devwalk(c, nc, name, nname, NULL, 0, acpigen);
}

static size_t acpistat(struct chan *c, uint8_t *dp, size_t n)
{
	struct Atable *a = genatable(c);

	if (c->qid.type == QTDIR)
		a = a->parent;
	assert(a != NULL);

	/* TODO(dcross): make acpigen work here. */
	return devstat(c, dp, n, a->cdirs, a->nchildren + NQtypes, devgen);
}

static struct chan *acpiopen(struct chan *c, int omode)
{
	return devopen(c, omode, NULL, 0, acpigen);
}

static void acpiclose(struct chan *unused)
{
}

static char *ttext;
static int tlen;

// Get the table from the qid.
// Read that one table using the pointers.
static size_t acpiread(struct chan *c, void *a, size_t n, off64_t off)
{
	long q;
	struct Atable *t;
	char *ns, *s, *e, *ntext;

	if (ttext == NULL) {
		tlen = 32768;
		ttext = kzmalloc(tlen, 0);
	}
	if (ttext == NULL)
		error(ENOMEM, "acpiread: no memory");
	q = c->qid.path & QIndexMask;
	switch (q) {
	case Qdir:
		return devdirread(c, a, n, NULL, 0, acpigen);
	case Qraw:
		return readmem(off, a, n, ttext, tlen);
	case Qtbl:
		s = ttext;
		e = ttext + tlen;
		strlcpy(s, "no tables\n", tlen);
		for (t = tfirst; t != NULL; t = t->next) {
			ns = seprinttable(s, e, t);
			while (ns == e - 1) {
				ntext = krealloc(ttext, tlen * 2, 0);
				if (ntext == NULL)
					panic("acpi: no memory\n");
				s = ntext + (ttext - s);
				ttext = ntext;
				tlen *= 2;
				e = ttext + tlen;
				ns = seprinttable(s, e, t);
			}
			s = ns;
		}
		return readstr(off, a, n, ttext);
	case Qpretty:
		s = ttext;
		e = ttext + tlen;
		s = dumpfadt(s, e, fadt);
		s = dumpmadt(s, e, apics);
		s = dumpslit(s, e, slit);
		s = dumpsrat(s, e, srat);
		s = dumpdmar(s, e, dmar);
		dumpmsct(s, e, mscttbl);
		return readstr(off, a, n, ttext);
	default:
		error(EINVAL, "acpiread: bad path %d\n", q);
	}
	error(EPERM, ERROR_FIXME);

	return -1;
}

static size_t acpiwrite(struct chan *c, void *a, size_t n, off64_t off)
{
	error(EFAIL, "acpiwrite: not until we can figure out what it's for");
#if 0
	ERRSTACK(2);
	struct cmdtab *ct;
	struct cmdbuf *cb;
	struct Reg *r;
	unsigned int rno, fun, dev, bus, i;

	if (c->qid.path == Qio) {
		if (reg == NULL)
			error(EFAIL, "region not configured");
		return regio(reg, a, n, off, 1);
	}
	if (c->qid.path != Qctl)
		error(EPERM, ERROR_FIXME);

	cb = parsecmd(a, n);
	if (waserror()) {
		kfree(cb);
		nexterror();
	}
	ct = lookupcmd(cb, ctls, ARRAY_SIZE(ctls));
	switch (ct->index) {
		case CMregion:
			/* TODO: this block is racy on reg (global) */
			r = reg;
			if (r == NULL) {
				r = kzmalloc(sizeof(struct Reg), 0);
				r->name = NULL;
			}
			kstrdup(&r->name, cb->f[1]);
			r->spc = acpiregid(cb->f[2]);
			if (r->spc < 0) {
				kfree(r);
				reg = NULL;
				error(EFAIL, "bad region type");
			}
			if (r->spc == Rpcicfg || r->spc == Rpcibar) {
				rno = r->base >> Rpciregshift & Rpciregmask;
				fun = r->base >> Rpcifunshift & Rpcifunmask;
				dev = r->base >> Rpcidevshift & Rpcidevmask;
				bus = r->base >> Rpcibusshift & Rpcibusmask;
#ifdef CONFIG_X86
				r->tbdf = MKBUS(BusPCI, bus, dev, fun);
#else
				r->tbdf = 0
#endif
				r->base = rno;	/* register ~ our base addr */
			}
			r->base = strtoul(cb->f[3], NULL, 0);
			r->len = strtoul(cb->f[4], NULL, 0);
			r->accsz = strtoul(cb->f[5], NULL, 0);
			if (r->accsz < 1 || r->accsz > 4) {
				kfree(r);
				reg = NULL;
				error(EFAIL, "bad region access size");
			}
			reg = r;
			printd("region %s %s %p %p sz%d",
				   r->name, acpiregstr(r->spc), r->base, r->len, r->accsz);
			break;
		case CMgpe:
			i = strtoul(cb->f[1], NULL, 0);
			if (i >= ngpes)
				error(ERANGE, "gpe out of range");
			kstrdup(&gpes[i].obj, cb->f[2]);
			setgpeen(i, 1);
			break;
		default:
			panic("acpi: unknown ctl");
	}
	poperror();
	kfree(cb);
	return n;
#endif
}

struct {
	char *(*pretty)(struct Atable *atbl, char *start, char *end, void *arg);
} acpisw[NACPITBLS] = {
};

static char *pretty(struct Atable *atbl, char *start, char *end, void *arg)
{
	int type;

	type = atbl->type;
	if (type < 0 || NACPITBLS < type)
		return start;
	if (acpisw[type].pretty == NULL)
		return seprintf(start, end, "\"\"\n");
	return acpisw[type].pretty(atbl, start, end, arg);
}

static char *raw(struct Atable *atbl, char *start, char *end, void *unused_arg)
{
	size_t len = MIN(end - start, atbl->rawsize);

	memmove(start, atbl->raw, len);

	return start + len;
}

struct dev acpidevtab __devtab = {
	.name = "acpi",

	.reset = devreset,
	.init = devinit,
	.shutdown = devshutdown,
	.attach = acpiattach,
	.walk = acpiwalk,
	.stat = acpistat,
	.open = acpiopen,
	.create = devcreate,
	.close = acpiclose,
	.read = acpiread,
	.bread = devbread,
	.write = acpiwrite,
	.bwrite = devbwrite,
	.remove = devremove,
	.wstat = devwstat,
};
