diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-01 10:25:10 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-01 10:25:10 +0100 |
commit | 56343cafcfb47a4ef3fff0d6a8e3220ecd93518b (patch) | |
tree | 4e0e06c49e5eff8f1d2fd599f7d0cad92fcaa9f2 /sys/src/9/pc64/squidboy.c | |
parent | 28ad4e661610353efec655fdf147a46e156bf46e (diff) |
add experimental pc64 kernel
Diffstat (limited to 'sys/src/9/pc64/squidboy.c')
-rw-r--r-- | sys/src/9/pc64/squidboy.c | 113 |
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); +} |