summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/squidboy.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-02-01 10:23:17 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2014-02-01 10:23:17 +0100
commit28ad4e661610353efec655fdf147a46e156bf46e (patch)
treee830a6f8cfa91507114c1bc52f3c45356d235b15 /sys/src/9/pc/squidboy.c
parent06bc19c28f3bd1528f669626eb9826226decabd9 (diff)
pc kernel: split mpstartap() and squidboy into separate file... stuff for amd64
Diffstat (limited to 'sys/src/9/pc/squidboy.c')
-rw-r--r--sys/src/9/pc/squidboy.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/sys/src/9/pc/squidboy.c b/sys/src/9/pc/squidboy.c
new file mode 100644
index 000000000..03fccb691
--- /dev/null
+++ b/sys/src/9/pc/squidboy.c
@@ -0,0 +1,119 @@
+#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)
+{
+// iprint("Hello Squidboy\n");
+
+ machinit();
+ mmuinit();
+
+ cpuidentify();
+ cpuidprint();
+ checkmtrr();
+
+ apic->online = 1;
+ coherence();
+
+ lapicinit(apic);
+ lapiconline();
+ syncclock();
+ timersinit();
+
+ fpoff();
+
+ lock(&active);
+ active.machs |= 1<<m->machno;
+ unlock(&active);
+
+ while(!active.thunderbirdsarego)
+ microdelay(100);
+
+ schedinit();
+}
+
+void
+mpstartap(Apic* apic)
+{
+ ulong *apbootp, *pdb, *pte;
+ Mach *mach, *mach0;
+ int i, machno;
+ uchar *p;
+
+ mach0 = MACHP(0);
+
+ /*
+ * Initialise the AP page-tables and Mach structure. The page-tables
+ * are the same as for the bootstrap processor with the exception of
+ * the PTE for the Mach structure.
+ * Xspanalloc will panic if an allocation can't be made.
+ */
+ p = xspanalloc(4*BY2PG, BY2PG, 0);
+ pdb = (ulong*)p;
+ memmove(pdb, mach0->pdb, BY2PG);
+ p += BY2PG;
+
+ if((pte = mmuwalk(pdb, MACHADDR, 1, 0)) == nil)
+ return;
+ memmove(p, KADDR(PPN(*pte)), BY2PG);
+ *pte = PADDR(p)|PTEWRITE|PTEVALID;
+ if(mach0->havepge)
+ *pte |= PTEGLOBAL;
+ p += BY2PG;
+
+ mach = (Mach*)p;
+ if((pte = mmuwalk(pdb, MACHADDR, 2, 0)) == nil)
+ return;
+ *pte = PADDR(mach)|PTEWRITE|PTEVALID;
+ if(mach0->havepge)
+ *pte |= PTEGLOBAL;
+ p += BY2PG;
+
+ machno = apic->machno;
+ MACHP(machno) = mach;
+ mach->machno = machno;
+ mach->pdb = pdb;
+ mach->gdt = (Segdesc*)p; /* filled by mmuinit */
+
+ /*
+ * Tell the AP where its kernel vector and pdb are.
+ * The offsets are known in the AP bootstrap code.
+ */
+ apbootp = (ulong*)(APBOOTSTRAP+0x08);
+ *apbootp++ = (ulong)squidboy; /* assembler jumps here eventually */
+ *apbootp++ = PADDR(pdb);
+ *apbootp = (ulong)apic;
+
+ /*
+ * 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);
+}