*/
TEXT _multibootheader(SB), $0
LONG $0x1BADB002 /* magic */
- LONG $0x00010003 /* flags */
- LONG $-(0x1BADB002 + 0x00010003) /* checksum */
+ LONG $0x00010007 /* flags */
+ LONG $-(0x1BADB002 + 0x00010007) /* checksum */
LONG $_multibootheader-KZERO(SB) /* header_addr */
LONG $_startKADDR-KZERO(SB) /* load_addr */
LONG $edata-KZERO(SB) /* load_end_addr */
LONG $0 /* mode_type */
LONG $0 /* width */
LONG $0 /* height */
- LONG $0 /* depth */
+ LONG $32 /* depth */
/*
* the kernel expects the data segment to be page-aligned
INCL CX /* one more for post decrement */
STD
REP; MOVSB
- ADDL $KZERO, BX
- MOVL BX, multiboot-KZERO(SB)
- MOVL $_startPADDR(SB), AX
- ANDL $~KZERO, AX
+ MOVL BX, multibootptr-KZERO(SB)
+ MOVL $_startPADDR-KZERO(SB), AX
JMP* AX
-/* multiboot structure pointer */
-TEXT multiboot(SB), $0
+/* multiboot structure pointer (physical address) */
+TEXT multibootptr(SB), $0
LONG $0
/*
CLI /* make sure interrupts are off */
/* set up the gdt so we have sane plan 9 style gdts. */
- MOVL $tgdtptr(SB), AX
- ANDL $~KZERO, AX
+ MOVL $tgdtptr-KZERO(SB), AX
MOVL (AX), GDTR
MOVW $1, AX
MOVW AX, MSW
WORD $(3*8)
LONG $tgdt-KZERO(SB)
-TEXT m0rgdtptr(SB), $0
- WORD $(NGDT*8-1)
- LONG $(CPU0GDT-KZERO)
-
-TEXT m0gdtptr(SB), $0
- WORD $(NGDT*8-1)
- LONG $CPU0GDT
-
-TEXT m0idtptr(SB), $0
- WORD $(256*8-1)
- LONG $IDTADDR
+TEXT vtgdtptr(SB), $0
+ WORD $(3*8)
+ LONG $tgdt(SB)
TEXT mode32bit(SB), $0
- /* At this point, the GDT setup is done. */
-
MOVL $((CPU0END-CPU0PDB)>>2), CX
MOVL $PADDR(CPU0PDB), DI
XORL AX, AX
* be initialised here.
*/
TEXT _startpg(SB), $0
+ MOVL $vtgdtptr(SB), AX
+ MOVL (AX), GDTR
+
MOVL $0, (PDO(0))(CX) /* undo double-map of KZERO at 0 */
MOVL CX, CR3 /* load and flush the mmu */
MOVL CR2, AX
RET
+TEXT putcr2(SB), $0
+ MOVL cr2+0(FP), AX
+ MOVL AX, CR2
+ RET
+
TEXT getcr3(SB), $0 /* CR3 - page directory base */
MOVL CR3, AX
RET
MOVL BP, AX /* BP set to -1 if traped */
RET
+/* fault-proof memcpy */
+TEXT peek(SB), $0
+ MOVL src+0(FP), SI
+ MOVL dst+4(FP), DI
+ MOVL cnt+8(FP), CX
+ CLD
+TEXT _peekinst(SB), $0
+ REP; MOVSB
+ MOVL CX, AX
+ RET
+
/*
* Try to determine the CPU type which requires fiddling with EFLAGS.
* If the Id bit can be toggled then the CPUID instruction can be used
* 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(fun, regs[4]);
+ * cpuid(fn, sublvl, regs[4]);
*/
TEXT cpuid(SB), $0
MOVL $0x240000, AX
TESTL $0x200000, AX /* Id */
JZ _cpu486 /* can't toggle this bit on some 486 */
MOVL fn+0(FP), AX
+ MOVL sublvl+4(FP), CX
CPUID
JMP _cpuid
_cpu486:
XORL CX, CX
XORL DX, DX
_cpuid:
- MOVL regs+4(FP), BP
+ MOVL regs+8(FP), BP
MOVL AX, 0(BP)
MOVL BX, 4(BP)
MOVL CX, 8(BP)
WAIT
RET
-TEXT fpstatus(SB), $0 /* get floating point status */
- FSTSW AX
- RET
-
-TEXT fpenv(SB), $0 /* save state without waiting */
- MOVL p+0(FP), AX
- FSTENV 0(AX)
- RET
-
TEXT fpclear(SB), $0 /* clear pending exceptions */
FPON
FCLEX /* no WAIT */
FPOFF
RET
-TEXT fpssesave0(SB), $0 /* save state and disable */
+TEXT fpssesave(SB), $0 /* save state and disable */
MOVL p+0(FP), AX
FXSAVE 0(AX) /* no WAIT */
FPOFF
RET
-TEXT fpsserestore0(SB), $0 /* enable and restore state */
+TEXT fpsserestore(SB), $0 /* enable and restore state */
FPON
MOVL p+0(FP), AX
FXRSTOR 0(AX)
* Test-And-Set
*/
TEXT tas(SB), $0
+TEXT _tas(SB), $0
MOVL $0xDEADDEAD, AX
MOVL lock+0(FP), BX
XCHGL AX, (BX) /* lock->key */
_rnddone:
RET
+/* debug register access */
+
+TEXT putdr(SB), $0
+ MOVL p+0(FP), SI
+ MOVL 28(SI), AX
+ MOVL AX, DR7
+_putdr01236:
+ MOVL 0(SI), AX
+ MOVL AX, DR0
+ MOVL 4(SI), AX
+ MOVL AX, DR1
+ MOVL 8(SI), AX
+ MOVL AX, DR2
+ MOVL 12(SI), AX
+ MOVL AX, DR3
+ MOVL 24(SI), AX
+ MOVL AX, DR6
+ RET
+
+TEXT putdr01236(SB), $0
+ MOVL p+0(FP), SI
+ JMP _putdr01236
+
+TEXT getdr6(SB), $0
+ MOVL DR6, AX
+ RET
+
+TEXT putdr6(SB), $0
+ MOVL p+0(FP), AX
+ MOVL AX, DR6
+ RET
+
+TEXT putdr7(SB), $0
+ MOVL p+0(FP), AX
+ MOVL AX, DR7
+ RET
+
+/* VMX instructions */
+TEXT vmxon(SB), $0
+ /* VMXON 4(SP) */
+ BYTE $0xf3; BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+ JMP _vmout
+
+TEXT vmxoff(SB), $0
+ BYTE $0x0f; BYTE $0x01; BYTE $0xc4
+ JMP _vmout
+
+TEXT vmclear(SB), $0
+ /* VMCLEAR 4(SP) */
+ BYTE $0x66; BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+ JMP _vmout
+
+TEXT vmlaunch(SB), $0
+ MOVL $0x6C14, DI
+ MOVL SP, DX
+ BYTE $0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
+ JBE _vmout
+ MOVL $0x6C16, DI
+ MOVL $vmrestore(SB), DX
+ BYTE $0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
+ JBE _vmout
+
+ MOVL resume+4(FP), AX
+ TESTL AX, AX
+ MOVL ureg+0(FP), DI
+ MOVL 4(DI), SI
+ MOVL 8(DI), BP
+ MOVL 16(DI), BX
+ MOVL 20(DI), DX
+ MOVL 24(DI), CX
+ MOVL 28(DI), AX
+ MOVL 0(DI), DI
+ JNE _vmresume
+ BYTE $0x0f; BYTE $0x01; BYTE $0xc2 /* VMLAUNCH */
+ JMP _vmout
+_vmresume:
+ BYTE $0x0f; BYTE $0x01; BYTE $0xc3 /* VMRESUME */
+ JMP _vmout
+
+TEXT vmrestore(SB), $0
+ PUSHL DI
+ MOVL ureg+0(FP), DI
+ POPL 0(DI)
+ MOVL SI, 4(DI)
+ MOVL BP, 8(DI)
+ MOVL BX, 16(DI)
+ MOVL DX, 20(DI)
+ MOVL CX, 24(DI)
+ MOVL AX, 28(DI)
+ XORL AX, AX
+ RET
+
+TEXT vmptrld(SB), $0
+ /* VMPTRLD 4(SP) */
+ BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+ JMP _vmout
+
+TEXT vmwrite(SB), $0
+ MOVL addr+0(FP),DI
+ MOVL val+4(FP),DX
+ /* VMWRITE DX, DI */
+ BYTE $0x0f; BYTE $0x79; BYTE $0xfa
+ JMP _vmout
+
+TEXT vmread(SB), $0
+ MOVL addr+0(FP),DI
+ MOVL valp+4(FP),SI
+ /* VMREAD (SI), DI */
+ BYTE $0x0f; BYTE $0x78; BYTE $0x3e
+ JMP _vmout
+
+TEXT invept(SB), $0
+ MOVL type+0(FP), AX
+ /* INVEPT AX, 8(SP) */
+ BYTE $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x80; BYTE $0x44; BYTE $0x24; BYTE $0x08
+ JMP _vmout
+
+TEXT invvpid(SB), $0
+ MOVL type+0(FP), AX
+ /* INVVPID AX, 8(SP) */
+ BYTE $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x81; BYTE $0x44; BYTE $0x24; BYTE $0x08
+ JMP _vmout
+
+_vmout:
+ JC _vmout1
+ JZ _vmout2
+ XORL AX, AX
+ RET
+_vmout1:
+ MOVL $-1, AX
+ RET
+_vmout2:
+ MOVL $-2, AX
+ RET
+
/*
* Used to get to the first process:
* set up an interrupt return frame and IRET to user level.