shithub: riscv

Download patch

ref: 4e8494aad79a124f2b15ede9e7873fed46e1bb0a
parent: 152159a8297a7595b4455c03361851d354288177
author: cinap_lenrek <[email protected]>
date: Sat Mar 25 00:08:14 EDT 2017

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.

--- a/sys/src/9/pc/archacpi.c
+++ b/sys/src/9/pc/archacpi.c
@@ -789,6 +789,8 @@
 	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)
--- a/sys/src/9/pc/archmp.c
+++ b/sys/src/9/pc/archmp.c
@@ -383,6 +383,7 @@
 {
 	char *cp;
 	_MP_ *_mp_;
+	ulong len;
 
 	if((cp = getconf("*nomp")) != nil && strcmp(cp, "0") != 0)
 		return 1;
@@ -394,16 +395,32 @@
 	 * 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;
--- a/sys/src/9/pc/dat.h
+++ b/sys/src/9/pc/dat.h
@@ -267,6 +267,8 @@
 KMap*	kmap(Page*);
 void	kunmap(KMap*);
 
+extern u32int MemMin;
+
 struct
 {
 	char	machs[MAXMACH];		/* active CPUs */
--- a/sys/src/9/pc64/dat.h
+++ b/sys/src/9/pc64/dat.h
@@ -230,6 +230,8 @@
 typedef void KMap;
 #define	VA(k)		((void*)k)
 
+extern u32int MemMin;
+
 struct
 {
 	char	machs[MAXMACH];		/* bitmap of active CPUs */