From 4e8494aad79a124f2b15ede9e7873fed46e1bb0a Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 25 Mar 2017 04:08:14 +0100 Subject: 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. --- sys/src/9/pc/archacpi.c | 2 ++ sys/src/9/pc/archmp.c | 27 ++++++++++++++++++++++----- sys/src/9/pc/dat.h | 2 ++ 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 */ -- cgit v1.2.3