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);
lapicbase = get32(p); p += 8;
va = vmap(lapicbase, 1024);
print("LAPIC: %.8lux %.8lux\n", lapicbase, (ulong)va);
print("LAPIC: %.8lux %#p\n", lapicbase, va);
if(va == nil)
panic("acpiinit: cannot map lapic %.8lux", lapicbase);

View file

@ -41,7 +41,6 @@ mpgetbus(int busno)
return bus;
print("mpgetbus: can't find bus %d\n", busno);
return 0;
}
@ -292,11 +291,12 @@ pcmpinit(void)
* Map the local APIC.
*/
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)
panic("pcmpinit: cannot map lapic %.8lux", pcmp->lapicbase);
p = ((uchar*)pcmp)+sizeof(PCMP);
p = ((uchar*)pcmp)+PCMPsz;
e = ((uchar*)pcmp)+pcmp->length;
if(getconf("*dumpmp") != nil)
dumpmp(p, e);
@ -323,28 +323,28 @@ pcmpinit(void)
apic->addr = va;
apic->paddr = pcmp->lapicbase;
}
p += sizeof(PCMPprocessor);
p += PCMPprocessorsz;
continue;
case PcmpBUS:
mkbus((PCMPbus*)p);
p += sizeof(PCMPbus);
p += PCMPbussz;
continue;
case PcmpIOAPIC:
if(apic = mkioapic((PCMPioapic*)p))
ioapicinit(apic, apic->apicno);
p += sizeof(PCMPioapic);
p += PCMPioapicsz;
continue;
case PcmpIOINTR:
mkiointr((PCMPintr*)p);
p += sizeof(PCMPintr);
p += PCMPintrsz;
continue;
case PcmpLINTR:
mklintr((PCMPintr*)p);
p += sizeof(PCMPintr);
p += PCMPintrsz;
continue;
}
@ -384,7 +384,7 @@ identify(void)
* if correct, check the version.
* 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))
return 1;

View file

