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

This commit is contained in:
cinap_lenrek 2012-01-20 20:03:38 +01:00
parent 9140ae4a2a
commit 7179a121a6
3 changed files with 69 additions and 52 deletions

View file

@ -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))
/* fast a20 */
CALL a20check(SB)
/* 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
OUTB
CALL a20wait(SB)
MOVL $0x64, DX
MOVB $0xD0, AL
OUTB
CALL a20wait2(SB)
MOVL $0x60, DX
INB
PUSHL AX
CALL a20wait(SB)
MOVL $0x64, DX
MOVB $0xD1, AL
OUTB
CALL a20wait(SB)
MOVL $0x60, DX
POPL AX
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 $0xAE, AL
MOVB $0xd1, AL /* command write */
OUTB
CALL kbdempty(SB)
MOVL $0x60, DX
MOVB $0xdf, AL /* a20 on */
OUTB
CALL kbdempty(SB)
MOVL $0x64, DX
MOVB $0xff, AL /* magic */
OUTB
CALL kbdempty(SB)
TEXT a20wait(SB), $0
_a20wait:
CALL a20check(SB)
/* fail */
XORL AX, AX
DECL AX
RET
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

View file

@ -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);

View file

@ -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";