shithub: nix

Download patch

ref: c26d56edea946bf2206bc894fe1c944c37d96ce7
parent: bfc9136801651ac4921c78e5b9b3a71cf382f26d
author: glenda <glenda@cirno>
date: Sun May 5 21:55:14 EDT 2024

moving to having NIX work as a device.

--- a/sys/src/nix/pc64/dat.h
+++ b/sys/src/nix/pc64/dat.h
@@ -241,6 +241,13 @@
 {
 	char	machs[MAXMACH];		/* bitmap of active CPUs */
 	int	exiting;		/* shutdown */
+
+	// NIX
+	Lock;
+	int	nonline;			/* # of active CPUs */
+	int nbooting;			/* # of CPUs waiting for the bTC to go */
+	int	ispanic;			/* shutdown in response to a panic */
+	int	thunderbirdsarego;	/* lets the added processors continue */
 }active;
 
 /*
--- a/sys/src/nix/pc64/devnix.c
+++ b/sys/src/nix/pc64/devnix.c
@@ -1,5 +1,9 @@
 /*
- * Lml 22 driver
+ * NIX driver
+ * Cores are placed into NIX mode by
+ * wiring a proc to a core
+ * opening a file by core number
+ * The file has the 'one opener' attribute
  */
 #include	"u.h"
 #include	"../port/lib.h"
@@ -8,10 +12,7 @@
 #include	"fns.h"
 #include	"../port/error.h"
 #include	"io.h"
-#include	"../port/pci.h"
 
-#include	"devlml.h"
-
 #define DBGREAD	0x01
 #define DBGWRIT	0x02
 #define DBGINTR	0x04
@@ -22,383 +23,169 @@
 
 enum{
 	Qdir,
-	Qctl0,
-	Qjpg0,
-	Qraw0,
-	Qctl1,
-	Qjpg1,
-	Qraw1,
+	Qctl,
+	Qstat,
+	Q1,
 };
 
