diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-03-25 04:08:14 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-03-25 04:08:14 +0100 |
commit | 4e8494aad79a124f2b15ede9e7873fed46e1bb0a (patch) | |
tree | db74a4ada9dc0542664fb64a6d3ade58ed2a35b6 /sys/src | |
parent | 152159a8297a7595b4455c03361851d354288177 (diff) |
pc kernel: handle PCMP and RSD being in low (kaddr) or reserved (vmap) memory
on thinkpad x1v4, the PCMP structure resides in upper reserved memory
pa=0xd7f49000 - while system memory ends at 0x0ffff000; so we have to
vmap() it instead of KADDR().
the RSD structure for ACPI might reside in low memory, so we sould
KADDR() in that case.
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/pc/archacpi.c | 2 | ||||
-rw-r--r-- | sys/src/9/pc/archmp.c | 27 | ||||
-rw-r--r-- | sys/src/9/pc/dat.h | 2 | ||||
-rw-r--r-- | sys/src/9/pc64/dat.h | 2 |
4 files changed, 28 insertions, 5 deletions
diff --git a/sys/src/9/pc/archacpi.c b/sys/src/9/pc/archacpi.c index a48d52799..39b6f3e2c 100644 --- a/sys/src/9/pc/archacpi.c +++ b/sys/src/9/pc/archacpi.c @@ -789,6 +789,8 @@ identify(void) pa = (uintptr)strtoull(cp, nil, 16); if(pa <= 1) rsd = sigsearch("RSD PTR "); + else if(pa < MemMin) + rsd = KADDR(pa); else rsd = vmap(pa, sizeof(Rsd)); if(rsd == nil) diff --git a/sys/src/9/pc/archmp.c b/sys/src/9/pc/archmp.c index 18e19e120..b331c27d6 100644 --- a/sys/src/9/pc/archmp.c +++ b/sys/src/9/pc/archmp.c @@ -383,6 +383,7 @@ identify(void) { char *cp; _MP_ *_mp_; + ulong len; if((cp = getconf("*nomp")) != nil && strcmp(cp, "0") != 0) return 1; @@ -394,16 +395,32 @@ identify(void) * if correct, check the version. * To do: check extended table checksum. */ - if((_mp_ = sigsearch("_MP_")) == 0 || checksum(_mp_, _MP_sz) || - (_mp_->physaddr == 0)) + if((_mp_ = sigsearch("_MP_")) == nil || checksum(_mp_, _MP_sz) != 0 || _mp_->physaddr == 0) return 1; - pcmp = KADDR(_mp_->physaddr); - if(memcmp(pcmp, "PCMP", 4) || checksum(pcmp, pcmp->length) || - (pcmp->version != 1 && pcmp->version != 4)) { + len = PCMPsz; + if(_mp_->physaddr < MemMin) + pcmp = KADDR(_mp_->physaddr); + else if((pcmp = vmap(_mp_->physaddr, len)) == nil) + return 1; + if(pcmp->length < len + || memcmp(pcmp, "PCMP", 4) != 0 + || (pcmp->version != 1 && pcmp->version != 4)){ +Bad: + if((uintptr)pcmp < KZERO) + vunmap(pcmp, len); pcmp = nil; return 1; } + len = pcmp->length; + if((uintptr)pcmp < KZERO) + vunmap(pcmp, PCMPsz); + if(_mp_->physaddr < MemMin) + pcmp = KADDR(_mp_->physaddr); + else if((pcmp = vmap(_mp_->physaddr, len)) == nil) + return 1; + if(checksum(pcmp, len) != 0) + goto Bad; if(m->havetsc && getconf("*notsc") == nil) archmp.fastclock = tscticks; diff --git a/sys/src/9/pc/dat.h b/sys/src/9/pc/dat.h index 6369f73de..35bf8b4d6 100644 --- a/sys/src/9/pc/dat.h +++ b/sys/src/9/pc/dat.h @@ -267,6 +267,8 @@ typedef struct KMap KMap; KMap* kmap(Page*); void kunmap(KMap*); +extern u32int MemMin; + struct { char machs[MAXMACH]; /* active CPUs */ diff --git a/sys/src/9/pc64/dat.h b/sys/src/9/pc64/dat.h index 4da598ff1..2a5029ca8 100644 --- a/sys/src/9/pc64/dat.h +++ b/sys/src/9/pc64/dat.h @@ -230,6 +230,8 @@ struct Mach typedef void KMap; #define VA(k) ((void*)k) +extern u32int MemMin; + struct { char machs[MAXMACH]; /* bitmap of active CPUs */ |