summaryrefslogtreecommitdiff
path: root/sys/src/9/pc64
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-11-20 19:05:43 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2014-11-20 19:05:43 +0100
commit529082d34d2bafd81d5987a2ed646c3a3c88a0a2 (patch)
tree72e78cefad3f628729ffacaec80a515bda77c27d /sys/src/9/pc64
parent5a6131ea0919726bee4cba03a7a5361e6ea6df92 (diff)
pc, pc64: preserve last KB of conventional memory (might contain bios tables)
we add new function convmemsize() that returns the size of *usable* conventional memory that does some sanity checking and reserves the last KB below the top of memory pointer. this avoids lowraminit() overriding potential bios tables and sigsearch() going off the rails looking for tables at above 640K.
Diffstat (limited to 'sys/src/9/pc64')
-rw-r--r--sys/src/9/pc64/memory.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/sys/src/9/pc64/memory.c b/sys/src/9/pc64/memory.c
index 349133976..cb2c15219 100644
--- a/sys/src/9/pc64/memory.c
+++ b/sys/src/9/pc64/memory.c
@@ -337,6 +337,24 @@ sigscan(uchar* addr, int len, char* signature)
return nil;
}
+static uintptr
+convmemsize(void)
+{
+ uintptr top;
+ uchar *bda;
+
+ bda = KADDR(0x400);
+ top = ((bda[0x14]<<8) | bda[0x13])*KB;
+
+ if(top < 64*KB || top > 640*KB)
+ top = 640*KB; /* sanity */
+
+ /* reserved for bios tables (EBDA) */
+ top -= 1*KB;
+
+ return top;
+}
+
void*
sigsearch(char* signature)
{
@@ -359,11 +377,9 @@ sigsearch(char* signature)
return r;
}
}
+ if((r = sigscan(KADDR(convmemsize()), 1024, signature)) != nil)
+ return r;
- if((p = ((bda[0x14]<<8)|bda[0x13])*1024) != 0){
- if((r = sigscan(KADDR(p-1024), 1024, signature)) != nil)
- return r;
- }
/* hack for virtualbox: look in KiB below 0xa0000 */
if((r = sigscan(KADDR(0xa0000-1024), 1024, signature)) != nil)
return r;
@@ -375,7 +391,6 @@ static void
lowraminit(void)
{
uintptr pa, x;
- uchar *bda;
/*
* Initialise the memory bank information for conventional memory
@@ -384,10 +399,7 @@ lowraminit(void)
* the BIOS data area.
*/
x = PADDR(CPU0END);
- bda = (uchar*)KADDR(0x400);
- pa = ((bda[0x14]<<8)|bda[0x13])*KB;
- if(pa > 640*KB)
- pa = 640*KB;
+ pa = convmemsize();
if(x < pa){
mapfree(&rmapram, x, pa-x);
memset(KADDR(x), 0, pa-x); /* keep us honest */