pc kernel: split mpstartap() and squidboy into separate file... stuff for amd64
This commit is contained in:
parent
06bc19c28f
commit
28ad4e6616
11 changed files with 165 additions and 131 deletions
|
@ -501,7 +501,7 @@ Foundapic:
|
||||||
e = p + tbldlen(t);
|
e = p + tbldlen(t);
|
||||||
lapicbase = get32(p); p += 8;
|
lapicbase = get32(p); p += 8;
|
||||||
va = vmap(lapicbase, 1024);
|
va = vmap(lapicbase, 1024);
|
||||||
print("LAPIC: %.8lux %.8lux\n", lapicbase, (ulong)va);
|
print("LAPIC: %.8lux %#p\n", lapicbase, va);
|
||||||
if(va == nil)
|
if(va == nil)
|
||||||
panic("acpiinit: cannot map lapic %.8lux", lapicbase);
|
panic("acpiinit: cannot map lapic %.8lux", lapicbase);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ mpgetbus(int busno)
|
||||||
return bus;
|
return bus;
|
||||||
|
|
||||||
print("mpgetbus: can't find bus %d\n", busno);
|
print("mpgetbus: can't find bus %d\n", busno);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,11 +291,12 @@ pcmpinit(void)
|
||||||
* Map the local APIC.
|
* Map the local APIC.
|
||||||
*/
|
*/
|
||||||
va = vmap(pcmp->lapicbase, 1024);
|
va = vmap(pcmp->lapicbase, 1024);
|
||||||
print("LAPIC: %.8lux %.8lux\n", pcmp->lapicbase, (ulong)va);
|
|
||||||
|
print("LAPIC: %.8lux %#p\n", pcmp->lapicbase, va);
|
||||||
if(va == nil)
|
if(va == nil)
|
||||||
panic("pcmpinit: cannot map lapic %.8lux", pcmp->lapicbase);
|
panic("pcmpinit: cannot map lapic %.8lux", pcmp->lapicbase);
|
||||||
|
|
||||||
p = ((uchar*)pcmp)+sizeof(PCMP);
|
p = ((uchar*)pcmp)+PCMPsz;
|
||||||
e = ((uchar*)pcmp)+pcmp->length;
|
e = ((uchar*)pcmp)+pcmp->length;
|
||||||
if(getconf("*dumpmp") != nil)
|
if(getconf("*dumpmp") != nil)
|
||||||
dumpmp(p, e);
|
dumpmp(p, e);
|
||||||
|
@ -323,28 +323,28 @@ pcmpinit(void)
|
||||||
apic->addr = va;
|
apic->addr = va;
|
||||||
apic->paddr = pcmp->lapicbase;
|
apic->paddr = pcmp->lapicbase;
|
||||||
}
|
}
|
||||||
p += sizeof(PCMPprocessor);
|
p += PCMPprocessorsz;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case PcmpBUS:
|
case PcmpBUS:
|
||||||
mkbus((PCMPbus*)p);
|
mkbus((PCMPbus*)p);
|
||||||
p += sizeof(PCMPbus);
|
p += PCMPbussz;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case PcmpIOAPIC:
|
case PcmpIOAPIC:
|
||||||
if(apic = mkioapic((PCMPioapic*)p))
|
if(apic = mkioapic((PCMPioapic*)p))
|
||||||
ioapicinit(apic, apic->apicno);
|
ioapicinit(apic, apic->apicno);
|
||||||
p += sizeof(PCMPioapic);
|
p += PCMPioapicsz;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case PcmpIOINTR:
|
case PcmpIOINTR:
|
||||||
mkiointr((PCMPintr*)p);
|
mkiointr((PCMPintr*)p);
|
||||||
p += sizeof(PCMPintr);
|
p += PCMPintrsz;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case PcmpLINTR:
|
case PcmpLINTR:
|
||||||
mklintr((PCMPintr*)p);
|
mklintr((PCMPintr*)p);
|
||||||
p += sizeof(PCMPintr);
|
p += PCMPintrsz;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ identify(void)
|
||||||
* if correct, check the version.
|
* if correct, check the version.
|
||||||
* To do: check extended table checksum.
|
* To do: check extended table checksum.
|
||||||
*/
|
*/
|
||||||
if((_mp_ = sigsearch("_MP_")) == 0 || checksum(_mp_, sizeof(_MP_)) ||
|
if((_mp_ = sigsearch("_MP_")) == 0 || checksum(_mp_, _MP_sz) ||
|
||||||
(_mp_->physaddr == 0))
|
(_mp_->physaddr == 0))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
|
@ -759,7 +759,7 @@ cpuidentify(void)
|
||||||
char *p;
|
char *p;
|
||||||
int family, model, nomce;
|
int family, model, nomce;
|
||||||
X86type *t, *tab;
|
X86type *t, *tab;
|
||||||
ulong cr4;
|
uintptr cr4;
|
||||||
ulong regs[4];
|
ulong regs[4];
|
||||||
vlong mca, mct;
|
vlong mca, mct;
|
||||||
|
|
||||||
|
@ -804,6 +804,7 @@ cpuidentify(void)
|
||||||
wrmsr(0x10, 0);
|
wrmsr(0x10, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* use i8253 to guess our cpu speed
|
* use i8253 to guess our cpu speed
|
||||||
*/
|
*/
|
||||||
|
@ -815,7 +816,7 @@ cpuidentify(void)
|
||||||
* If machine check was enabled clear out any lingering status.
|
* If machine check was enabled clear out any lingering status.
|
||||||
*/
|
*/
|
||||||
if(m->cpuiddx & (Pge|Mce|Pse)){
|
if(m->cpuiddx & (Pge|Mce|Pse)){
|
||||||
cr4 = 0;
|
cr4 = getcr4();
|
||||||
if(m->cpuiddx & Pse)
|
if(m->cpuiddx & Pse)
|
||||||
cr4 |= 0x10; /* page size extensions */
|
cr4 |= 0x10; /* page size extensions */
|
||||||
if(p = getconf("*nomce"))
|
if(p = getconf("*nomce"))
|
||||||
|
@ -851,6 +852,7 @@ cpuidentify(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
putcr4(cr4);
|
putcr4(cr4);
|
||||||
|
|
||||||
if(m->cpuiddx & Mce)
|
if(m->cpuiddx & Mce)
|
||||||
rdmsr(0x01, &mct);
|
rdmsr(0x01, &mct);
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ dmasetup(int chan, void *va, long len, int flags)
|
||||||
* if this isn't kernel memory or crossing 64k boundary or above 16 meg
|
* if this isn't kernel memory or crossing 64k boundary or above 16 meg
|
||||||
* use the bounce buffer.
|
* use the bounce buffer.
|
||||||
*/
|
*/
|
||||||
if((ulong)va < KZERO
|
if((uintptr)va < KZERO
|
||||||
|| ((pa=PADDR(va))&0xFFFF0000) != ((pa+len)&0xFFFF0000)
|
|| ((pa=PADDR(va))&0xFFFF0000) != ((pa+len)&0xFFFF0000)
|
||||||
|| pa >= 16*MB){
|
|| pa >= 16*MB){
|
||||||
if(xp->bva == nil)
|
if(xp->bva == nil)
|
||||||
|
|
|
@ -1896,7 +1896,7 @@ setup(Ctlr *ctlr)
|
||||||
p = ctlr->pcidev;
|
p = ctlr->pcidev;
|
||||||
ctlr->nic = vmap(ctlr->port, p->mem[0].size);
|
ctlr->nic = vmap(ctlr->port, p->mem[0].size);
|
||||||
if(ctlr->nic == nil){
|
if(ctlr->nic == nil){
|
||||||
print("%s: can't map %#p\n", cname(ctlr), ctlr->port);
|
print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(i82563reset(ctlr)){
|
if(i82563reset(ctlr)){
|
||||||
|
|
|
@ -106,9 +106,11 @@ $AUDIO: ../port/audioif.h
|
||||||
ether8003.$O ether8390.$O: ether8390.h
|
ether8003.$O ether8390.$O: ether8390.h
|
||||||
etheryuk.$O: yukdump.h
|
etheryuk.$O: yukdump.h
|
||||||
$VGA mouse.$O: screen.h /sys/include/memdraw.h
|
$VGA mouse.$O: screen.h /sys/include/memdraw.h
|
||||||
|
vgavesa.$O: /386/include/ureg.h
|
||||||
devfloppy.$O: floppy.h
|
devfloppy.$O: floppy.h
|
||||||
archmp.$O mp.$O: apbootstrap.h
|
archmp.$O mp.$O: apbootstrap.h
|
||||||
apic.$O archmp.$O mp.$O: mp.h
|
apic.$O archmp.$O mp.$O: mp.h
|
||||||
|
squidboy.$O: mp.h
|
||||||
$SDEV: ../port/sd.h
|
$SDEV: ../port/sd.h
|
||||||
sd53c8xx.$O: sd53c8xx.i
|
sd53c8xx.$O: sd53c8xx.i
|
||||||
sdiahci.$O: ahci.h
|
sdiahci.$O: ahci.h
|
||||||
|
|
|
@ -90,7 +90,7 @@ mpintrinit(Bus* bus, PCMPintr* intr, int vno, int /*irq*/)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
checkmtrr(void)
|
checkmtrr(void)
|
||||||
{
|
{
|
||||||
int i, vcnt;
|
int i, vcnt;
|
||||||
|
@ -172,114 +172,6 @@ syncclock(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
squidboy(Apic* apic)
|
|
||||||
{
|
|
||||||
// iprint("Hello Squidboy\n");
|
|
||||||
|
|
||||||
machinit();
|
|
||||||
mmuinit();
|
|
||||||
|
|
||||||
cpuidentify();
|
|
||||||
cpuidprint();
|
|
||||||
checkmtrr();
|
|
||||||
|
|
||||||
apic->online = 1;
|
|
||||||
coherence();
|
|
||||||
|
|
||||||
lapicinit(apic);
|
|
||||||
lapiconline();
|
|
||||||
syncclock();
|
|
||||||
timersinit();
|
|
||||||
|
|
||||||
fpoff();
|
|
||||||
|
|
||||||
lock(&active);
|
|
||||||
active.machs |= 1<<m->machno;
|
|
||||||
unlock(&active);
|
|
||||||
|
|
||||||
while(!active.thunderbirdsarego)
|
|
||||||
microdelay(100);
|
|
||||||
|
|
||||||
schedinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
mpstartap(Apic* apic)
|
|
||||||
{
|
|
||||||
ulong *apbootp, *pdb, *pte;
|
|
||||||
Mach *mach, *mach0;
|
|
||||||
int i, machno;
|
|
||||||
uchar *p;
|
|
||||||
|
|
||||||
mach0 = MACHP(0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialise the AP page-tables and Mach structure. The page-tables
|
|
||||||
* are the same as for the bootstrap processor with the exception of
|
|
||||||
* the PTE for the Mach structure.
|
|
||||||
* Xspanalloc will panic if an allocation can't be made.
|
|
||||||
*/
|
|
||||||
p = xspanalloc(4*BY2PG, BY2PG, 0);
|
|
||||||
pdb = (ulong*)p;
|
|
||||||
memmove(pdb, mach0->pdb, BY2PG);
|
|
||||||
p += BY2PG;
|
|
||||||
|
|
||||||
if((pte = mmuwalk(pdb, MACHADDR, 1, 0)) == nil)
|
|
||||||
return;
|
|
||||||
memmove(p, KADDR(PPN(*pte)), BY2PG);
|
|
||||||
*pte = PADDR(p)|PTEWRITE|PTEVALID;
|
|
||||||
if(mach0->havepge)
|
|
||||||
*pte |= PTEGLOBAL;
|
|
||||||
p += BY2PG;
|
|
||||||
|
|
||||||
mach = (Mach*)p;
|
|
||||||
if((pte = mmuwalk(pdb, MACHADDR, 2, 0)) == nil)
|
|
||||||
return;
|
|
||||||
*pte = PADDR(mach)|PTEWRITE|PTEVALID;
|
|
||||||
if(mach0->havepge)
|
|
||||||
*pte |= PTEGLOBAL;
|
|
||||||
p += BY2PG;
|
|
||||||
|
|
||||||
machno = apic->machno;
|
|
||||||
MACHP(machno) = mach;
|
|
||||||
mach->machno = machno;
|
|
||||||
mach->pdb = pdb;
|
|
||||||
mach->gdt = (Segdesc*)p; /* filled by mmuinit */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tell the AP where its kernel vector and pdb are.
|
|
||||||
* The offsets are known in the AP bootstrap code.
|
|
||||||
*/
|
|
||||||
apbootp = (ulong*)(APBOOTSTRAP+0x08);
|
|
||||||
*apbootp++ = (ulong)squidboy; /* assembler jumps here eventually */
|
|
||||||
*apbootp++ = PADDR(pdb);
|
|
||||||
*apbootp = (ulong)apic;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mpinit(void)
|
mpinit(void)
|
||||||
{
|
{
|
||||||
|
@ -297,11 +189,11 @@ mpinit(void)
|
||||||
|
|
||||||
for(i=0; i<=MaxAPICNO; i++){
|
for(i=0; i<=MaxAPICNO; i++){
|
||||||
if(apic = mpapic[i])
|
if(apic = mpapic[i])
|
||||||
print("LAPIC%d: pa=%lux va=%lux flags=%x\n",
|
print("LAPIC%d: pa=%lux va=%#p flags=%x\n",
|
||||||
i, apic->paddr, (ulong)apic->addr, apic->flags);
|
i, apic->paddr, apic->addr, apic->flags);
|
||||||
if(apic = mpioapic[i])
|
if(apic = mpioapic[i])
|
||||||
print("IOAPIC%d: pa=%lux va=%lux flags=%x gsibase=%d mre=%d\n",
|
print("IOAPIC%d: pa=%lux va=%#p flags=%x gsibase=%d mre=%d\n",
|
||||||
i, apic->paddr, (ulong)apic->addr, apic->flags, apic->gsibase, apic->mre);
|
i, apic->paddr, apic->addr, apic->flags, apic->gsibase, apic->mre);
|
||||||
}
|
}
|
||||||
for(b = mpbus; b; b = b->next){
|
for(b = mpbus; b; b = b->next){
|
||||||
print("BUS%d type=%d flags=%x\n", b->busno, b->type, b->po|b->el);
|
print("BUS%d type=%d flags=%x\n", b->busno, b->type, b->po|b->el);
|
||||||
|
|
|
@ -12,6 +12,8 @@ typedef struct { /* floating pointer */
|
||||||
uchar reserved[3];
|
uchar reserved[3];
|
||||||
} _MP_;
|
} _MP_;
|
||||||
|
|
||||||
|
#define _MP_sz (4+4+1+1+1+1+1+3)
|
||||||
|
|
||||||
typedef struct { /* configuration table header */
|
typedef struct { /* configuration table header */
|
||||||
uchar signature[4]; /* "PCMP" */
|
uchar signature[4]; /* "PCMP" */
|
||||||
ushort length; /* total table length */
|
ushort length; /* total table length */
|
||||||
|
@ -27,6 +29,8 @@ typedef struct { /* configuration table header */
|
||||||
uchar reserved;
|
uchar reserved;
|
||||||
} PCMP;
|
} PCMP;
|
||||||
|
|
||||||
|
#define PCMPsz (4+2+1+1+20+4+2+2+4+2+1+1)
|
||||||
|
|
||||||
typedef struct { /* processor table entry */
|
typedef struct { /* processor table entry */
|
||||||
uchar type; /* entry type (0) */
|
uchar type; /* entry type (0) */
|
||||||
uchar apicno; /* local APIC id */
|
uchar apicno; /* local APIC id */
|
||||||
|
@ -37,12 +41,16 @@ typedef struct { /* processor table entry */
|
||||||
uchar reserved[8];
|
uchar reserved[8];
|
||||||
} PCMPprocessor;
|
} PCMPprocessor;
|
||||||
|
|
||||||
|
#define PCMPprocessorsz (1+1+1+1+4+4+8)
|
||||||
|
|
||||||
typedef struct { /* bus table entry */
|
typedef struct { /* bus table entry */
|
||||||
uchar type; /* entry type (1) */
|
uchar type; /* entry type (1) */
|
||||||
uchar busno; /* bus id */
|
uchar busno; /* bus id */
|
||||||
char string[6]; /* bus type string */
|
char string[6]; /* bus type string */
|
||||||
} PCMPbus;
|
} PCMPbus;
|
||||||
|
|
||||||
|
#define PCMPbussz (1+1+6)
|
||||||
|
|
||||||
typedef struct { /* I/O APIC table entry */
|
typedef struct { /* I/O APIC table entry */
|
||||||
uchar type; /* entry type (2) */
|
uchar type; /* entry type (2) */
|
||||||
uchar apicno; /* I/O APIC id */
|
uchar apicno; /* I/O APIC id */
|
||||||
|
@ -51,6 +59,8 @@ typedef struct { /* I/O APIC table entry */
|
||||||
ulong addr; /* I/O APIC address */
|
ulong addr; /* I/O APIC address */
|
||||||
} PCMPioapic;
|
} PCMPioapic;
|
||||||
|
|
||||||
|
#define PCMPioapicsz (1+1+1+1+4)
|
||||||
|
|
||||||
typedef struct { /* interrupt table entry */
|
typedef struct { /* interrupt table entry */
|
||||||
uchar type; /* entry type ([34]) */
|
uchar type; /* entry type ([34]) */
|
||||||
uchar intr; /* interrupt type */
|
uchar intr; /* interrupt type */
|
||||||
|
@ -61,6 +71,8 @@ typedef struct { /* interrupt table entry */
|
||||||
uchar intin; /* destination APIC [L]INTIN# */
|
uchar intin; /* destination APIC [L]INTIN# */
|
||||||
} PCMPintr;
|
} PCMPintr;
|
||||||
|
|
||||||
|
#define PCMPintrsz (1+1+2+1+1+1+1)
|
||||||
|
|
||||||
typedef struct { /* system address space mapping entry */
|
typedef struct { /* system address space mapping entry */
|
||||||
uchar type; /* entry type (128) */
|
uchar type; /* entry type (128) */
|
||||||
uchar length; /* of this entry (20) */
|
uchar length; /* of this entry (20) */
|
||||||
|
@ -70,6 +82,8 @@ typedef struct { /* system address space mapping entry */
|
||||||
ulong addrlength[2];
|
ulong addrlength[2];
|
||||||
} PCMPsasm;
|
} PCMPsasm;
|
||||||
|
|
||||||
|
#define PCMPsasmsz (1+1+1+1+8+8)
|
||||||
|
|
||||||
typedef struct { /* bus hierarchy descriptor entry */
|
typedef struct { /* bus hierarchy descriptor entry */
|
||||||
uchar type; /* entry type (129) */
|
uchar type; /* entry type (129) */
|
||||||
uchar length; /* of this entry (8) */
|
uchar length; /* of this entry (8) */
|
||||||
|
@ -79,6 +93,8 @@ typedef struct { /* bus hierarchy descriptor entry */
|
||||||
uchar reserved[3];
|
uchar reserved[3];
|
||||||
} PCMPhierarchy;
|
} PCMPhierarchy;
|
||||||
|
|
||||||
|
#define PCMPhirarchysz (1+1+1+1+1+3)
|
||||||
|
|
||||||
typedef struct { /* compatibility bus address space modifier entry */
|
typedef struct { /* compatibility bus address space modifier entry */
|
||||||
uchar type; /* entry type (130) */
|
uchar type; /* entry type (130) */
|
||||||
uchar length; /* of this entry (8) */
|
uchar length; /* of this entry (8) */
|
||||||
|
@ -87,6 +103,8 @@ typedef struct { /* compatibility bus address space modifier entry */
|
||||||
ulong range; /* predefined range list */
|
ulong range; /* predefined range list */
|
||||||
} PCMPcbasm;
|
} PCMPcbasm;
|
||||||
|
|
||||||
|
#define PCMPcbasmsz (1+1+1+1+4)
|
||||||
|
|
||||||
enum { /* table entry types */
|
enum { /* table entry types */
|
||||||
PcmpPROCESSOR = 0x00, /* one entry per processor */
|
PcmpPROCESSOR = 0x00, /* one entry per processor */
|
||||||
PcmpBUS = 0x01, /* one entry per bus */
|
PcmpBUS = 0x01, /* one entry per bus */
|
||||||
|
@ -233,6 +251,7 @@ extern int mpintrinit(Bus*, PCMPintr*, int, int);
|
||||||
extern void mpinit(void);
|
extern void mpinit(void);
|
||||||
extern int mpintrenable(Vctl*);
|
extern int mpintrenable(Vctl*);
|
||||||
extern void mpshutdown(void);
|
extern void mpshutdown(void);
|
||||||
|
extern void mpstartap(Apic*);
|
||||||
|
|
||||||
extern Bus* mpbus;
|
extern Bus* mpbus;
|
||||||
extern Bus* mpbuslast;
|
extern Bus* mpbuslast;
|
||||||
|
|
|
@ -82,8 +82,8 @@ link
|
||||||
audiohda
|
audiohda
|
||||||
|
|
||||||
misc
|
misc
|
||||||
archacpi mp apic
|
archacpi mp apic squidboy
|
||||||
archmp mp apic
|
archmp mp apic squidboy
|
||||||
mtrr
|
mtrr
|
||||||
|
|
||||||
uarti8250
|
uarti8250
|
||||||
|
|
|
@ -84,8 +84,8 @@ link
|
||||||
audiohda
|
audiohda
|
||||||
|
|
||||||
misc
|
misc
|
||||||
archacpi mp apic
|
archacpi mp apic squidboy
|
||||||
archmp mp apic
|
archmp mp apic squidboy
|
||||||
mtrr
|
mtrr
|
||||||
|
|
||||||
sdaoe
|
sdaoe
|
||||||
|
|
119
sys/src/9/pc/squidboy.c
Normal file
119
sys/src/9/pc/squidboy.c
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
// iprint("Hello Squidboy\n");
|
||||||
|
|
||||||
|
machinit();
|
||||||
|
mmuinit();
|
||||||
|
|
||||||
|
cpuidentify();
|
||||||
|
cpuidprint();
|
||||||
|
checkmtrr();
|
||||||
|
|
||||||
|
apic->online = 1;
|
||||||
|
coherence();
|
||||||
|
|
||||||
|
lapicinit(apic);
|
||||||
|
lapiconline();
|
||||||
|
syncclock();
|
||||||
|
timersinit();
|
||||||
|
|
||||||
|
fpoff();
|
||||||
|
|
||||||
|
lock(&active);
|
||||||
|
active.machs |= 1<<m->machno;
|
||||||
|
unlock(&active);
|
||||||
|
|
||||||
|
while(!active.thunderbirdsarego)
|
||||||
|
microdelay(100);
|
||||||
|
|
||||||
|
schedinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpstartap(Apic* apic)
|
||||||
|
{
|
||||||
|
ulong *apbootp, *pdb, *pte;
|
||||||
|
Mach *mach, *mach0;
|
||||||
|
int i, machno;
|
||||||
|
uchar *p;
|
||||||
|
|
||||||
|
mach0 = MACHP(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the AP page-tables and Mach structure. The page-tables
|
||||||
|
* are the same as for the bootstrap processor with the exception of
|
||||||
|
* the PTE for the Mach structure.
|
||||||
|
* Xspanalloc will panic if an allocation can't be made.
|
||||||
|
*/
|
||||||
|
p = xspanalloc(4*BY2PG, BY2PG, 0);
|
||||||
|
pdb = (ulong*)p;
|
||||||
|
memmove(pdb, mach0->pdb, BY2PG);
|
||||||
|
p += BY2PG;
|
||||||
|
|
||||||
|
if((pte = mmuwalk(pdb, MACHADDR, 1, 0)) == nil)
|
||||||
|
return;
|
||||||
|
memmove(p, KADDR(PPN(*pte)), BY2PG);
|
||||||
|
*pte = PADDR(p)|PTEWRITE|PTEVALID;
|
||||||
|
if(mach0->havepge)
|
||||||
|
*pte |= PTEGLOBAL;
|
||||||
|
p += BY2PG;
|
||||||
|
|
||||||
|
mach = (Mach*)p;
|
||||||
|
if((pte = mmuwalk(pdb, MACHADDR, 2, 0)) == nil)
|
||||||
|
return;
|
||||||
|
*pte = PADDR(mach)|PTEWRITE|PTEVALID;
|
||||||
|
if(mach0->havepge)
|
||||||
|
*pte |= PTEGLOBAL;
|
||||||
|
p += BY2PG;
|
||||||
|
|
||||||
|
machno = apic->machno;
|
||||||
|
MACHP(machno) = mach;
|
||||||
|
mach->machno = machno;
|
||||||
|
mach->pdb = pdb;
|
||||||
|
mach->gdt = (Segdesc*)p; /* filled by mmuinit */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tell the AP where its kernel vector and pdb are.
|
||||||
|
* The offsets are known in the AP bootstrap code.
|
||||||
|
*/
|
||||||
|
apbootp = (ulong*)(APBOOTSTRAP+0x08);
|
||||||
|
*apbootp++ = (ulong)squidboy; /* assembler jumps here eventually */
|
||||||
|
*apbootp++ = PADDR(pdb);
|
||||||
|
*apbootp = (ulong)apic;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
Loading…
Reference in a new issue