summaryrefslogtreecommitdiff
path: root/sys/src/9/pc64/squidboy.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-02-01 10:25:10 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2014-02-01 10:25:10 +0100
commit56343cafcfb47a4ef3fff0d6a8e3220ecd93518b (patch)
tree4e0e06c49e5eff8f1d2fd599f7d0cad92fcaa9f2 /sys/src/9/pc64/squidboy.c
parent28ad4e661610353efec655fdf147a46e156bf46e (diff)
add experimental pc64 kernel
Diffstat (limited to 'sys/src/9/pc64/squidboy.c')
-rw-r--r--sys/src/9/pc64/squidboy.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/sys/src/9/pc64/squidboy.c b/sys/src/9/pc64/squidboy.c
new file mode 100644
index 000000000..b0d9f409f
--- /dev/null
+++ b/sys/src/9/pc64/squidboy.c
@@ -0,0 +1,113 @@
+#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"
+
+extern void checkmtrr(void);
+
+static void
+squidboy(Apic* apic)
+{
+ machinit();
+ mmuinit();
+ cpuidentify();
+ cpuidprint();
+ checkmtrr();
+ apic->online = 1;
+ coherence();
+
+ lapicinit(apic);
+ lapiconline();
+ syncclock();
+ timersinit();
+
+ lock(&active);
+ active.machs |= 1<<m->machno;
+ unlock(&active);
+
+ while(!active.thunderbirdsarego)
+ microdelay(100);
+
+ schedinit();
+}
+
+void
+mpstartap(Apic* apic)
+{
+ uintptr *apbootp, *pml4, *pdp0;
+ 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.
+ */
+ pml4[PTLX(KZERO, 3)] = MACHP(0)->pml4[PTLX(KZERO, 3)];
+
+ /* 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;
+
+ /*
+ * 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 < 1000; i++){
+ if(apic->online)
+ break;
+ delay(10);
+ }
+ nvramwrite(0x0F, 0x00);
+}