plan9fox/sys/src/9/pc64/squidboy.c
cinap_lenrek 20ea113790 kernel: support large 64-bit pci membars, increase pc64 VMAPSIZE to 1TB
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.
2021-11-26 20:51:45 +00:00

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);
}