shithub: riscv

Download patch

ref: 0ad5929695507eb80f18e177f29f5c51697bcc23
parent: e0c8b9955de9fab16f65ad0471a696a2e8b2fe81
author: cinap_lenrek <cinap_lenrek@localhost>
date: Sat May 14 15:20:16 EDT 2011

9boot: add e820 scan to bootloader

--- a/sys/src/9/pc/memory.c
+++ b/sys/src/9/pc/memory.c
@@ -673,35 +673,51 @@
 	ulong cont, base, len;
 	uvlong last;
 	Emap *e;
+	char *s;
 
-	if(getconf("*norealmode") || getconf("*noe820scan"))
-		return -1;
-
-	cont = 0;
-	for(i=0; i<nelem(emap); i++){
-		memset(&u, 0, sizeof u);
-		u.ax = 0xE820;
-		u.bx = cont;
-		u.cx = 20;
-		u.dx = SMAP;
-		u.es = (PADDR(RMBUF)>>4)&0xF000;
-		u.di = PADDR(RMBUF)&0xFFFF;
-		u.trap = 0x15;
-		realmode(&u);
-		cont = u.bx;
-		if((u.flags&Carry) || u.ax != SMAP || u.cx != 20)
-			break;
-		e = &emap[nemap++];
-		*e = *(Emap*)RMBUF;
-		if(u.bx == 0)
-			break;
+	if((s = getconf("e820")) != nil){
+		for(nemap = 0; nemap < nelem(emap); nemap++){
+			if(*s == 0)
+				break;
+			e = emap + nemap;
+			e->base = strtoull(s, &s, 16);
+			if(*s != ' ')
+				break;
+			e->len = strtoull(s, &s, 16) - e->base;
+			if(*s != ' ' && *s != 0 || e->len >= 1ull<<32 || e->len == 0)
+				break;
+			e->type = Ememory;
+		}
+	}else{
+		if(getconf("*norealmode") || getconf("*noe820scan"))
+			return -1;
+		cont = 0;
+		for(i=0; i<nelem(emap); i++){
+			memset(&u, 0, sizeof u);
+			u.ax = 0xE820;
+			u.bx = cont;
+			u.cx = 20;
+			u.dx = SMAP;
+			u.es = (PADDR(RMBUF)>>4)&0xF000;
+			u.di = PADDR(RMBUF)&0xFFFF;
+			u.trap = 0x15;
+			realmode(&u);
+			cont = u.bx;
+			if((u.flags&Carry) || u.ax != SMAP || u.cx != 20)
+				break;
+			e = &emap[nemap++];
+			*e = *(Emap*)RMBUF;
+			if(u.bx == 0)
+				break;
+		}
 	}
+
 	if(nemap == 0)
 		return -1;
 	
 	qsort(emap, nemap, sizeof emap[0], emapcmp);
 
-	if(getconf("*noe820print") == nil){
+	if(s == nil && getconf("*noe820print") == nil){
 		for(i=0; i<nemap; i++){
 			e = &emap[i];
 			print("E820: %.8llux %.8llux ", e->base, e->base+e->len);
--- a/sys/src/boot/pc/apm.s
+++ b/sys/src/boot/pc/apm.s
@@ -7,19 +7,19 @@
 
 	PUSHR(rBX)
 	LWI(0x5300, rAX)
-	INT $0x15
+	BIOSCALL(0x15)
 	POPR(rBX)
 	JC noapm
 
 	PUSHR(rBX)
 	LWI(0x5304, rAX)
-	INT $0x15
+	BIOSCALL(0x15)
 	POPR(rBX)
 	CLC
 
 	/* connect */
 	LWI(0x5303, rAX)
-	INT $0x15
+	BIOSCALL(0x15)
 	JC noapm
 
 	OPSIZE; PUSHR(rSI)
--- /dev/null
+++ b/sys/src/boot/pc/e820.s
@@ -1,0 +1,20 @@
+#include "x16.h"
+#include "mem.h"
+
+TEXT e820(SB), $0
+	MOVL bx+4(SP), BX
+	MOVL p+8(SP), DI
+
+	MOVL $0xe820, AX
+	MOVL $0x534D4150, DX
+	CALL rmode16(SB)
+	LWI(24, rCX)
+	BIOSCALL(0x15)
+	JC _bad
+	CALL16(pmode32(SB))
+	MOVL BX, AX
+	RET
+_bad:
+	CALL16(pmode32(SB))
+	XORL AX, AX
+	RET
--- a/sys/src/boot/pc/fns.h
+++ b/sys/src/boot/pc/fns.h
@@ -9,8 +9,6 @@
 int getc(void);
 int gotc(void);
 void putc(int c);
-void a20(void);
-void apm(int id);
 void halt(void);
 void jump(void *pc);
 
--- a/sys/src/boot/pc/mkfile
+++ b/sys/src/boot/pc/mkfile
@@ -36,7 +36,7 @@
 	$LD -o $target -H3 -T0x0600 -l $prereq
 	ls -l $target
 
-9boot&:	l%.$O %.$O sub.$O apm.$O a20.$O
+9boot&:	l%.$O %.$O sub.$O apm.$O e820.$O a20.$O
 	$LD -o $target -H3 -T0x7c00 -l $prereq
 	ls -l $target
 
--- a/sys/src/boot/pc/sub.c
+++ b/sys/src/boot/pc/sub.c
@@ -235,6 +235,8 @@
 	*confend = 0;
 }
 
+void apm(int id);
+
 static void
 apmconf(int id)
 {
@@ -263,6 +265,73 @@
 	*confend++ = '\n';
 }
 
+ulong e820(ulong bx, void *p);
+
+static void
+e820conf(void)
+{
+	struct {
+		uvlong	base;
+		uvlong	len;
+		ulong	typ;
+		ulong	ext;
+	} e;
+	uvlong v;
+	ulong bx;
+	char *s;
+
+	memset(&e, 0, sizeof(e));
+	if((bx = e820(0, &e)) == 0)
+		return;
+
+	memmove(confend, "e820=", 5);
+	confend += 5;
+
+	do{
+		s = confend;
+		v = e.base;
+		addconfx("", 8, v>>32);
+		addconfx("", 8, v&0xffffffff);
+		v = e.base + e.len;
+		addconfx(" ", 8, v>>32);
+		addconfx("", 8, v&0xffffffff);
+
+		print(s);
+
+		switch(e.typ){
+		case 1:
+			print(" ram");
+			break;
+		case 2:
+			print(" reserved");
+			break;
+		case 3:
+			print(" acpi reclaim");
+			break;
+		case 4:
+			print(" acpi nvs");
+			break;
+		case 5:
+			print(" bad");
+			break;
+		default:
+			print(" ???");
+		}
+		print(crnl);
+
+		if(e.typ == 1 && (e.ext & 1) == 0)
+			*confend++ = ' ';
+		else
+			confend = s;
+		memset(&e, 0, sizeof(e));
+	} while(bx = e820(bx, &e));
+
+	*confend++ = '\n';
+	*confend = 0;
+}
+
+void a20(void);
+
 char*
 bootkern(void *f)
 {
@@ -269,6 +338,8 @@
 	uchar *e, *d, *t;
 	ulong n;
 	Exec ex;
+
+	e820conf();
 
 	a20();
 	if(readn(f, &ex, sizeof(ex)) != sizeof(ex))