pc kernel: split mpstartap() and squidboy into separate file... stuff for amd64

This commit is contained in:
cinap_lenrek 2014-02-01 10:23:17 +01:00
parent 06bc19c28f
commit 28ad4e6616
11 changed files with 165 additions and 131 deletions

View file

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

View file

@ -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;

View file

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

View file

@ -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)

View file

@ -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)){

View file

@ -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

View file

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

View file

@ -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;

View file

@ -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

View file

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