archmp: checksum _MP_ structure before use, coherence() and comments (import from sources)

we used to only test the checksum of the PCMP structure referenced by
the _MP_ without checking _MP_ itself. now fixed.

geoff added some coherence() calls and comments in the mpstartup and
apic code which seems to be a good idea.
This commit is contained in:
cinap_lenrek 2012-08-25 14:06:42 +02:00
parent 69f5a04ac3
commit 19219d5a95
3 changed files with 12 additions and 5 deletions

View file

@ -242,6 +242,7 @@ lapicstartap(Apic* apic, int v)
int i; int i;
ulong crhi; ulong crhi;
/* make apic's processor do a warm reset */
crhi = apic->apicno<<24; crhi = apic->apicno<<24;
lapicw(LapicICRHI, crhi); lapicw(LapicICRHI, crhi);
lapicw(LapicICRLO, LapicFIELD|ApicLEVEL|LapicASSERT|ApicINIT); lapicw(LapicICRLO, LapicFIELD|ApicLEVEL|LapicASSERT|ApicINIT);
@ -249,8 +250,10 @@ lapicstartap(Apic* apic, int v)
lapicw(LapicICRLO, LapicFIELD|ApicLEVEL|LapicDEASSERT|ApicINIT); lapicw(LapicICRLO, LapicFIELD|ApicLEVEL|LapicDEASSERT|ApicINIT);
delay(10); delay(10);
/* assumes apic is not an 82489dx */
for(i = 0; i < 2; i++){ for(i = 0; i < 2; i++){
lapicw(LapicICRHI, crhi); lapicw(LapicICRHI, crhi);
/* make apic's processor start at v in real mode */
lapicw(LapicICRLO, LapicFIELD|ApicEDGE|ApicSTARTUP|(v/BY2PG)); lapicw(LapicICRLO, LapicFIELD|ApicEDGE|ApicSTARTUP|(v/BY2PG));
microdelay(200); microdelay(200);
} }

View file

@ -384,11 +384,12 @@ 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 || _mp_->physaddr == 0) if((_mp_ = sigsearch("_MP_")) == 0 || checksum(_mp_, sizeof(_MP_)) ||
(_mp_->physaddr == 0))
return 1; return 1;
pcmp = KADDR(_mp_->physaddr); pcmp = KADDR(_mp_->physaddr);
if(memcmp(pcmp, "PCMP", 4) || checksum(pcmp, pcmp->length) || if(memcmp(pcmp, "PCMP", 4) || checksum(pcmp, pcmp->length) ||
(pcmp->version != 1 && pcmp->version != 4)) { (pcmp->version != 1 && pcmp->version != 4)) {
pcmp = nil; pcmp = nil;
return 1; return 1;

View file

@ -185,6 +185,7 @@ squidboy(Apic* apic)
checkmtrr(); checkmtrr();
apic->online = 1; apic->online = 1;
coherence();
lapicinit(apic); lapicinit(apic);
lapiconline(); lapiconline();
@ -251,14 +252,14 @@ mpstartap(Apic* apic)
* The offsets are known in the AP bootstrap code. * The offsets are known in the AP bootstrap code.
*/ */
apbootp = (ulong*)(APBOOTSTRAP+0x08); apbootp = (ulong*)(APBOOTSTRAP+0x08);
*apbootp++ = (ulong)squidboy; *apbootp++ = (ulong)squidboy; /* assembler jumps here eventually */
*apbootp++ = PADDR(pdb); *apbootp++ = PADDR(pdb);
*apbootp = (ulong)apic; *apbootp = (ulong)apic;
/* /*
* Universal Startup Algorithm. * Universal Startup Algorithm.
*/ */
p = KADDR(0x467); p = KADDR(0x467); /* warm-reset vector */
*p++ = PADDR(APBOOTSTRAP); *p++ = PADDR(APBOOTSTRAP);
*p++ = PADDR(APBOOTSTRAP)>>8; *p++ = PADDR(APBOOTSTRAP)>>8;
i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16; i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
@ -267,8 +268,9 @@ mpstartap(Apic* apic)
print("mp: bad APBOOTSTRAP\n"); print("mp: bad APBOOTSTRAP\n");
*p++ = i; *p++ = i;
*p = i>>8; *p = i>>8;
coherence();
nvramwrite(0x0F, 0x0A); nvramwrite(0x0F, 0x0A); /* shutdown code: warm reset upon init ipi */
lapicstartap(apic, PADDR(APBOOTSTRAP)); lapicstartap(apic, PADDR(APBOOTSTRAP));
for(i = 0; i < 1000; i++){ for(i = 0; i < 1000; i++){
if(apic->online) if(apic->online)
@ -327,6 +329,7 @@ mpinit(void)
return; return;
} }
apic->online = 1; apic->online = 1;
lapicinit(apic); lapicinit(apic);
/* /*