@ -759,7 +759,7 @@ cpuidentify(void)
char *p;
int family, model, nomce;
X86type *t, *tab;
ulong cr4;
uintptr cr4;
ulong regs[4];
vlong mca, mct;
@ -804,6 +804,7 @@ cpuidentify(void)
wrmsr(0x10, 0);
}
/*
* use i8253 to guess our cpu speed
*/
@ -815,7 +816,7 @@ cpuidentify(void)
* If machine check was enabled clear out any lingering status.
*/
if(m->cpuiddx & (Pge|Mce|Pse)){
cr4 = 0;
cr4 = getcr4();
if(m->cpuiddx & Pse)
cr4 |= 0x10; /* page size extensions */
if(p = getconf("*nomce"))
@ -851,6 +852,7 @@ cpuidentify(void)
}
putcr4(cr4);
if(m->cpuiddx & Mce)
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
* use the bounce buffer.
*/
if((ulong)va < KZERO
if((uintptr)va < KZERO
|| ((pa=PADDR(va))&0xFFFF0000) != ((pa+len)&0xFFFF0000)
|| pa >= 16*MB){
if(xp->bva == nil)

View file

@ -1896,7 +1896,7 @@ setup(Ctlr *ctlr)
p = ctlr->pcidev;
ctlr->nic = vmap(ctlr->port, p->mem[0].size);
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;
}
if(i82563reset(ctlr)){

View file

@ -106,9 +106,11 @@ $AUDIO: ../port/audioif.h
ether8003.$O ether8390.$O: ether8390.h
etheryuk.$O: yukdump.h
$VGA mouse.$O: screen.h /sys/include/memdraw.h
vgavesa.$O: /386/include/ureg.h
devfloppy.$O: floppy.h
archmp.$O mp.$O: apbootstrap.h
apic.$O archmp.$O mp.$O: mp.h
squidboy.$O: mp.h
$SDEV: ../port/sd.h
sd53c8xx.$O: sd53c8xx.i
sdiahci.$O: ahci.h

View file

@ -90,7 +90,7 @@ mpintrinit(Bus* bus, PCMPintr* intr, int vno, int /*irq*/)
return v;
}
static void
void
checkmtrr(void)
{
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
mpinit(void)
{
@ -297,11 +189,11 @@ mpinit(void)
for(i=0; i<=MaxAPICNO; i++){
if(apic = mpapic[i])
print("LAPIC%d: pa=%lux va=%lux flags=%x\n",
i, apic->paddr, (ulong)apic->addr, apic->flags);
print("LAPIC%d: pa=%lux va=%#p flags=%x\n",
i, apic->paddr, apic->addr, apic->flags);
if(apic = mpioapic[i])
print("IOAPIC%d: pa=%lux va=%lux flags=%x gsibase=%d mre=%d\n",
i, apic->paddr, (ulong)apic->addr, apic->flags, apic->gsibase, apic->mre);
print("IOAPIC%d: pa=%lux va=%#p flags=%x gsibase=%d mre=%d\n",
i, apic->paddr, apic->addr, apic->flags, apic->gsibase, apic->mre);
}
for(b = mpbus; b; b = b->next){
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];
} _MP_;
#define _MP_sz (4+4+1+1+1+1+1+3)
typedef struct { /* configuration table header */
uchar signature[4]; /* "PCMP" */
ushort length; /* total table length */
@ -27,6 +29,8 @@ typedef struct { /* configuration table header */
uchar reserved;
} PCMP;
#define PCMPsz (4+2+1+1+20+4+2+2+4+2+1+1)
typedef struct { /* processor table entry */
uchar type; /* entry type (0) */
uchar apicno; /* local APIC id */
@ -37,12 +41,16 @@ typedef struct { /* processor table entry */
uchar reserved[8];
} PCMPprocessor;
#define PCMPprocessorsz (1+1+1+1+4+4+8)
typedef struct { /* bus table entry */
uchar type; /* entry type (1) */
uchar busno; /* bus id */
char string[6]; /* bus type string */
} PCMPbus;
#define PCMPbussz (1+1+6)
typedef struct { /* I/O APIC table entry */
uchar type; /* entry type (2) */
uchar apicno; /* I/O APIC id */
@ -51,6 +59,8 @@ typedef struct { /* I/O APIC table entry */
ulong addr; /* I/O APIC address */
} PCMPioapic;
#define PCMPioapicsz (1+1+1+1+4)
typedef struct { /* interrupt table entry */
uchar type; /* entry type ([34]) */
uchar intr; /* interrupt type */
@ -61,6 +71,8 @@ typedef struct { /* interrupt table entry */
uchar intin; /* destination APIC [L]INTIN# */
} PCMPintr;
#define PCMPintrsz (1+1+2+1+1+1+1)
typedef struct { /* system address space mapping entry */
uchar type; /* entry type (128) */
uchar length; /* of this entry (20) */
@ -70,6 +82,8 @@ typedef struct { /* system address space mapping entry */
ulong addrlength[2];
} PCMPsasm;
#define PCMPsasmsz (1+1+1+1+8+8)
typedef struct { /* bus hierarchy descriptor entry */
uchar type; /* entry type (129) */
uchar length; /* of this entry (8) */
@ -79,6 +93,8 @@ typedef struct { /* bus hierarchy descriptor entry */
uchar reserved[3];
} PCMPhierarchy;
#define PCMPhirarchysz (1+1+1+1+1+3)
typedef struct { /* compatibility bus address space modifier entry */
uchar type; /* entry type (130) */
uchar length; /* of this entry (8) */
@ -87,6 +103,8 @@ typedef struct { /* compatibility bus address space modifier entry */
ulong range; /* predefined range list */
} PCMPcbasm;
#define PCMPcbasmsz (1+1+1+1+4)
enum { /* table entry types */
PcmpPROCESSOR = 0x00, /* one entry per processor */
PcmpBUS = 0x01, /* one entry per bus */
@ -233,6 +251,7 @@ extern int mpintrinit(Bus*, PCMPintr*, int, int);
extern void mpinit(void);
extern int mpintrenable(Vctl*);
extern void mpshutdown(void);
extern void mpstartap(Apic*);
extern Bus* mpbus;
extern Bus* mpbuslast;

View file

@ -82,8 +82,8 @@ link
audiohda
misc
archacpi mp apic
archmp mp apic
archacpi mp apic squidboy
archmp mp apic squidboy
mtrr
uarti8250

View file

@ -84,8 +84,8 @@ link
audiohda
misc
archacpi mp apic
archmp mp apic
archacpi mp apic squidboy
archmp mp apic squidboy
mtrr
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);
}