#include "x16.h"
#include "mem.h"
-#define WRMSR BYTE $0x0F; BYTE $0x30 /* WRMSR, argument in AX/DX (lo/hi) */
-#define RDTSC BYTE $0x0F; BYTE $0x31 /* RDTSC, result in AX/DX (lo/hi) */
-#define RDMSR BYTE $0x0F; BYTE $0x32 /* RDMSR, result in AX/DX (lo/hi) */
+#undef ORB
-#ifdef PXE
-#define PDB 0x90000 /* temporary page tables (24KB) */
-#else
-#define PDB 0x08000
-#endif PXE
+#define DATA32SEL SELECTOR(1, SELGDT, 0)
+#define EXEC32SEL SELECTOR(2, SELGDT, 0)
+#define DATA16SEL SELECTOR(3, SELGDT, 0)
+#define EXEC16SEL SELECTOR(4, SELGDT, 0)
-/*#define VGA 1 */
-#define NoScreenBlank 1
-/*#define ResetDiscs 1*/
+#define SEGSS BYTE $0x36
+#define SEGES BYTE $0x26
+#define FARRET BYTE $0xCB
TEXT origin(SB), $0
- /*
- * This part of l.s is used only in the boot kernel.
- * It assumes that we are in real address mode, i.e.,
- * that we look like an 8086.
- *
- * Make sure the segments are reasonable.
- * If we were started directly from the BIOS
- * (i.e. no MS-DOS) then DS may not be
- * right.
- */
- MOVW CS, AX
- MOVW AX, DS
-
-#ifdef VGA
-#ifdef NoScreenBlank
- /*
- * Get the current video mode. If it isn't mode 3,
- * set text mode 3.
- * Well, no. Windows95 won't co-operate here so we have
- * to explicitly set mode 3.
- */
- XORL AX, AX
- MOVB $0x0F, AH
- INT $0x10 /* get current video mode in AL */
- CMPB AL, $03
- JEQ sayhello
-#endif /* NoScreenBlank */
- XORL AX, AX
- MOVB $0x03, AL
- INT $0x10 /* set video mode in AL */
-
-sayhello:
- LWI(hello(SB), rSI)
- CALL16(biosputs(SB))
-#endif /* VGA */
-#ifdef ResetDiscs
- XORL AX, AX /* reset disc system */
- XORL DX, DX
- MOVB $0x80, DL
- INT $0x13
-#endif /* ResetDiscs */
-
-#ifdef DOTCOM
-/*
- * relocate everything to a half meg and jump there
- * - looks weird because it is being assembled by a 32 bit
- * assembler for a 16 bit world
- *
- * only b.com does this - not 9load
- */
- MOVL $0,BX
- INCL BX
- SHLL $15,BX
- MOVL BX,CX
- MOVW BX,ES
- MOVL $0,SI
- MOVL SI,DI
- CLD
- REP
- MOVSL
-
- /*
- * Jump to the copied image;
- * fix up the DS for the new location.
- */
- FARJUMP16(0x8000, _start8000(SB))
-
-TEXT _start8000(SB), $0
- MFSR(rCS, rAX) /* fix up DS, ES (0x8000) */
- MTSR(rAX, rDS)
- MTSR(rAX, rES)
-
- /*
- * If we are already in protected mode, have to get back
- * to real mode before trying any privileged operations
- * (like going into protected mode...).
- * Try to reset with a restart vector.
- */
- MFCR(rCR0, rAX) /* are we in protected mode? */
- ANDI(0x0001, rAX)
- JEQ _real
-
- CLR(rBX)
- MTSR(rBX, rES)
-
- LWI(0x0467, rBX) /* reset entry point */
- LWI(_start8000(SB), rAX) /* offset within segment */
- BYTE $0x26
- BYTE $0x89
- BYTE $0x07 /* MOVW AX, ES:[BX] */
- LBI(0x69, rBL)
- MFSR(rCS, rAX) /* segment */
- BYTE $0x26
- BYTE $0x89
- BYTE $0x07 /* MOVW AX, ES:[BX] */
-
- CLR(rDX)
- OUTPORTB(0x70, 0x8F)
- OUTPORTB(0x71, 0x0A)
-
- FARJUMP16(0xFFFF, 0x0000) /* reset */
-#endif /* DOTCOM */
-
-_real:
-
-/*
- * do things that need to be done in real mode.
- * the results get written to CONFADDR (0x1200)
- * in a series of <4-byte-magic-number><block-of-data>
- * the data length is dependent on the magic number.
- *
- * this gets parsed by conf.c:/^readlsconf
- *
- * N.B. CALL16 kills rDI, so we can't call anything.
- */
- LWI(0x0000, rAX)
- MTSR(rAX, rES)
- LWI(0x1200, rDI)
-
-/*
- * turn off interrupts
- */
CLI
+ CLR(rCX)
+ MTSR(rCX, rSS)
+ OPSIZE; MOVL $origin(SB), SP
+ PUSHA
+ OPSIZE; ADSIZE; PUSHL SP
+ OPSIZE; ADSIZE; PUSHL CX
+ PUSHI(start(SB))
-/*
- * detect APM1.2 bios support
- */
- /* save DI */
- SW(rDI, rock(SB))
-
- /* disconnect anyone else */
- LWI(0x5304, rAX)
- LWI(0x0000, rBX)
- INT $0x15
+TEXT pmode32(SB), $0
+ CLI
- /* connect */
- CLC
- LWI(0x5303, rAX)
- LWI(0x0000, rBX)
- INT $0x15
- CLI /* apm put interrupts back? */
+ /* get return pc */
+ POPR(rDI)
- JC noapm
+ /* make sure stack is at 0000: */
+ CLR(rCX)
+ MTSR(rCX, rSS)
+ OPSIZE; ANDL $0xFFFF, SP
- OPSIZE; PUSHR(rSI)
- OPSIZE; PUSHR(rBX)
+ /* convert 16-bit return pc to far pointer */
+ PUSHI(EXEC32SEL)
PUSHR(rDI)
- PUSHR(rDX)
- PUSHR(rCX)
- PUSHR(rAX)
-
- /* put DI, ES back */
- LW(rock(SB), rDI)
- LWI(0x0000, rAX)
- MTSR(rAX, rES)
-
- /*
- * 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:
-
-/*
- * end of real mode hacks: write terminator, put ES back.
- */
- LWI(0x0000, rAX)
- STOSW
- STOSW
-
- MFSR(rCS, rAX) /* fix up ES (0x8000) */
- MTSR(rAX, rES)
-
-/*
- * goto protected mode
- */
-/* MOVL tgdtptr(SB),GDTR /**/
- BYTE $0x0f
- BYTE $0x01
- BYTE $0x16
- WORD $tgdtptr(SB)
-
- LWI(1, rAX)
- /* MOV AX,MSW */
- BYTE $0x0F; BYTE $0x01; BYTE $0xF0
-
-/*
- * clear prefetch queue (weird code to avoid optimizations)
- */
- /* JMP .+2 */
- BYTE $0xEB
- BYTE $0x00
-
-/*
- * set all segs
- */
-/* MOVW $SELECTOR(1, SELGDT, 0),AX /**/
- BYTE $0xc7
- BYTE $0xc0
- WORD $SELECTOR(1, SELGDT, 0)
- MOVW AX,DS
- MOVW AX,SS
- MOVW AX,ES
- MOVW AX,FS
- MOVW AX,GS
-
-/* JMPFAR SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/
- BYTE $0x66
- BYTE $0xEA
- LONG $mode32bit-KZERO(SB)
- WORD $SELECTOR(2, SELGDT, 0)
-
-TEXT mode32bit(SB),$0
- /*
- * make a bottom level page table page that maps the first
- * 16 meg of physical memory
- */
- MOVL $PDB, DI /* clear 6 pages for the tables etc. */
- XORL AX, AX
- MOVL $(6*BY2PG), CX
- SHRL $2, CX
-
- CLD
- REP; STOSL
-
- MOVL $PDB, AX /* phys addr of temporary page table */
- MOVL $(4*1024),CX /* pte's per page */
- MOVL $((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX
-setpte:
- MOVL BX,-4(AX)(CX*4)
- SUBL $(1<<PGSHIFT),BX
- LOOP setpte
-
- /*
- * make a top level page table page that maps the first
- * 16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg
- */
- MOVL AX,BX
- ADDL $(4*BY2PG),AX
- ADDL $(PTEVALID|PTEKERNEL|PTEWRITE),BX
- MOVL BX,0(AX)
- MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX)
- ADDL $BY2PG,BX
- MOVL BX,4(AX)
- MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+4)(AX)
- ADDL $BY2PG,BX
- MOVL BX,8(AX)
- MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+8)(AX)
- ADDL $BY2PG,BX
- MOVL BX,12(AX)
- MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+12)(AX)
-
- /*
- * point processor to top level page & turn on paging
- *
- * this produces the apparently harmless "VMX|F(125):468 Dis 0x0:0x0"
- * message in the VMware log.
- */
- MOVL AX,CR3
- MOVL CR0,AX
- ORL $0X80000000,AX
- MOVL AX,CR0
-
- /*
- * use a jump to an absolute location to get the PC into
- * KZERO.
- */
- LEAL tokzero(SB),AX
- JMP* AX
-
-/*
- * When we load 9load from DOS, the bootstrap jumps
- * to the instruction right after `JUMP', which gets
- * us into kzero.
- *
- * The name prevents it from being optimized away.
- */
-TEXT jumplabel(SB), $0
- BYTE $'J'; BYTE $'U'; BYTE $'M'; BYTE $'P'
- LEAL tokzero(SB),AX
- JMP* AX
+ /* load gdt */
+ SEGSS; LGDT(tgdtptr(SB))
+
+ /* enable protected mode */
+ MFCR(rCR0, rCX)
+ ORB $1, CL
+ MTCR(rCX, rCR0)
+
+ /* 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
+ /* setup farret to rmode16x */
+ PUSHL $EXEC16SEL
+ PUSHL $rmode16x(SB)
+
+ /* 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
-TEXT tokzero(SB),$0
/*
- * Clear BSS
+ * load 16-bit realmode data segment 0000: and
+ * return to 32 bit return pc interpreted
+ * as 16 bit far pointer.
*/
- LEAL edata(SB),SI
- MOVL SI,DI
- ADDL $4,DI
- MOVL $0,AX
- MOVL AX,(SI)
- LEAL end(SB),CX
- SUBL DI,CX
- SHRL $2,CX
- CLD
- REP
- MOVSL
-
- /*
- * stack and mach
- */
- MOVL $mach0(SB),SP
- MOVL SP,m(SB)
- MOVL $0,0(SP)
- ADDL $(MACHSIZE-4),SP /* start stack above machine struct */
-
- CALL main(SB)
-
-loop:
- JMP loop
-
-GLOBL mach0+0(SB), $MACHSIZE
-GLOBL m(SB), $4
-
-/*
- * gdt to get us to 32-bit/segmented/unpaged mode
- */
-TEXT tgdt(SB),$0
+ CLR(rCX)
+ JMP _segret
+TEXT tgdt(SB), $0
/* null descriptor */
- LONG $0
- LONG $0
+ LONG $0
+ LONG $0
/* data segment descriptor for 4 gigabytes (PL 0) */
- LONG $(0xFFFF)
- LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
+ LONG $(0xFFFF)
+ LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
/* exec segment descriptor for 4 gigabytes (PL 0) */
- LONG $(0xFFFF)
- LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-
- /* exec segment descriptor for 4 gigabytes (PL 0) 16-bit */
- LONG $(0xFFFF)
- LONG $(SEGG|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-
-/*
- * pointer to initial gdt
- */
-TEXT tgdtptr(SB),$0
- WORD $(4*8)
- LONG $tgdt-KZERO(SB)
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT biosputs(SB), $0
- PUSHA
- CLR(rBX)
-_BIOSputs:
- LODSB
- ORB(rAL, rAL)
- JEQ _BIOSputsret
-
- LBI(0x0E, rAH)
- BIOSCALL(0x10)
- JMP _BIOSputs
-
-_BIOSputsret:
- POPA
- RET
-
-/*
- * input a byte
- */
-TEXT inb(SB),$0
-
- MOVL p+0(FP),DX
- XORL AX,AX
- INB
- RET
-
-/*
- * input a short from a port
- */
-TEXT ins(SB), $0
-
- MOVL p+0(FP), DX
- XORL AX, AX
- OPSIZE; INL
- RET
-
-/*
- * input a long from a port
- */
-TEXT inl(SB), $0
-
- MOVL p+0(FP), DX
- XORL AX, AX
- INL
- RET
-
-/*
- * output a byte
- */
-TEXT outb(SB),$0
-
- MOVL p+0(FP),DX
- MOVL b+4(FP),AX
- OUTB
- RET
-
-/*
- * output a short to a port
- */
-TEXT outs(SB), $0
- MOVL p+0(FP), DX
- MOVL s+4(FP), AX
- OPSIZE; OUTL
- RET
-
-/*
- * output a long to a port
- */
-TEXT outl(SB), $0
- MOVL p+0(FP), DX
- MOVL s+4(FP), AX
- OUTL
- RET
+ LONG $(0xFFFF)
+ LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-/*
- * input a string of bytes from a port
- */
-TEXT insb(SB),$0
+ /* data segment descriptor for (PL 0) 16-bit */
+ LONG $(0xFFFF)
+ LONG $((0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
- MOVL p+0(FP),DX
- MOVL a+4(FP),DI
- MOVL c+8(FP),CX
- CLD; REP; INSB
- RET
+ /* exec segment descriptor for (PL 0) 16-bit */
+ LONG $(0xFFFF)
+ LONG $((0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-/*
- * input a string of shorts from a port
- */
-TEXT inss(SB),$0
- MOVL p+0(FP),DX
- MOVL a+4(FP),DI
- MOVL c+8(FP),CX
- CLD
- REP; OPSIZE; INSL
- RET
+TEXT tgdtptr(SB), $0
+ WORD $(5*8)
+ LONG $tgdt(SB)
-/*
- * output a string of bytes to a port
- */
-TEXT outsb(SB),$0
+TEXT jump(SB), $0
+ MOVL 4(SP), AX
+ JMP *AX
- MOVL p+0(FP),DX
- MOVL a+4(FP),SI
- MOVL c+8(FP),CX
- CLD; REP; OUTSB
- RET
+TEXT halt(SB), $0
+_halt:
+ JMP _halt
-/*
- * output a string of shorts to a port
- */
-TEXT outss(SB),$0
- MOVL p+0(FP),DX
- MOVL a+4(FP),SI
- MOVL c+8(FP),CX
- CLD
- REP; OPSIZE; OUTSL
+TEXT getc(SB), $0
+ CALL rmode16(SB)
+ STI
+ MOVB $0x00, AH
+ BIOSCALL(0x16)
+_getcret:
+ CALL16(pmode32(SB))
+ ANDL $0xFF, AX
RET
-/*
- * input a string of longs from a port
- */
-TEXT insl(SB),$0
-
- MOVL p+0(FP),DX
- MOVL a+4(FP),DI
- MOVL c+8(FP),CX
- CLD; REP; INSL
+TEXT gotc(SB), $0
+ CALL rmode16(SB)
+ STI
+ MOVB $0x01, AH
+ BIOSCALL(0x16)
+ JNZ _getcret
+ CLR(rAX)
+ JMP _getcret
+
+TEXT putc(SB), $0
+ MOVL 4(SP),AX
+ CALL rmode16(SB)
+ STI
+ MOVB $0x0E, AH
+ BIOSCALL(0x10)
+_pret32:
+ CALL16(pmode32(SB))
+ ANDL $0xFFFF, AX
RET
-/*
- * output a string of longs to a port
- */
-TEXT outsl(SB),$0
-
- MOVL p+0(FP),DX
- MOVL a+4(FP),SI
- MOVL c+8(FP),CX
- CLD; REP; OUTSL
- RET
+TEXT usleep(SB), $0
+ MOVL t+4(SP), AX
+ PUSHL AX
+ CALL rmode16(SB)
+ STI
+ POPR(rDX)
+ POPR(rCX)
+ MOVB $0x86, AH
+ BIOSCALL(0x15)
+ JMP _pret32
-/*
- * routines to load/read various system registers
- */
-GLOBL idtptr(SB),$6
-TEXT putidt(SB),$0 /* interrupt descriptor table */
- MOVL t+0(FP),AX
- MOVL AX,idtptr+2(SB)
- MOVL l+4(FP),AX
- MOVW AX,idtptr(SB)
- MOVL idtptr(SB),IDTR
- RET
+#ifdef PXE
-TEXT putcr3(SB),$0 /* top level page table pointer */
- MOVL t+0(FP),AX
- MOVL AX,CR3
- RET
+TEXT pxeinit(SB), $0
+ CALL rmode16(SB)
-TEXT getcr0(SB),$0 /* coprocessor bits */
- MOVL CR0,AX
- RET
+ /* get pxe env structure in ES:BX */
+ LWI(0x5650, rAX)
+ BIOSCALL(0x1A)
+ JC _pret32
-TEXT getcr2(SB),$0 /* fault address */
- MOVL CR2,AX
- RET
+ /* !PXE or PXEENV+ signature */
+ SEGES; LXW(0, xBX, rAX)
+ CMPI((('!'<<0)|('P'<<8)), rAX)
+ JEQ _getentry
+ CMPI((('P'<<0)|('X'<<8)), rAX)
+ JNE _pret32
-TEXT getcr3(SB),$0 /* page directory base */
- MOVL CR3,AX
- RET
+ SEGES; LXW(0x2A, xBX, rAX)
+ SEGES; LXW(0x28, xBX, rBX)
+ MTSR(rAX, rES)
-TEXT getcr4(SB), $0 /* CR4 - extensions */
- MOVL CR4, AX
- RET
+_getentry:
+ SEGES; LXW(0x12, xBX, rAX)
+ SW(rAX, pxepseg(SB))
+ SEGES; LXW(0x10, xBX, rAX)
+ SW(rAX, pxepoff(SB))
+ CLR(rAX)
+ JMP _pret32
-TEXT _cycles(SB), $0 /* time stamp counter */
- RDTSC
- MOVL vlong+0(FP), CX /* &vlong */
- MOVL AX, 0(CX) /* lo */
- MOVL DX, 4(CX) /* hi */
- RET
+TEXT pxecallret(SB), $0
+ ADDI(6, rSP)
+ JMP _pret32
-TEXT rdmsr(SB), $0 /* model-specific register */
- MOVL index+0(FP), CX
- RDMSR
- MOVL vlong+4(FP), CX /* &vlong */
- MOVL AX, 0(CX) /* lo */
- MOVL DX, 4(CX) /* hi */
- RET
-
-TEXT wrmsr(SB), $0
- MOVL index+0(FP), CX
- MOVL lo+4(FP), AX
- MOVL hi+8(FP), DX
- WRMSR
- RET
+TEXT pxecall(SB), $0
+ MOVL op+4(SP),AX
+ MOVL buf+8(SP),SI
+ CALL rmode16(SB)
-TEXT mb386(SB), $0
- POPL AX /* return PC */
- PUSHFL
- PUSHL CS
- PUSHL AX
- IRETL
+ CLR(rCX)
+ PUSHR(rCX)
+ PUSHR(rSI)
-/*
- * special traps
- */
-TEXT intr0(SB),$0
- PUSHL $0
- PUSHL $0
- JMP intrcommon
-TEXT intr1(SB),$0
- PUSHL $0
- PUSHL $1
- JMP intrcommon
-TEXT intr2(SB),$0
- PUSHL $0
- PUSHL $2
- JMP intrcommon
-TEXT intr3(SB),$0
- PUSHL $0
- PUSHL $3
- JMP intrcommon
-TEXT intr4(SB),$0
- PUSHL $0
- PUSHL $4
- JMP intrcommon
-TEXT intr5(SB),$0
- PUSHL $0
- PUSHL $5
- JMP intrcommon
-TEXT intr6(SB),$0
- PUSHL $0
- PUSHL $6
- JMP intrcommon
-TEXT intr7(SB),$0
- PUSHL $0
- PUSHL $7
- JMP intrcommon
-TEXT intr8(SB),$0
- PUSHL $8
- JMP intrcommon
-TEXT intr9(SB),$0
- PUSHL $0
- PUSHL $9
- JMP intrcommon
-TEXT intr10(SB),$0
- PUSHL $10
- JMP intrcommon
-TEXT intr11(SB),$0
- PUSHL $11
- JMP intrcommon
-TEXT intr12(SB),$0
- PUSHL $12
- JMP intrcommon
-TEXT intr13(SB),$0
- PUSHL $13
- JMP intrcommon
-TEXT intr14(SB),$0
- PUSHL $14
- JMP intrcommon
-TEXT intr15(SB),$0
- PUSHL $0
- PUSHL $15
- JMP intrcommon
-TEXT intr16(SB),$0
- PUSHL $0
- PUSHL $16
- JMP intrcommon
-TEXT intr24(SB),$0
- PUSHL $0
- PUSHL $24
- JMP intrcommon
-TEXT intr25(SB),$0
- PUSHL $0
- PUSHL $25
- JMP intrcommon
-TEXT intr26(SB),$0
- PUSHL $0
- PUSHL $26
- JMP intrcommon
-TEXT intr27(SB),$0
- PUSHL $0
- PUSHL $27
- JMP intrcommon
-TEXT intr28(SB),$0
- PUSHL $0
- PUSHL $28
- JMP intrcommon
-TEXT intr29(SB),$0
- PUSHL $0
- PUSHL $29
- JMP intrcommon
-TEXT intr30(SB),$0
- PUSHL $0
- PUSHL $30
- JMP intrcommon
-TEXT intr31(SB),$0
- PUSHL $0
- PUSHL $31
- JMP intrcommon
-TEXT intr32(SB),$0
- PUSHL $0
- PUSHL $32
- JMP intrcommon
-TEXT intr33(SB),$0
- PUSHL $0
- PUSHL $33
- JMP intrcommon
-TEXT intr34(SB),$0
- PUSHL $0
- PUSHL $34
- JMP intrcommon
-TEXT intr35(SB),$0
- PUSHL $0
- PUSHL $35
- JMP intrcommon
-TEXT intr36(SB),$0
- PUSHL $0
- PUSHL $36
- JMP intrcommon
-TEXT intr37(SB),$0
- PUSHL $0
- PUSHL $37
- JMP intrcommon
-TEXT intr38(SB),$0
- PUSHL $0
- PUSHL $38
- JMP intrcommon
-TEXT intr39(SB),$0
- PUSHL $0
- PUSHL $39
- JMP intrcommon
-TEXT intr64(SB),$0
- PUSHL $0
- PUSHL $64
- JMP intrcommon
-TEXT intrbad(SB),$0
- PUSHL $0
- PUSHL $0x1ff
- JMP intrcommon
+ /* opcode */
+ PUSHR(rAX)
-intrcommon:
- PUSHL DS
- PUSHL ES
- PUSHL FS
- PUSHL GS
- PUSHAL
- MOVL $(KDSEL),AX
- MOVW AX,DS
- MOVW AX,ES
- LEAL 0(SP),AX
- PUSHL AX
- CALL trap(SB)
- POPL AX
- POPAL
- POPL GS
- POPL FS
- POPL ES
- POPL DS
- ADDL $8,SP /* error code and trap type */
- IRETL
+ /* farcall */
+ PUSHR(rCX)
+ PUSHI(pxecallret(SB))
+ LW(pxepseg(SB), rAX)
+ PUSHR(rAX)
+ LW(pxepoff(SB), rAX)
+ PUSHR(rAX)
-/*
- * interrupt level is interrupts on or off
- */
-TEXT spllo(SB),$0
- PUSHFL
- POPL AX
STI
- RET
-TEXT splhi(SB),$0
- PUSHFL
- POPL AX
- CLI
- RET
+ CLR(rAX)
+ CLR(rBX)
+ CLR(rCX)
+ CLR(rDX)
+ CLR(rDI)
+ CLR(rSI)
+ FARRET
-TEXT splx(SB),$0
- MOVL s+0(FP),AX
- PUSHL AX
- POPFL
- RET
+TEXT pxepseg(SB), $0
+ WORD $0
+TEXT pxepoff(SB), $0
+ WORD $0
-/*
- * do nothing whatsoever till interrupt happens
- */
-TEXT idle(SB),$0
- HLT
- RET
+#else /* PXE */
/*
- * Try to determine the CPU type which requires fiddling with EFLAGS.
- * If the Id bit can be toggled then the CPUID instruciton can be used
- * to determine CPU identity and features. First have to check if it's
- * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be
- * toggled then it's an older 486 of some kind.
- *
- * cpuid(id[], &ax, &dx);
+ * in:
+ * DL drive
+ * AX:BX lba32,
+ * 0000:SI buffer
*/
-#define CPUID BYTE $0x0F; BYTE $0xA2 /* CPUID, argument in AX */
-TEXT cpuid(SB), $0
- MOVL $0x240000, AX
- PUSHL AX
- POPFL /* set Id|Ac */
-
- PUSHFL
- POPL BX /* retrieve value */
-
- MOVL $0, AX
- PUSHL AX
- POPFL /* clear Id|Ac, EFLAGS initialised */
-
- PUSHFL
- POPL AX /* retrieve value */
- XORL BX, AX
- TESTL $0x040000, AX /* Ac */
- JZ _cpu386 /* can't set this bit on 386 */
- TESTL $0x200000, AX /* Id */
- JZ _cpu486 /* can't toggle this bit on some 486 */
-
- MOVL $0, AX
- CPUID
- MOVL id+0(FP), BP
- MOVL BX, 0(BP) /* "Genu" "Auth" "Cyri" */
- MOVL DX, 4(BP) /* "ineI" "enti" "xIns" */
- MOVL CX, 8(BP) /* "ntel" "cAMD" "tead" */
-
- MOVL $1, AX
- CPUID
- JMP _cpuid
-
-_cpu486:
- MOVL $0x400, AX
- MOVL $0, DX
- JMP _cpuid
+TEXT readsect16(SB), $0
+ PUSHA
+ CLR(rCX)
-_cpu386:
- MOVL $0x300, AX
- MOVL $0, DX
+ PUSHR(rCX) /* qword lba */
+ PUSHR(rCX)
+ PUSHR(rBX)
+ PUSHR(rAX)
-_cpuid:
- MOVL ax+4(FP), BP
- MOVL AX, 0(BP)
- MOVL dx+8(FP), BP
- MOVL DX, 0(BP)
- RET
+ PUSHR(rCX) /* dword buffer */
+ PUSHR(rSI)
+ INC(rCX)
+ PUSHR(rCX) /* word # of sectors */
-/*
- * basic timing loop to determine CPU frequency
- */
-TEXT aamloop(SB),$0
+ PUSHI(0x0010) /* byte reserved, byte packet size */
- MOVL c+0(FP),CX
-aaml1:
- AAM
- LOOP aaml1
+ MW(rSP, rSI)
+ LWI(0x4200, rAX)
+ BIOSCALL(0x13)
+ JCC _readok
+ ADDI(0x10, rSP)
+ POPA
+ CLR(rAX)
+ DEC(rAX)
RET
-
-TEXT hello(SB), $0
- BYTE $'\r';
- BYTE $'\n';
- BYTE $'P'; BYTE $'l'; BYTE $'a'; BYTE $'n';
- BYTE $' '; BYTE $'9'; BYTE $' '; BYTE $'f';
- BYTE $'r'; BYTE $'o'; BYTE $'m'; BYTE $' ';
- BYTE $'B'; BYTE $'e'; BYTE $'l'; BYTE $'l';
- BYTE $' '; BYTE $'L'; BYTE $'a'; BYTE $'b';
- BYTE $'s';
-#ifdef PXE
- BYTE $' '; BYTE $'b'; BYTE $'y'; BYTE $' ';
- BYTE $'P'; BYTE $'X'; BYTE $'E';
-#endif
- BYTE $'\r';
- BYTE $'\n';
- BYTE $'\z';
-
-TEXT rock(SB), $0
- BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-
-GLOBL pxe(SB), $4
-#ifdef PXE
-DATA pxe+0(SB)/4, $1
-#else
-DATA pxe+0(SB)/4, $0
-#endif /* PXE */
-
-/*
- * Save registers.
- */
-TEXT saveregs(SB), $0
- /* appease 8l */
- SUBL $32, SP
- POPL AX
- POPL AX
- POPL AX
- POPL AX
- POPL AX
- POPL AX
- POPL AX
- POPL AX
-
- PUSHL AX
- PUSHL BX
- PUSHL CX
- PUSHL DX
- PUSHL BP
- PUSHL DI
- PUSHL SI
- PUSHFL
-
- XCHGL 32(SP), AX /* swap return PC and saved flags */
- XCHGL 0(SP), AX
- XCHGL 32(SP), AX
+_readok:
+ ADDI(0x10, rSP)
+ POPA
+ CLR(rAX)
RET
-TEXT restoreregs(SB), $0
- /* appease 8l */
- PUSHL AX
- PUSHL AX
- PUSHL AX
- PUSHL AX
- PUSHL AX
- PUSHL AX
- PUSHL AX
- PUSHL AX
- ADDL $32, SP
-
- XCHGL 32(SP), AX /* swap return PC and saved flags */
- XCHGL 0(SP), AX
- XCHGL 32(SP), AX
-
- POPFL
- POPL SI
- POPL DI
- POPL BP
- POPL DX
- POPL CX
- POPL BX
- POPL AX
+TEXT readsect(SB), $0
+ MOVL 4(SP), DX
+ MOVW 8(SP), AX
+ MOVW 10(SP), BX
+ MOVL 12(SP), SI
+ CALL rmode16(SB)
+ STI
+ CALL16(readsect16(SB))
+ CALL16(pmode32(SB))
+ ANDL $0xFFFF, AX
RET
-/*
- * Assumed to be in protected mode at time of call.
- * Switch to real mode, execute an interrupt, and
- * then switch back to protected mode.
- *
- * Assumes:
- *
- * - no device interrupts are going to come in
- * - 0-16MB is identity mapped in page tables
- * - can use code segment 0x1000 in real mode
- * to get at l.s code
- */
-TEXT realmodeidtptr(SB), $0
- WORD $(4*256-1)
- LONG $0
-
-TEXT realmode0(SB), $0
- CALL saveregs(SB)
-
- /* switch to low code address */
- LEAL physcode-KZERO(SB), AX
- JMP *AX
-
-TEXT physcode(SB), $0
-
- /* switch to low stack */
- MOVL SP, AX
- MOVL $0x7C00, SP
- PUSHL AX
-
- /* load IDT with real-mode version; GDT already fine */
- MOVL realmodeidtptr(SB), IDTR
-
- /* edit INT $0x00 instruction below */
- MOVL realmodeintr(SB), AX
- MOVB AX, realmodeintrinst+1(SB)
-
- /* disable paging */
- MOVL CR0, AX
- ANDL $0x7FFFFFFF, AX
- MOVL AX, CR0
- /* JMP .+2 to clear prefetch queue*/
- BYTE $0xEB; BYTE $0x00
-
- /* jump to 16-bit code segment */
-/* JMPFAR SELECTOR(3, SELGDT, 0):$again16bit(SB) /**/
- BYTE $0xEA
- LONG $again16bit-KZERO(SB)
- WORD $SELECTOR(3, SELGDT, 0)
-
-TEXT again16bit(SB), $0
- /*
- * Now in 16-bit compatibility mode.
- * These are 32-bit instructions being interpreted
- * as 16-bit instructions. I'm being lazy and
- * not using the macros because I know when
- * the 16- and 32-bit instructions look the same
- * or close enough.
- */
-
- /* disable protected mode and jump to real mode cs */
- OPSIZE; MOVL CR0, AX
- OPSIZE; XORL BX, BX
- OPSIZE; INCL BX
- OPSIZE; XORL BX, AX
- OPSIZE; MOVL AX, CR0
-
- /* JMPFAR 0x1000:now16real */
- BYTE $0xEA
- WORD $now16real-KZERO(SB)
- WORD $0x1000
-
-TEXT now16real(SB), $0
- /* copy the registers for the bios call */
- LWI(0x1000, rAX)
- MOVW AX,SS
- LWI(realmoderegs(SB), rBP)
-
- /* offsets are in Ureg */
- LXW(44, xBP, rAX)
- MOVW AX, DS
- LXW(40, xBP, rAX)
- MOVW AX, ES
-
- OPSIZE; LXW(0, xBP, rDI)
- OPSIZE; LXW(4, xBP, rSI)
- OPSIZE; LXW(16, xBP, rBX)
- OPSIZE; LXW(20, xBP, rDX)
- OPSIZE; LXW(24, xBP, rCX)
- OPSIZE; LXW(28, xBP, rAX)
-
- CLC
-
-TEXT realmodeintrinst(SB), $0
- INT $0x00
-
-
- /* save the registers after the call */
-
- LWI(0x7bfc, rSP)
- OPSIZE; PUSHFL
- OPSIZE; PUSHL AX
-
- LWI(0x1000, rAX)
- MOVW AX,SS
- LWI(realmoderegs(SB), rBP)
-
- OPSIZE; SXW(rDI, 0, xBP)
- OPSIZE; SXW(rSI, 4, xBP)
- OPSIZE; SXW(rBX, 16, xBP)
- OPSIZE; SXW(rDX, 20, xBP)
- OPSIZE; SXW(rCX, 24, xBP)
- OPSIZE; POPL AX
- OPSIZE; SXW(rAX, 28, xBP)
-
- MOVW DS, AX
- OPSIZE; SXW(rAX, 44, xBP)
- MOVW ES, AX
- OPSIZE; SXW(rAX, 40, xBP)
-
- OPSIZE; POPL AX
- OPSIZE; SXW(rAX, 64, xBP) /* flags */
-
- /* re-enter protected mode and jump to 32-bit code */
- OPSIZE; MOVL $1, AX
- OPSIZE; MOVL AX, CR0
-
-/* JMPFAR SELECTOR(2, SELGDT, 0):$again32bit(SB) /**/
- OPSIZE
- BYTE $0xEA
- LONG $again32bit-KZERO(SB)
- WORD $SELECTOR(2, SELGDT, 0)
-
-TEXT again32bit(SB), $0
- MOVW $SELECTOR(1, SELGDT, 0),AX
- MOVW AX,DS
- MOVW AX,SS
- MOVW AX,ES
- MOVW AX,FS
- MOVW AX,GS
-
- /* enable paging and jump to kzero-address code */
- MOVL CR0, AX
- ORL $0x80000000, AX
- MOVL AX, CR0
- LEAL again32kzero(SB), AX
- JMP* AX
-
-TEXT again32kzero(SB), $0
- /* breathe a sigh of relief - back in 32-bit protected mode */
-
- /* switch to old stack */
- PUSHL AX /* match popl below for 8l */
- MOVL $0x7BFC, SP
- POPL SP
+#endif
- /* restore idt */
- MOVL idtptr(SB),IDTR
+#ifdef ISO
- CALL restoreregs(SB)
- RET
+TEXT bootname(SB), $0
+ BYTE $'3'; BYTE $'8'; BYTE $'6'; BYTE $'/';
+ BYTE $'9'; BYTE $'b'; BYTE $'o'; BYTE $'o';
+ BYTE $'t'; BYTE $'i'; BYTE $'s'; BYTE $'o';
+ BYTE $0
-TEXT realmoderegs(SB), $0
- LONG $0; LONG $0; LONG $0; LONG $0
- LONG $0; LONG $0; LONG $0; LONG $0
- LONG $0; LONG $0; LONG $0; LONG $0
- LONG $0; LONG $0; LONG $0; LONG $0
- LONG $0; LONG $0; LONG $0; LONG $0
+#endif
-TEXT realmodeintr(SB), $0
- LONG $0
+TEXT crnl(SB), $0
+ BYTE $'\r'; BYTE $'\n'; BYTE $0
+TEXT hex(SB), $0
+ BYTE $'0'; BYTE $'1'; BYTE $'2'; BYTE $'3';
+ BYTE $'4'; BYTE $'5'; BYTE $'6'; BYTE $'7';
+ BYTE $'8'; BYTE $'9'; BYTE $'a'; BYTE $'b';
+ BYTE $'c'; BYTE $'d'; BYTE $'e'; BYTE $'f'