diff options
author | cinap_lenrek <cinap_lenrek@rei2.9hal> | 2012-01-20 20:03:38 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@rei2.9hal> | 2012-01-20 20:03:38 +0100 |
commit | 7179a121a6c4426064818760e216c875fa78afcf (patch) | |
tree | 6272edb960208e16cf7e92e559713a73a881ad9b /sys/src/boot | |
parent | 9140ae4a2ae59966c6d9b6e5cad9ecab6a0fda09 (diff) |
9boot: always check if a20 is already enabled, use different keyboard code, retry on failure.
Diffstat (limited to 'sys/src/boot')
-rw-r--r-- | sys/src/boot/pc/a20.s | 94 | ||||
-rw-r--r-- | sys/src/boot/pc/fns.h | 8 | ||||
-rw-r--r-- | sys/src/boot/pc/sub.c | 9 |
3 files changed, 64 insertions, 47 deletions
diff --git a/sys/src/boot/pc/a20.s b/sys/src/boot/pc/a20.s index 72e346f59..70933110e 100644 --- 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 - OUTB - - /* slow a20 */ - CALL a20wait(SB) - MOVL $0x64, DX - MOVB $0xAD, AL + TESTB $2, AL + JNZ _no92 + ORB $2, AL + ANDB $0xfe, AL OUTB +_no92: + CALL a20check(SB) - CALL a20wait(SB) + /* try keyboard */ + CALL kbdempty(SB) MOVL $0x64, DX - MOVB $0xD0, AL + MOVB $0xd1, AL /* command write */ 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 diff --git a/sys/src/boot/pc/fns.h b/sys/src/boot/pc/fns.h index 8a36ce04b..c4a46b1fc 100644 --- a/sys/src/boot/pc/fns.h +++ b/sys/src/boot/pc/fns.h @@ -29,3 +29,11 @@ void print(char *s); 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); diff --git a/sys/src/boot/pc/sub.c b/sys/src/boot/pc/sub.c index 470d31c39..035a2dd57 100644 --- a/sys/src/boot/pc/sub.c +++ b/sys/src/boot/pc/sub.c @@ -283,8 +283,6 @@ addconfx(char *s, int w, ulong v) *confend = 0; } -void apm(int id); - static void apmconf(int id) { @@ -314,8 +312,6 @@ apmconf(int id) *confend = 0; } -ulong e820(ulong bx, void *p); - static void e820conf(void) { @@ -380,8 +376,6 @@ beswal(ulong l) return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; } -void a20(void); - char* bootkern(void *f) { @@ -389,7 +383,8 @@ bootkern(void *f) 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"; |