summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-08-25 14:06:42 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-08-25 14:06:42 +0200
commit19219d5a9552171887f4d7e314b25bae2d3fc2f8 (patch)
tree5afa23cc863cfffb528a3ec78c7a5acbe403344a
parent69f5a04ac39f63f0b16df41cc268b3227b5cac99 (diff)
downloadplan9front-19219d5a9552171887f4d7e314b25bae2d3fc2f8.tar.xz
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.
-rw-r--r--sys/src/9/pc/apic.c3
-rw-r--r--sys/src/9/pc/archmp.c5
-rw-r--r--sys/src/9/pc/mp.c9
3 files changed, 12 insertions, 5 deletions
diff --git a/sys/src/9/pc/apic.c b/sys/src/9/pc/apic.c
index 0788e5adf..eada39531 100644
--- a/sys/src/9/pc/apic.c
+++ b/sys/src/9/pc/apic.c
@@ -242,6 +242,7 @@ lapicstartap(Apic* apic, int v)
int i;
ulong crhi;
+ /* make apic's processor do a warm reset */
crhi = apic->apicno<<24;
lapicw(LapicICRHI, crhi);
lapicw(LapicICRLO, LapicFIELD|ApicLEVEL|LapicASSERT|ApicINIT);
@@ -249,8 +250,10 @@ lapicstartap(Apic* apic, int v)
lapicw(LapicICRLO, LapicFIELD|ApicLEVEL|LapicDEASSERT|ApicINIT);
delay(10);
+ /* assumes apic is not an 82489dx */
for(i = 0; i < 2; i++){
lapicw(LapicICRHI, crhi);
+ /* make apic's processor start at v in real mode */
lapicw(LapicICRLO, LapicFIELD|ApicEDGE|ApicSTARTUP|(v/BY2PG));
microdelay(200);
}
diff --git a/sys/src/9/pc/archmp.c b/sys/src/9/pc/archmp.c
index 3247e04f5..bbde765a0 100644
--- a/sys/src/9/pc/archmp.c
+++ b/sys/src/9/pc/archmp.c
@@ -384,11 +384,12 @@ identify(void)
* if correct, check the version.
* 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;
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 = nil;
return 1;
diff --git a/sys/src/9/pc/mp.c b/sys/src/9/pc/mp.c
index c53d2b089..27eee1da6 100644
--- a/sys/src/9/pc/mp.c
+++ b/sys/src/9/pc/mp.c
@@ -185,6 +185,7 @@ squidboy(Apic* apic)
checkmtrr();
apic->online = 1;
+ coherence();
lapicinit(apic);
lapiconline();
@@ -251,14 +252,14 @@ mpstartap(Apic* apic)
* The offsets are known in the AP bootstrap code.
*/
apbootp = (ulong*)(APBOOTSTRAP+0x08);
- *apbootp++ = (ulong)squidboy;
+ *apbootp++ = (ulong)squidboy; /* assembler jumps here eventually */
*apbootp++ = PADDR(pdb);
*apbootp = (ulong)apic;
/*
* Universal Startup Algorithm.
*/
- p = KADDR(0x467);
+ p = KADDR(0x467); /* warm-reset vector */
*p++ = PADDR(APBOOTSTRAP);
*p++ = PADDR(APBOOTSTRAP)>>8;
i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
@@ -267,8 +268,9 @@ mpstartap(Apic* apic)
print("mp: bad APBOOTSTRAP\n");
*p++ = i;
*p = i>>8;
+ coherence();
- nvramwrite(0x0F, 0x0A);
+ nvramwrite(0x0F, 0x0A); /* shutdown code: warm reset upon init ipi */
lapicstartap(apic, PADDR(APBOOTSTRAP));
for(i = 0; i < 1000; i++){
if(apic->online)
@@ -327,6 +329,7 @@ mpinit(void)
return;
}
apic->online = 1;
+
lapicinit(apic);
/*