shithub: riscv

Download patch

ref: 7179a121a6c4426064818760e216c875fa78afcf
parent: 9140ae4a2ae59966c6d9b6e5cad9ecab6a0fda09
author: cinap_lenrek <[email protected]>
date: Fri Jan 20 15:03:38 EST 2012

9boot: always check if a20 is already enabled, use different keyboard code, retry on failure.

--- a/sys/src/boot/pc/a20.s
+++ b/sys/src/boot/pc/a20.s
@@ -2,69 +2,83 @@
 
 #undef ORB
 
+TEXT a20test(SB), $0
+	LONG $1234567
+
+TEXT a20check(SB), $0
+	MOVL $10000, CX
+_loop:
+	LEAL a20test(SB), AX
+	MOVL (AX), BX
+	ADDL $12345, BX
+	MOVL BX, (AX)
+	ORL $(1<<20), AX
+	MOVL (AX), AX
+	CMPL AX, BX
+	JNZ _done
+	LOOP _loop
+	RET
+_done:
+	/* return directly to caller of a20() */
+	ADDL $4, SP
+	XORL AX, AX
+	RET
+
 TEXT a20(SB), $0
+	CALL a20check(SB)
+
+	/* try bios */
 	CALL rmode16(SB)
 	STI
 	LWI(0x2401, rAX)
 	BIOSCALL(0x15)
-	JC _biosfail
 	CALL16(pmode32(SB))
-	RET
 
-_biosfail:
-	CALL16(pmode32(SB))
+	CALL a20check(SB)
 
-	/* fast a20 */
+	/* try fast a20 */
 	MOVL $0x92, DX
 	INB
-	ANDB $0xFE, AX
-	ORB $0x02, AX
+	TESTB $2, AL
+	JNZ _no92
+	ORB $2, AL
+	ANDB $0xfe, AL
 	OUTB
+_no92:
+	CALL a20check(SB)
 
-	/* slow a20 */
-	CALL a20wait(SB)
+	/* try keyboard */
+	CALL kbdempty(SB)
 	MOVL $0x64, DX
-	MOVB $0xAD, AL
+	MOVB $0xd1, AL	/* command write */
 	OUTB
-
-	CALL a20wait(SB)
-	MOVL $0x64, DX
-	MOVB $0xD0, AL
-	OUTB
-
-	CALL a20wait2(SB)
+	CALL kbdempty(SB)
 	MOVL $0x60, DX
-	INB
-	PUSHL AX
-
-	CALL a20wait(SB)
+	MOVB $0xdf, AL	/* a20 on */
+	OUTB
+	CALL kbdempty(SB)
 	MOVL $0x64, DX
-	MOVB $0xD1, AL
+	MOVB $0xff, AL	/* magic */
 	OUTB
+	CALL kbdempty(SB)
 
-	CALL a20wait(SB)
-	MOVL $0x60, DX
-	POPL AX
-	ORB $2, AL
-	OUTB
+	CALL a20check(SB)
 
-	CALL a20wait(SB)
-	MOVL $0x64, DX
-	MOVB $0xAE, AL
-	OUTB
+	/* fail */
+	XORL AX, AX
+	DECL AX
+	RET
 
-TEXT a20wait(SB), $0
-_a20wait:
+TEXT kbdempty(SB), $0
+_kbdwait:
 	MOVL $0x64, DX
 	INB
 	TESTB $1, AL
-	JZ _a20wait2
-	RET
-
-TEXT a20wait2(SB), $0
-_a20wait2:
-	MOVL $0x64, DX
+	JZ _kbdempty
+	MOVL $0x60, DX
 	INB
+	JMP _kbdwait
+_kbdempty:
 	TESTB $2, AL
-	JNZ _a20wait
+	JNZ _kbdwait
 	RET
--- a/sys/src/boot/pc/fns.h
+++ b/sys/src/boot/pc/fns.h
@@ -29,3 +29,11 @@
 char *configure(void *f, char *path);
 char *bootkern(void *f);
 
+/* a20.s */
+int a20(void);
+
+/* e820.s */
+ulong e820(ulong bx, void *p);
+
+/* apm.s */
+void apm(int id);
--- a/sys/src/boot/pc/sub.c
+++ b/sys/src/boot/pc/sub.c
@@ -283,8 +283,6 @@
 	*confend = 0;
 }
 
-void apm(int id);
-
 static void
 apmconf(int id)
 {
@@ -314,8 +312,6 @@
 	*confend = 0;
 }
 
-ulong e820(ulong bx, void *p);
-
 static void
 e820conf(void)
 {
@@ -380,8 +376,6 @@
 	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
 }
 
-void a20(void);
-
 char*
 bootkern(void *f)
 {
@@ -389,7 +383,8 @@
 	ulong n;
 	Exec ex;
 
-	a20();
+	while(a20() < 0)
+		print("a20 enable failed\r\n");
 
 	if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
 		return "bad header";