shithub: riscv

Download patch

ref: e0c8b9955de9fab16f65ad0471a696a2e8b2fe81
parent: b4f2bf77b3710306bf1965201d526154c9dbddb7
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Sat May 14 13:06:27 EDT 2011

9boot: add APM support

--- /dev/null
+++ b/sys/src/boot/pc/apm.s
@@ -1,0 +1,51 @@
+#include "x16.h"
+#include "mem.h"
+
+TEXT apm(SB), $0
+	MOVL id+4(SP), BX
+	CALL rmode16(SB)
+
+	PUSHR(rBX)
+	LWI(0x5300, rAX)
+	INT $0x15
+	POPR(rBX)
+	JC noapm
+
+	PUSHR(rBX)
+	LWI(0x5304, rAX)
+	INT $0x15
+	POPR(rBX)
+	CLC
+
+	/* connect */
+	LWI(0x5303, rAX)
+	INT $0x15
+	JC noapm
+
+	OPSIZE; PUSHR(rSI)
+	OPSIZE; PUSHR(rBX)
+	PUSHR(rDI)
+	PUSHR(rDX)
+	PUSHR(rCX)
+	PUSHR(rAX)
+
+	LWI(CONFADDR, rDI)
+
+	/*
+	 * write APM data.  first four bytes are APM\0.
+	 */
+	LWI(0x5041, rAX)
+	STOSW
+
+	LWI(0x004d, rAX)
+	STOSW
+
+	LWI(8, rCX)
+apmmove:
+	POPR(rAX)
+	STOSW
+	LOOP apmmove
+
+noapm:
+	CALL16(pmode32(SB))
+	RET
--- a/sys/src/boot/pc/fns.h
+++ b/sys/src/boot/pc/fns.h
@@ -10,6 +10,7 @@
 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/mem.h
+++ b/sys/src/boot/pc/mem.h
@@ -16,8 +16,8 @@
 /*
  * Fundamental addresses
  */
-#define CONFADDR	0x80001200		/* info passed from boot loader */
-#define BIOSXCHG	0x80006000		/* To exchange data with the BIOS */
+#define CONFADDR	0x1200		/* info passed from boot loader */
+#define BIOSXCHG	0x6000		/* To exchange data with the BIOS */
 
 #define SELGDT	(0<<3)	/* selector is in gdt */
 #define	SELLDT	(1<<3)	/* selector is in ldt */
--- 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 a20.$O
+9boot&:	l%.$O %.$O sub.$O apm.$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
@@ -129,18 +129,26 @@
 	return p - buf;
 }
 
+#define BOOTLINE	((char*)CONFADDR)
+#define BOOTLINELEN	64
+#define BOOTARGS	((char*)(CONFADDR+BOOTLINELEN))
+#define	BOOTARGSLEN	(4096-0x200-BOOTLINELEN)
+
+char *confend;
+
+static void apmconf(int);
+
 char*
 configure(void *f, char *path)
 {
-	char line[64], *p, *kern;
+	char line[64], *kern, *p;
 	int inblock, n;
-
 Clear:
 	kern = 0;
 	inblock = 0;
-	p = (char*)(CONFADDR & ~0xF0000000UL);
-	memset(p, 0, 0xE00);
-	p += 64;
+
+	confend = (char*)BOOTARGS;
+	memset(confend, 0, BOOTARGSLEN);
 Loop:
 	while((n = readline(f, line)) > 0){
 		if(*line == 0 || strchr("#;=", *line))
@@ -149,21 +157,25 @@
 			inblock = memcmp("[common]", line, 8);
 			continue;
 		}
-		if(memcmp("clear", line, 6) == 0){
+		if(!memcmp("clear", line, 6)){
 			print("ok\r\n");
 			goto Clear;
 		}
-		if(memcmp("boot", line, 5) == 0)
+		if(!memcmp("boot", line, 5))
 			break;
 		if(inblock || !strrchr(line, '='))
 			continue;
-		print(line); print(crnl);
-		if(memcmp("bootfile=", line, 9) == 0)
+		if(!memcmp("bootfile=", line, 9))
 			memmove(kern = path, line+9, 1 + n-9);
-		memmove(p, line, n); p += n;
-		*p++ = '\n';
+		if(!memcmp("apm", line, 3) && line[4]=='='){
+			apmconf('0' - line[3]);
+			continue;
+		}
+		memmove(confend, line, n); confend += n;
+		*confend++ = '\n';
+		print(line); print(crnl);
 	}
-	*p = 0;
+	*confend = 0;
 	if(f){
 		close(f);
 		f = 0;
@@ -177,6 +189,7 @@
 			goto Loop;
 	if(p = strrchr(kern, '!'))
 		kern = p+1;
+
 	return kern;
 }
 
@@ -199,6 +212,57 @@
 	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
 }
 
+static void
+hexfmt(char *s, int i, ulong a)
+{
+	s += i;
+	while(i > 0){
+		*--s = hex[a&15];
+		a >>= 4;
+		i--;
+	}
+}
+
+static void
+addconfx(char *s, int w, ulong v)
+{
+	int n;
+
+	n = strlen(s);
+	memmove(confend, s, n);
+	hexfmt(confend+n, w, v);
+	confend += n+w;
+	*confend = 0;
+}
+
+static void
+apmconf(int id)
+{
+	uchar *a;
+	char *s;
+
+	a = (uchar*)CONFADDR;
+	memset(a, 0, 20);
+
+	apm(id);
+	if(memcmp(a, "APM", 4))
+		return;
+
+	s = confend;
+
+	addconfx("apm", 1, id);
+	addconfx("=ax=", 4, *((ushort*)(a+4)));
+	addconfx(" ebx=", 8, *((ulong*)(a+12)));
+	addconfx(" cx=", 4, *((ushort*)(a+6)));
+	addconfx(" dx=", 4, *((ushort*)(a+8)));
+	addconfx(" di=", 4, *((ushort*)(a+10)));
+	addconfx(" esi=", 8, *((ulong*)(a+16)));
+
+	print(s); print(crnl);
+
+	*confend++ = '\n';
+}
+
 char*
 bootkern(void *f)
 {
@@ -223,6 +287,7 @@
 		goto Error;
 	close(f);
 	unload();
+	memset(BOOTLINE, 0, BOOTLINELEN);
 	jump(e);
 Error:		
 	return "i/o error";