2014-02-01 09:25:10 +00:00
|
|
|
#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"
|
|
|
|
|
2017-11-07 23:34:08 +00:00
|
|
|
extern void _stts(void);
|
|
|
|
|
2014-02-01 09:25:10 +00:00
|
|
|
static void
|
|
|
|
squidboy(Apic* apic)
|
|
|
|
{
|
|
|
|
machinit();
|
|
|
|
mmuinit();
|
|
|
|
cpuidentify();
|
|
|
|
cpuidprint();
|
2017-03-11 15:24:56 +00:00
|
|
|
syncclock();
|
|
|
|
active.machs[m->machno] = 1;
|
2014-02-01 09:25:10 +00:00
|
|
|
apic->online = 1;
|
|
|
|
lapicinit(apic);
|
|
|
|
lapiconline();
|
|
|
|
timersinit();
|
2017-11-07 23:34:08 +00:00
|
|
|
_stts();
|
2014-02-01 09:25:10 +00:00
|
|
|
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)];
|
2014-02-15 05:17:05 +00:00
|
|
|
pml4[PTLX(VMAP, 3)] = MACHP(0)->pml4[PTLX(VMAP, 3)];
|
2014-02-01 09:25:10 +00:00
|
|
|
|
|
|
|
/* 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;
|
2019-08-29 05:35:22 +00:00
|
|
|
apbootp[4] |= (uintptr)m->havenx<<11; /* EFER */
|
2014-02-01 09:25:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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));
|
2017-03-11 15:24:56 +00:00
|
|
|
for(i = 0; i < 100000; i++){
|
|
|
|
if(arch->fastclock == tscticks)
|
|
|
|
cycles(&m->tscticks); /* for ap's syncclock(); */
|
2014-02-01 09:25:10 +00:00
|
|
|
if(apic->online)
|
|
|
|
break;
|
2017-03-11 15:24:56 +00:00
|
|
|
delay(1);
|
2014-02-01 09:25:10 +00:00
|
|
|
}
|
|
|
|
nvramwrite(0x0F, 0x00);
|
|
|
|
}
|