#define DATA32SEL SELECTOR(1, SELGDT, 0)
#define EXEC32SEL SELECTOR(2, SELGDT, 0)
-#define EXEC16SEL SELECTOR(3, SELGDT, 0)
+#define DATA16SEL SELECTOR(3, SELGDT, 0)
+#define EXEC16SEL SELECTOR(4, SELGDT, 0)
+
#define SEGSS BYTE $0x36
#define SEGES BYTE $0x26
#define FARRET BYTE $0xCB
PUSHI(start(SB))
TEXT pmode32(SB), $0
+ CLI
+
+ /* disable nmi */
+ PUSHA
+ LWI(0x70, rDX)
+ INB
+ ANDB $0x7F, AL
+ OUTB
+ POPA
+
+ /* get return pc */
POPR(rDI)
+
+ /* make sure stack is at 0000: */
+ CLR(rCX)
+ MTSR(rCX, rSS)
+ OPSIZE; ANDL $0xFFFF, SP
+
+ /* convert 16-bit return pc to far pointer */
+ PUSHI(EXEC32SEL)
+ PUSHR(rDI)
+
+ /* load gdt */
SEGSS; LGDT(tgdtptr(SB))
+
+ /* enable protected mode */
MFCR(rCR0, rCX)
ORB $1, CL
MTCR(rCX, rCR0)
- PUSHI(EXEC32SEL)
- PUSHR(rDI)
+
+ /* flush */
+ FARJUMP16(EXEC16SEL, pmode32flush(SB));
+TEXT pmode32flush(SB), $0
+
+ /* load 32-bit protected mode data selector */
LWI(DATA32SEL, rCX)
+
_segret:
+ /* load all data segments */
MTSR(rCX, rDS)
MTSR(rCX, rES)
+ MTSR(rCX, rFS)
+ MTSR(rCX, rGS)
MTSR(rCX, rSS)
FARRET
TEXT rmode16(SB), $0
- POPL DI
- OPSIZE; BYTE $0xEA
- WORD $unreal(SB)
- WORD $EXEC16SEL
+ /* setup farret to rmode16x */
+ PUSHL $EXEC16SEL
+ PUSHL $rmode16x(SB)
-TEXT unreal(SB), $0
+ /* load 16-bit protected mode data selector */
+ MOVL $DATA16SEL, CX
+ JMP _segret
+
+TEXT rmode16x(SB), $0
+ /* disable protected mode */
MFCR(rCR0, rCX)
ANDB $0xfe, CL
MTCR(rCX, rCR0)
+
+ /* flush */
+ FARJUMP16(0, rmode16flush(SB));
+TEXT rmode16flush(SB), $0
+
+ /*
+ * load 16-bit realmode data segment 0000: and
+ * return to 32 bit return pc interpreted
+ * as 16 bit far pointer.
+ */
CLR(rCX)
- PUSHR(rCX)
- PUSHR(rDI)
JMP _segret
TEXT tgdt(SB), $0
LONG $(0xFFFF)
LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
- /* exec segment descriptor for 4 gigabytes (PL 0) 16-bit */
+ /* data segment descriptor for (PL 0) 16-bit */
LONG $(0xFFFF)
- LONG $(SEGG|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
+ LONG $((0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
+
+ /* exec segment descriptor for (PL 0) 16-bit */
+ LONG $(0xFFFF)
+ LONG $((0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
TEXT tgdtptr(SB), $0
- WORD $(4*8)
+ WORD $(5*8)
LONG $tgdt(SB)
TEXT jump(SB), $0
_halt:
JMP _halt
+TEXT spllo(SB), $0
+ /* enable nmi */
+ PUSHA
+ LWI(0x70, rDX)
+ INB
+ ORB $0x80, AL
+ OUTB
+ POPA
+
+ STI
+ RET
+
TEXT getc(SB), $0
CALL rmode16(SB)
- STI
+ CALL16(spllo(SB))
MOVB $0x00, AH
BIOSCALL(0x16)
_getcret:
- CLI
CALL16(pmode32(SB))
ANDL $0xFF, AX
RET
TEXT gotc(SB), $0
CALL rmode16(SB)
- STI
+ CALL16(spllo(SB))
MOVB $0x01, AH
BIOSCALL(0x16)
JNZ _getcret
TEXT putc(SB), $0
MOVL 4(SP),AX
CALL rmode16(SB)
- STI
+ CALL16(spllo(SB))
MOVB $0x0E, AH
BIOSCALL(0x10)
_pret32:
- CLI
CALL16(pmode32(SB))
ANDL $0xFFFF, AX
RET
-TEXT a20(SB), $0
+#ifdef PXE
+
+TEXT pxeinit(SB), $0
CALL rmode16(SB)
- STI
- LWI(0x2401, rAX)
- BIOSCALL(0x15)
- JMP _pret32
-#ifdef PXE
+ /* get pxe env structure in ES:BX */
+ LWI(0x5650, rAX)
+ BIOSCALL(0x1A)
+ JC _pret32
+
+ /* !PXE or PXEENV+ signature */
+ SEGES; LXW(0, xBX, rAX)
+ CMPI((('!'<<0)|('P'<<8)), rAX)
+ JEQ _getentry
+ CMPI((('P'<<0)|('X'<<8)), rAX)
+ JNE _pret32
+
+ SEGES; LXW(0x2A, xBX, rAX)
+ SEGES; LXW(0x28, xBX, rBX)
+ MTSR(rAX, rES)
+
+_getentry:
+ SEGES; LXW(0x12, xBX, rAX)
+ SW(rAX, pxepseg(SB))
+ SEGES; LXW(0x10, xBX, rAX)
+ SW(rAX, pxepoff(SB))
+ CLR(rAX)
+ JMP _pret32
TEXT pxecallret(SB), $0
ADDI(6, rSP)
MOVL op+4(SP),AX
MOVL buf+8(SP),SI
CALL rmode16(SB)
- CLI
CLR(rCX)
PUSHR(rCX)
/* opcode */
PUSHR(rAX)
+ /* farcall */
PUSHR(rCX)
PUSHI(pxecallret(SB))
- /* get pxe env structure in ES:BX */
- LWI(0x5650, rAX)
- BIOSCALL(0x1A)
- JC _farret
-
- /* !PXE or PXEENV+ signature */
- SEGES; LXW(0, xBX, rAX)
- CMPI((('!'<<0)|('P'<<8)), rAX)
- JEQ _getentry
- CMPI((('P'<<0)|('X'<<8)), rAX)
- JNE _farret
-
- SEGES; LXW(0x2A, xBX, rAX)
- SEGES; LXW(0x28, xBX, rBX)
- MTSR(rAX, rES)
-
-_getentry:
- SEGES; LXW(0x12, xBX, rAX)
+ LW(pxepseg(SB), rAX)
PUSHR(rAX)
- SEGES; LXW(0x10, xBX, rAX)
+ LW(pxepoff(SB), rAX)
PUSHR(rAX)
-_pxecall:
+ CALL16(spllo(SB))
+
CLR(rAX)
CLR(rBX)
CLR(rCX)
CLR(rDX)
CLR(rDI)
CLR(rSI)
-_farret:
FARRET
-_pxeplus:
- CMPI((('P'<<0)|('X'<<8)), rAX)
- JNE _farret
-
- PUSHR(rAX)
- JMP _pxecall
+TEXT pxepseg(SB), $0
+ WORD $0
+TEXT pxepoff(SB), $0
+ WORD $0
#else /* PXE */
MOVW 10(SP), BX
MOVL 12(SP), SI
CALL rmode16(SB)
- STI
+ CALL16(spllo(SB))
CALL16(readsect16(SB))
- CLI
CALL16(pmode32(SB))
ANDL $0xFFFF, AX
RET