jehanne/sys/src/kern/amd64/squidboy.c

108 lines
2.2 KiB
C

#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 initialize_processor(void);
static void
squidboy(Apic* apic)
{
initialize_processor();
mmuinit();
cpuidentify();
cpuidprint();
syncclock();
active.machs[m->machno] = 1;
apic->online = 1;
m->online = 1;
lapicinit(apic);
lapiconline();
timersinit();
schedinit();
}
void
mpstartap(Apic* apic)
{
uintptr_t *apbootp, *pml4, *pdp0;
Segdesc *gdt;
Mach *mach;
uint8_t *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)];
pml4[PTLX(VMAP, 3)] = MACHP(0)->pml4[PTLX(VMAP, 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 < 100000; i++){
if(arch->fastclock == tscticks)
cycles(&m->tscticks); /* for ap's syncclock(); */
if(apic->online)
break;
delay(1);
}
nvramwrite(0x0F, 0x00);
}