#include "mem.h"
/*
* Some machine instructions not handled by 8[al].
*/
#define WRMSR BYTE $0x0F; BYTE $0x30 /* WRMSR, lo argument in AX */
/* hi argument in DX */
#define RDMSR BYTE $0x0F; BYTE $0x32 /* RDMSR, lo result in AX */
/* hi result in DX */
#define FARJUMP(s, o) BYTE $0xEA; /* far jump to ptr32:16 */\
LONG $o; WORD $s
/*
* Macro for calculating offset within the page directory base.
* Note that this is assembler-specific hence the '<<2'.
*/
#define PDO(a) (((((a))>>22) & 0x03FF)<<2)
TEXT _warp64(SB), $0
CLI
MOVL cr3+0(FP), BP /* pml4 */
MOVL CR3, CX /* load address of PDB */
ADDL $KZERO, CX
MOVL PDO(KZERO)(CX), DX /* double-map KZERO at 0 */
MOVL DX, PDO(0)(CX)
MOVL CR3, CX
MOVL CX, CR3 /* load and flush the mmu */
MOVL $_start32id<>-KZERO(SB), AX
JMP* AX /* jump to identity-map */
TEXT _start32id<>(SB), $0
MOVL CR0, DX /* turn off paging */
ANDL $~0x80000000, DX /* ~(PG) */
MOVL $_stop32pg<>-KZERO(SB), AX
MOVL DX, CR0
JMP* AX /* forward into the past */
TEXT _stop32pg<>(SB), $0
MOVL $multibootheader-KZERO(SB), BX
MOVL $0x2badb002, AX
MOVL $0x00110000, CX
JMP* CX
MOVL CR4, AX
ORL $0x00000020, AX /* Pae */
MOVL AX, CR4
MOVL BP, CR3 /* pml4 */
MOVL $0xC0000080, CX /* Extended Feature Enable */
RDMSR
ORL $0x00000100, AX /* Long Mode Enable */
MOVL $0xC0000080, CX
WRMSR
MOVL CR0, DX /* enable paging */
ORL $0x80010000, DX
MOVL $_start32cm<>-KZERO(SB), AX
MOVL DX, CR0
JMP* AX
TEXT _start32cm<>(SB), $0 /* compatibility mode */
MOVL $_gdtptr64<>-KZERO(SB), AX /* load a long-mode GDT */
MOVL (AX), GDTR
MOVL $_start64lm<>-KZERO(SB), AX
JMP* AX
TEXT _start64lm<>(SB), $0 /* finally - long mode */
MOVL $multibootheader-KZERO(SB), BX /* multiboot data pointer */
MOVL $0x2badb002, AX /* multiboot magic */
FARJUMP((1<<3), 0x00110000) /* selector 1, in GDT, RPL 0 */
_idle:
JMP _idle
TEXT _gdt64<>(SB), $0
LONG $0x00000000; LONG $0x00000000 /* NULL descriptor */
LONG $0x00000000; LONG $0x00209800 /* CS */
LONG $0x00000000; LONG $0x00008000 /* DS */
TEXT _gdtptr64<>(SB), $0
WORD $(3*8-1)
LONG $_gdt64<>-KZERO(SB)
|