/* 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 <acpi.h>
#include <arch/ioapic.h>
#include <arch/topology.h>

int mpacpi(int ncleft)
{
	char *already;
	int np, bp;
	struct apic *apic;
	struct Apicst *st;
	struct Madt *mt;

	/* If we don't have an mpisabusno yet, it's because the MP tables failed
	 * to parse.  So we'll just take the last one available.  I think we're
	 * supposed to parse the ACPI shit with the AML to figure out the buses
	 * and find a clear one, but fuck that.  Note this busno is just for our
	 * own RDT/Rbus bookkeeping. */
	if (mpisabusno == -1)
		mpisabusno = Nbus - 1;

	if (apics == NULL)
		return ncleft;
	mt = apics->tbl;
	if (mt == NULL)
		return ncleft;

	printd("APIC lapic paddr %#.8llux, flags %#.8ux\n",
		   mt->lapicpa, mt->pcat);
	np = 0;
	printd("apics->st %p\n", apics->st);
	for (int i = 0; i < apics->nchildren; i++) {
		st = apics->children[i]->tbl;
		already = "";
		switch (st->type) {
		case ASlapic:
			printd("ASlapic %d\n", st->lapic.id);
			/* this table is supposed to have all of them if it
			 * exists */
			if (st->lapic.id > MaxAPICNO)
				break;
			apic = xlapic + st->lapic.id;
			bp = (np++ == 0);
			if (apic->useable) {
				already = "(mp)";
			} else if (ncleft != 0) {
				ncleft--;
				apicinit(st->lapic.id, mt->lapicpa, bp);
			} else
				already = "(off)";

			printd("apic proc %d/%d apicid %d %s\n", np - 1,
			       apic->machno, st->lapic.id, already);
			break;
		case ASlx2apic:
			// XXX hacked version of above
			printd("ASlx2apic %d\n", st->lx2apic.id);
			/* this table is supposed to have all of them if it
			 * exists */
			if (st->lx2apic.id > MaxAPICNO)
				break;
			apic = xlapic + st->lx2apic.id;
			bp = (np++ == 0);
			if (apic->useable) {
				already = "(mp)";
			} else if (ncleft != 0) {
				ncleft--;
				apicinit(st->lx2apic.id, mt->lapicpa, bp);
			} else
				already = "(off)";

			// XXX machno is 0.  looks like an old plan9 thing
			printd("apic proc %d/%d apicid %d %s\n", np - 1,
			       apic->machno, st->lx2apic.id, already);
			break;

		case ASioapic:
			printd("ASioapic %d\n", st->ioapic.id);
			if (st->ioapic.id > Napic)
				break;
			apic = xioapic + st->ioapic.id;
			if (apic->useable) {
				apic->ibase = st->ioapic.ibase;	/* gnarly */
				already = "(mp)";
				goto pr1;
			}
			ioapicinit(st->ioapic.id, st->ioapic.ibase,
				   st->ioapic.addr);
pr1:
			printd("ioapic %d ", st->ioapic.id);
			printd("addr %p base %d %s\n", apic->paddr, apic->ibase,
				   already);
			break;
		}
	}
	return ncleft;
}