-static Dirtab lmldir[] = {
+static Dirtab nixdir[] = {
 	".",		{Qdir, 0, QTDIR},	0,	0555,
-	"lml0ctl",	{Qctl0},		0,	0666,
-	"lml0jpg",	{Qjpg0},		0,	0444,
-	"lml0raw",	{Qraw0},		0,	0444,
-	"lml1ctl",	{Qctl1},		0,	0666,
-	"lml1jpg",	{Qjpg1},		0,	0444,
-	"lml1raw",	{Qraw1},		0,	0444,
+	"nixctl",	{Qctl},		0,	0666,
+	"nixstat",  {Qstat},	0,	0444,
+	"nix1",		{Q1},		0,	0444,
 };
 
-typedef struct LML LML;
+typedef struct DEVNIX DEVNIX;
 
-struct LML {
-	/* Hardware */
-	Pcidev	*pcidev;
-	uintptr	pciBaseAddr;
+struct DEVNIX {
+	int online;
+	int nixed;
+} DEVNIX[MAXMACH];
 
-	/* Allocated memory */
-	CodeData *codedata;
+int nnix;
 
-	/* Software state */
-	ulong	jpgframeno;
-	int	frameNo;
-	Rendez	sleepjpg;
-	int	jpgopens;
-} lmls[NLML];
 
-int nlml;
-
-static FrameHeader jpgheader = {
-	MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
-	{ 'L', 'M', 'L', '\0'},
-	-1, 0, 0,  0
-};
-
-#define writel(v, a) *(ulong *)(a) = (v)
-#define readl(a) *(ulong*)(a)
-
-static int
-getbuffer(void *x)
-{
-	static last = NBUF-1;
-	int l = last;
-	LML *lml;
-
-	lml = x;
-	for(;;){
-		last = (last+1) % NBUF;
-		if(lml->codedata->statCom[last] & STAT_BIT)
-			return last + 1;
-		if(last == l)
-			return 0;
-	}
-}
-
-static long
-jpgread(LML *lml, void *va, long nbytes, vlong, int dosleep)
-{
-	int bufno;
-	FrameHeader *jpgheader;
-
-	/*
-	 * reads should be of size 1 or sizeof(FrameHeader).
-	 * Frameno is the number of the buffer containing the data.
-	 */
-	while((bufno = getbuffer(lml)) == 0 && dosleep)
-		sleep(&lml->sleepjpg, getbuffer, lml);
-	if(--bufno < 0)
-		return 0;
-
-	jpgheader = (FrameHeader*)(lml->codedata->frag[bufno].hdr+2);
-	if(nbytes == sizeof(FrameHeader)){
-		memmove(va, jpgheader, sizeof(FrameHeader));
-		return sizeof(FrameHeader);
-	}
-	if(nbytes == 1){
-		*(char *)va = bufno;
-		return 1;
-	}
-	return 0;
-}
-
-static void lmlintr(Ureg *, void *);
-
 static void
-prepbuf(LML *lml)
+nixreset(void)
 {
-	int i;
-	CodeData *cd;
+	DEVNIX *nix;
 
-	cd = lml->codedata;
-	for(i = 0; i < NBUF; i++){
-		cd->statCom[i] = PADDR(&(cd->fragdesc[i]));
-		cd->fragdesc[i].addr = PADDR(cd->frag[i].fb);
-		/* Length is in double words, in position 1..20 */
-		cd->fragdesc[i].leng = FRAGSIZE >> 1 | FRAGM_FINAL_B;
-		memmove(cd->frag[i].hdr+2, &jpgheader, sizeof(FrameHeader)-2);
-	}
-}
-
-static void
-lmlreset(void)
-{
-	uvlong regpa;
-	char name[32];
-	void *regva;
-	LML *lml;
-	Pcidev *pcidev;
-	Physseg segbuf;
-
 	pcidev = nil;
 
-	for(nlml = 0; nlml < NLML && (pcidev = pcimatch(pcidev, VENDOR_ZORAN,
-	    ZORAN_36067)); nlml++){
-		lml = &lmls[nlml];
-		lml->pcidev = pcidev;
-		lml->codedata = (CodeData*)(((ulong)xalloc(Codedatasize+ BY2PG)
-			+ BY2PG-1) & ~(BY2PG-1));
-		if(lml->codedata == nil){
-			print("devlml: xalloc(%ux, %ux, 0)\n", Codedatasize, BY2PG);
-			return;
+	for(nnix = 0; nnix < MAXMACH; nnix++){
+		nix = &nixs[nnix];
 		}
 
-		print("Installing Motion JPEG driver %s, irq %d\n",
-			MJPG_VERSION, pcidev->intl);
-		print("MJPG buffer at 0x%.8p, size 0x%.8ux\n", lml->codedata,
-			Codedatasize);
 
-		/* Get access to DMA memory buffer */
-		lml->codedata->pamjpg = PADDR(lml->codedata->statCom);
 
-		prepbuf(lml);
-
-		print("zr36067 found at 0x%.8lux", pcidev->mem[0].bar & ~0x0F);
-
-		regpa = pcidev->mem[0].bar & ~0x0F;
-		regva = vmap(regpa, pcidev->mem[0].size);
-		if(regva == 0){
-			print("lml: failed to map registers\n");
-			return;
-		}
-		lml->pciBaseAddr = (uintptr)regva;
-		print(", mapped at %#p\n", lml->pciBaseAddr);
-
-		memset(&segbuf, 0, sizeof(segbuf));
-		segbuf.attr = SG_PHYSICAL;
-		sprint(name, "lml%d.mjpg", nlml);
-		kstrdup(&segbuf.name, name);
-		segbuf.pa = PADDR(lml->codedata);
-		segbuf.size = Codedatasize;
-		if(addphysseg(&segbuf) == nil){
-			print("lml: physsegment: %s\n", name);
-			return;
-		}
-
-		memset(&segbuf, 0, sizeof(segbuf));
-		segbuf.attr = SG_PHYSICAL | SG_DEVICE | SG_NOEXEC;
-		sprint(name, "lml%d.regs", nlml);
-		kstrdup(&segbuf.name, name);
-		segbuf.pa = (uintptr)regpa;
-		segbuf.size = pcidev->mem[0].size;
-		if(addphysseg(&segbuf) == nil){
-			print("lml: physsegment: %s\n", name);
-			return;
-		}
-
-		/* set up interrupt handler */
-		intrenable(pcidev->intl, lmlintr, lml, pcidev->tbdf, "lml");
-	}
 }
 
 static Chan*
-lmlattach(char *spec)
+nixattach(char *spec)
 {
 	if(debug&DBGFS)
-		print("lmlattach\n");
+		print("nixattach\n");
 	return devattach(L'Λ', spec);
 }
 
 static Walkqid*
-lmlwalk(Chan *c, Chan *nc, char **name, int nname)
+nixwalk(Chan *c, Chan *nc, char **name, int nname)
 {
 	if(debug&DBGFS)
-		print("lmlwalk\n");
-	return devwalk(c, nc, name, nname, lmldir, 3*nlml+1, devgen);
+		print("nixwalk\n");
+	return devwalk(c, nc, name, nname, nixdir, 3*nnix+1, devgen);
 }
 
 static int
-lmlstat(Chan *c, uchar *db, int n)
+nixstat(Chan *c, uchar *db, int n)
 {
 	if(debug&DBGFS)
-		print("lmlstat\n");
-	return devstat(c, db, n, lmldir, 3*nlml+1, devgen);
+		print("nixstat\n");
+	return devstat(c, db, n, nixdir, 3*nnix+1, devgen);
 }
 
 static Chan*
-lmlopen(Chan *c, int omode)
+nixopen(Chan *c, int omode)
 {
 	int i;
-	LML *lml;
+	DEVNIX *nix;
 
 	if(debug&DBGFS)
-		print("lmlopen\n");
+		print("nixopen\n");
 	if(omode != OREAD)
 		error(Eperm);
 	c->aux = 0;
 	i = 0;
 	switch((ulong)c->qid.path){
-	case Qctl1:
-		i++;
-		/* fall through */
-	case Qctl0:
-		if(i >= nlml)
-			error(Eio);
+	case Qctl:
+		error(Eperm);
 		break;
-	case Qjpg1:
-	case Qraw1:
-		i++;
-		/* fall through */
-	case Qjpg0:
-	case Qraw0:
-		/* allow one open */
-		if(i >= nlml)
-			error(Eio);
-		lml = lmls+i;
-		if(lml->jpgopens)
-			error(Einuse);
-		lml->jpgopens = 1;
-		lml->jpgframeno = 0;
-		prepbuf(lml);
+	case Qstat:
+		error(Eperm);
 		break;
+	case Q1:
+		error("Eperm")
+		break;
 	}
-	return devopen(c, omode, lmldir, 3*nlml+1, devgen);
+	return devopen(c, omode, nixdir, 3*nnix+1, devgen);
 }
 
 static void
-lmlclose(Chan *c)
+nixclose(Chan *c)
 {
 	int i;
 
 	if(debug&DBGFS)
-		print("lmlclose\n");
+		print("nixclose\n");
 	i = 0;
 	switch((ulong)c->qid.path){
-	case Qjpg1:
-	case Qraw1:
-		i++;
-		/* fall through */
-	case Qjpg0:
-	case Qraw0:
-		lmls[i].jpgopens = 0;
-		break;
+	case Q1:
+	default:
 	}
 }
 
 static long
-lmlread(Chan *c, void *va, long n, vlong voff)
+nixread(Chan *c, void *va, long n, vlong voff)
 {
 	int i, len;
 	long off = voff;
 	uchar *buf = va;
-	LML *lml;
-	static char lmlinfo[1024];
+	DEVNIX *nix;
+	static char nixinfo[1024];
 
 	i = 0;
 	switch((ulong)c->qid.path){
 	case Qdir:
-		n = devdirread(c, (char *)buf, n, lmldir, 3*nlml+1, devgen);
+		n = devdirread(c, (char *)buf, n, nixdir, 3*nnix+1, devgen);
 		if(debug&(DBGFS|DBGREAD))
-			print("lmlread %ld\n", n);
+			print("nixread %ld\n", n);
 		return n;
-	case Qctl1:
-		i++;
-		/* fall through */
-	case Qctl0:
-		if(i >= nlml)
+	case Qctl:
+		error(Eperm);
+		break;
+	case Qstat:
+		if(i >= nnix)
 			error(Eio);
-		lml = lmls+i;
-		len = snprint(lmlinfo, sizeof lmlinfo, "lml%djpg	lml%draw\nlml%d.regs	0x%lux	0x%ux\nlml%d.mjpg	0x%lux	0x%ux\n",
-			i, i,
-			i, lml->pcidev->mem[0].bar & ~0x0F, lml->pcidev->mem[0].size,
-			i, PADDR(lml->codedata), Codedatasize);
+		nix = nixs+i;
+		len = snprint(nixinfo, sizeof nixinfo, "sizzle me a sizzler");
 		if(voff > len)
 			return 0;
 		if(n > len - voff)
 			n = len - voff;
-		memmove(va, lmlinfo+voff, n);
+		memmove(va, nixinfo+voff, n);
 		return n;
-	case Qjpg1:
-		i++;
-		/* fall through */
-	case Qjpg0:
-		if(i >= nlml)
-			error(Eio);
-		return jpgread(lmls+i, buf, n, off, 1);
-	case Qraw1:
-		i++;
-		/* fall through */
-	case Qraw0:
-		if(i >= nlml)
-			error(Eio);
-		return jpgread(lmls+i, buf, n, off, 0);
+	case Q1:
+		error(Eperm);
+		break;
 	}
 	return -1;
 }
 
 static long
-lmlwrite(Chan *, void *, long, vlong)
+nixwrite(Chan *, void *, long, vlong)
 {
 	error(Eperm);
 	return 0;
 }
 
-Dev lmldevtab = {
+Dev nixdevtab = {
 	L'Λ',
-	"video",
+	"nix",
 
-	lmlreset,
+	nixreset,
 	devinit,
 	devshutdown,
-	lmlattach,
-	lmlwalk,
-	lmlstat,
-	lmlopen,
+	nixattach,
+	nixwalk,
+	nixstat,
+	nixopen,
 	devcreate,
-	lmlclose,
-	lmlread,
+	nixclose,
+	nixread,
 	devbread,
-	lmlwrite,
+	nixwrite,
 	devbwrite,
 	devremove,
 	devwstat,
 };
 
-static void
-lmlintr(Ureg *, void *x)
-{
-	ulong fstart, fno, flags, statcom;
-	FrameHeader *jpgheader;
-	LML *lml;
-
-	lml = x;
-	flags = readl(lml->pciBaseAddr+INTR_STAT);
-	/* Reset all interrupts from 067 */
-	writel(0xff000000, lml->pciBaseAddr + INTR_STAT);
-
-	if(flags & INTR_JPEGREP){
-
-		if(debug&DBGINTR)
-			print("MjpgDrv_intrHandler stat=0x%.8lux\n", flags);
-
-		fstart = lml->jpgframeno & 3;
-		for(;;){
-			lml->jpgframeno++;
-			fno = lml->jpgframeno & 3;
-			if(lml->codedata->statCom[fno] & STAT_BIT)
-				break;
-			if(fno == fstart){
-				if(debug & DBGINTR)
-					print("Spurious lml jpg intr?\n");
-				return;
-			}
-		}
-		statcom = lml->codedata->statCom[fno];
-		jpgheader = (FrameHeader *)(lml->codedata->frag[fno].hdr + 2);
-		jpgheader->frameNo = lml->jpgframeno;
-		jpgheader->ftime  = todget(nil);
-		jpgheader->frameSize = (statcom & 0x00ffffff) >> 1;
-		jpgheader->frameSeqNo = statcom >> 24;
-		wakeup(&lml->sleepjpg);
-	}
-}
--- a/sys/src/nix/pc64/nix.h
+++ b/sys/src/nix/pc64/nix.h
@@ -43,3 +43,4 @@
 	char*	note;		/* to be posted in the TC after returning */
 	uchar	data[ICCLNSZ];	/* sent to the AC */
 };
+
--- a/sys/src/nix/pc64/nixmkfile
+++ b/sys/src/nix/pc64/nixmkfile
@@ -60,6 +60,7 @@
 	$CONF.rootc.$O\
 	$DEVS\
 	$PORT\
+	devnix.$O\
 	acore.$O\
 	tcore.$O\
 	l64acidt.$O\
--- /dev/null
+++ b/sys/src/nix/pc64/nixquidsC
@@ -1,0 +1,204 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "ureg.h"
+
+#include "mp.h"
+
+#define DBG print
+
+static void
+squidboy(Apic* apic)
+{
+	void acmmuswitch(void);
+	void acinit(void);
+	void acsched(void);
+
+	machinit();
+	mmuinit();
+	cpuidentify();
+	if(arch->clockinit)
+		arch->clockinit();
+	cpuidprint();
+	syncclock();
+	active.machs[m->machno] = 1;
+	apic->online = 1;
+	lapicinit(apic);
+	lapiconline();
+	timersinit();
+	m->nixtype = NIXAC;
+
+	/*
+	 * CAUTION: no time sync done, etc.
+	 */
+	DBG("Wait for the thunderbirds!\n");
+	if (0)
+	while(!active.thunderbirdsarego)
+		;
+
+
+	DBG("Hello Squidboy %d %d\n", m->apicno, m->machno);
+
+	switch(m->nixtype){
+	case NIXAC:
+		acmmuswitch();
+		acinit();
+		// consider ilock/iunlock here, but .. why no ainc?
+		active.nbooting--;
+		active.nonline++;
+		//adec(&active.nbooting);
+		//ainc(&active.nonline);	/* this was commented out */
+		acsched();
+		panic("squidboy");
+		break;
+	case NIXTC:
+		schedinit();
+		break;
+	}
+	panic("squidboy returns (type %d)", m->nixtype);
+}
+
+void
+mpstartap(Apic* apic)
+{
+	uintptr *apbootp, *pml4, *pdp0, v;
+	Segdesc *gdt;
+	Mach *mach;
+	uchar *p;
+	int i;
+
+	/*
+	 * Initialise the AP page-tables and Mach structure.
+	 * Xspanalloc will panic if an allocation can't be made.
+	 */
+	p = xspanalloc(2*PTSZ + BY2PG + MACHSIZE, BY2PG, 0);
+	pml4 = (uintptr*)p;
+	p += PTSZ;
+	pdp0 = (uintptr*)p;
+	p += PTSZ;
+	gdt = (Segdesc*)p;
+	p += BY2PG;
+	mach = (Mach*)p;
+
+	memset(pml4, 0, PTSZ);
+	memset(pdp0, 0, PTSZ);
+	memset(gdt, 0, BY2PG);
+	memset(mach, 0, MACHSIZE);
+
+	mach->machno = apic->machno;
+	mach->pml4 = pml4;
+	mach->gdt  = gdt;	/* filled by mmuinit */
+	MACHP(mach->machno) = mach;
+
+	/*
+	 * map KZERO (note that we share the KZERO (and VMAP)
+	 * PDP between processors.
+	 */
+	*mmuwalk(pml4, KZERO, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0);
+	for(v = VMAP; v < VMAP+VMAPSIZE; v += PGLSZ(3)){
+		mmuwalk(m->pml4, v, 2, 1);	/* force create */
+		*mmuwalk(pml4, v, 3, 0) = *mmuwalk(m->pml4, v, 3, 0);
+	}
+
+	/* double map */
+	pml4[0] = PADDR(pdp0) | PTEWRITE|PTEVALID;
+	pdp0[0] = *mmuwalk(pml4, KZERO, 2, 0);
+
+	/*
+	 * Tell the AP where its kernel vector and pdb are.
+	 * The offsets are known in the AP bootstrap code.
+	 */
+	apbootp = (uintptr*)(APBOOTSTRAP+0x08);
+	apbootp[0] = (uintptr)squidboy;	/* assembler jumps here eventually */
+	apbootp[1] = (uintptr)PADDR(pml4);
+	apbootp[2] = (uintptr)apic;
+	apbootp[3] = (uintptr)mach;
+	apbootp[4] |= (uintptr)m->havenx<<11;	/* EFER */
+
+	/*
+	 * Universal Startup Algorithm.
+	 */
+	p = KADDR(0x467);		/* warm-reset vector */
+	*p++ = PADDR(APBOOTSTRAP);
+	*p++ = PADDR(APBOOTSTRAP)>>8;
+	i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
+	/* code assumes i==0 */
+	if(i != 0)
+		print("mp: bad APBOOTSTRAP\n");
+	*p++ = i;
+	*p = i>>8;
+	coherence();
+
+	nvramwrite(0x0F, 0x0A);		/* shutdown code: warm reset upon init ipi */
+	lapicstartap(apic, PADDR(APBOOTSTRAP));
+	for(i = 0; i < 100000; i++){
+		if(arch->fastclock == tscticks)
+			cycles(&m->tscticks);	/* for ap's syncclock(); */
+		if(apic->online)
+			break;
+		delay(1);
+	}
+	nvramwrite(0x0F, 0x00);
+}
+
+static void
+testiccs(void)
+{
+	int i;
+	Mach *mp;
+	extern void testicc(int);
+
+	/* setup arguments for all */
+	for(i = 0; i < MACHMAX; i++)
+		if((mp = sys->machptr[i]) != nil && mp->online && mp->nixtype == NIXAC)
+			testicc(i);
+	print("bootcore: all cores done\n");
+}
+
+/*
+ * Rendezvous with other cores. Set roles for those that came
+ * up online, and wait until they are initialized.
+ * Sync TSC with them.
+ * We assume other processors that could boot had time to
+ * set online to 1 by now.
+ */
+static void
+nixsquids(void)
+{
+	Mach *mp;
+	int i;
+	uvlong now, start;
+
+	for(i = 1; i < MACHMAX; i++)
+		if((mp = sys->machptr[i]) != nil && mp->online){
+			/*
+			 * Inter-core calls. A ensure *mp->iccall and mp->icargs
+			 * go into different cache lines.
+			 */
+			mp->icc = mallocalign(sizeof *m->icc, ICCLNSZ, 0, 0);
+			mp->icc->fn = nil;
+			if(i < numtcs){
+				sys->nmach++;
+				mp->nixtype = NIXTC;
+				sys->nc[NIXTC]++;
+			}else
+				sys->nc[NIXAC]++;
+			ainc(&active.nbooting);
+		}
+	sys->epoch = rdtsc();
+	mfence();
+	wrmsr(0x10, sys->epoch);
+	m->rdtsc = rdtsc();
+	active.thunderbirdsarego = 1;
+	start = fastticks2us(fastticks(nil));
+	do{
+		now = fastticks2us(fastticks(nil));
+	}while(active.nbooting > 0 && now - start < 1000000)
+		;
+	if(active.nbooting > 0)
+		print("cpu0: %d cores couldn't start\n", active.nbooting);
+	active.nbooting = 0;
+}
--- a/sys/src/nix/pc64/squidboy.c
+++ /dev/null
@@ -1,133 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-
-#include "mp.h"
-
-#define DBG print
-
-static void
-squidboy(Apic* apic)
-{
-	void acmmuswitch(void);
-	void acinit(void);
-	void acsched(void);
-
-	machinit();
-	mmuinit();
-	cpuidentify();
-	if(arch->clockinit)
-		arch->clockinit();
-	cpuidprint();
-	syncclock();
-	active.machs[m->machno] = 1;
-	apic->online = 1;
-	lapicinit(apic);
-	lapiconline();
-	timersinit();
-	m->nixtype = NIXAC;
-
-	DBG("Hello Squidboy %d %d\n", m->apicno, m->machno);
-
-	switch(m->nixtype){
-	case NIXAC:
-		acmmuswitch();
-		acinit();
-		//adec(&active.nbooting);
-		//ainc(&active.nonline);	/* this was commented out */
-		acsched();
-		panic("squidboy");
-		break;
-	case NIXTC:
-		schedinit();
-		break;
-	}
-	panic("squidboy returns (type %d)", m->nixtype);
-}
-
-void
-mpstartap(Apic* apic)
-{
-	uintptr *apbootp, *pml4, *pdp0, v;
-	Segdesc *gdt;
-	Mach *mach;
-	uchar *p;
-	int i;
-
-	/*
-	 * Initialise the AP page-tables and Mach structure.
-	 * Xspanalloc will panic if an allocation can't be made.
-	 */
-	p = xspanalloc(2*PTSZ + BY2PG + MACHSIZE, BY2PG, 0);
-	pml4 = (uintptr*)p;
-	p += PTSZ;
-	pdp0 = (uintptr*)p;
-	p += PTSZ;
-	gdt = (Segdesc*)p;
-	p += BY2PG;
-	mach = (Mach*)p;
-
-	memset(pml4, 0, PTSZ);
-	memset(pdp0, 0, PTSZ);
-	memset(gdt, 0, BY2PG);
-	memset(mach, 0, MACHSIZE);
-
-	mach->machno = apic->machno;
-	mach->pml4 = pml4;
-	mach->gdt  = gdt;	/* filled by mmuinit */
-	MACHP(mach->machno) = mach;
-
-	/*
-	 * map KZERO (note that we share the KZERO (and VMAP)
-	 * PDP between processors.
-	 */
-	*mmuwalk(pml4, KZERO, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0);
-	for(v = VMAP; v < VMAP+VMAPSIZE; v += PGLSZ(3)){
-		mmuwalk(m->pml4, v, 2, 1);	/* force create */
-		*mmuwalk(pml4, v, 3, 0) = *mmuwalk(m->pml4, v, 3, 0);
-	}
-
-	/* double map */
-	pml4[0] = PADDR(pdp0) | PTEWRITE|PTEVALID;
-	pdp0[0] = *mmuwalk(pml4, KZERO, 2, 0);
-
-	/*
-	 * Tell the AP where its kernel vector and pdb are.
-	 * The offsets are known in the AP bootstrap code.
-	 */
-	apbootp = (uintptr*)(APBOOTSTRAP+0x08);
-	apbootp[0] = (uintptr)squidboy;	/* assembler jumps here eventually */
-	apbootp[1] = (uintptr)PADDR(pml4);
-	apbootp[2] = (uintptr)apic;
-	apbootp[3] = (uintptr)mach;
-	apbootp[4] |= (uintptr)m->havenx<<11;	/* EFER */
-
-	/*
-	 * Universal Startup Algorithm.
-	 */
-	p = KADDR(0x467);		/* warm-reset vector */
-	*p++ = PADDR(APBOOTSTRAP);
-	*p++ = PADDR(APBOOTSTRAP)>>8;
-	i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
-	/* code assumes i==0 */
-	if(i != 0)
-		print("mp: bad APBOOTSTRAP\n");
-	*p++ = i;
-	*p = i>>8;
-	coherence();
-
-	nvramwrite(0x0F, 0x0A);		/* shutdown code: warm reset upon init ipi */
-	lapicstartap(apic, PADDR(APBOOTSTRAP));
-	for(i = 0; i < 100000; i++){
-		if(arch->fastclock == tscticks)
-			cycles(&m->tscticks);	/* for ap's syncclock(); */
-		if(apic->online)
-			break;
-		delay(1);
-	}
-	nvramwrite(0x0F, 0x00);
-}