20ea113790
This makes vmap()/vunmap() take a vlong size argument, and change the type of Pci.mem[].size to vlong as well. Even if vmap() wont support large mappings, it is nice to get the original unruncated value for error checking. pc64 needs a bigger VMAP window, as system76 pangolin puts the framebuffer at a physical address > 512GB.
114 lines
2.4 KiB
C
114 lines
2.4 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 _stts(void);
|
|
|
|
static void
|
|
squidboy(Apic* apic)
|
|
{
|
|
machinit();
|
|
mmuinit();
|
|
cpuidentify();
|
|
if(arch->clockinit)
|
|
arch->clockinit();
|
|
cpuidprint();
|
|
syncclock();
|
|
active.machs[m->machno] = 1;
|
|
apic->online = 1;
|
|
lapicinit(apic);
|
|
lapiconline();
|
|
timersinit();
|
|
_stts();
|
|
schedinit();
|
|
}
|
|
|
|
void
|
|
mpstartap(Apic* apic)
|
|
{
|
|
uintptr *apbootp, *pml4, *pdp0, v;
|
|
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.
|
|
*/
|
|
*mmuwalk(pml4, KZERO, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0);
|
|
for(v = VMAP; v < VMAP+VMAPSIZE; v += PGLSZ(3)){
|
|
mmuwalk(m->pml4, v, 2, 1); /* force create */
|
|
*mmuwalk(pml4, v, 3, 0) = *mmuwalk(m->pml4, v, 3, 0);
|
|
}
|
|
|
|
/* 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;
|
|
apbootp[4] |= (uintptr)m->havenx<<11; /* EFER */
|
|
|
|
/*
|
|
* 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);
|
|
}
|