;; ######################################################################## ;; Macros ;; ######################################################################## ; descriptor type, base, limit, p_dpl_s, g_db_a %macro descriptor 5 dw %3 ; Limit 15-0 dw %2 ; Base 15-0 db %2 >> 16 ; Base 23-16 db ((%4 & 0xF) << 4) | (%1 & 0xF ) ; p_dpl_s_type db (%5 << 4) | ((%3 & 0xF0000) >> 16) ; g_db_a limit 19:16 db %2 >> 24 ; Base 31-24 %endmacro ; cdesc64 base, limit, dpl %macro cdesc64 3 descriptor 0xB, %1, %2, 0x9 | (%3 & 0x3) << 1, 0xD %endmacro ; gates type, offset, selector, p_dpl_s %macro gates 4 dw %2 ; Offset 15-00 dw %3 ; Selector db 0 ; Ist db ((%4 & 0xF) << 4) | (%1 & 0xF) ; p_dpl_s_type dw %2 >> 16 ; Offset 31-16 dd %2 >> 32 ; Offset 63-32 %endmacro ; idesc64 offset, selector, ring %macro idesc64 3 gates 0xE, %1, %2, 0x8 | ((%3 & 0x3) << 1) %endmacro ; pageDirectory2M addr, nx, a, pcd, pwt, u, w, p %macro pageDirectory2M 8 db %2 << 7 dw %1 >> 40 dd %1 >> 8 db (%3 << 5) | (%4 << 4) | (%5 << 3) | (%6 << 2) | (%7 << 1) | %8 %endmacro ; pageEntry2M addr, nx, pat, g, d, a, pcd, pwt, u, w, p %macro pageEntry2M 11 db %2 << 7 db %1 >> 48 dd %1 >> 16 dw (%3 << 12) | (%4 << 8) | (%5 << 6) | (%6 << 5) | (%7 << 4) | (%8 << 3) | (%9 << 2) | (%10 << 1) | %11 | 0x80 %endmacro ;; ######################################################################## ;; Code Section ;; ######################################################################## SECTION CODE ABSOLUTE=0xFFFFFFFF00000000 FLAT USE64 test_code: ;; Your Code Goes Here add r8, r15 hlt ;; ######################################################################## ;; Setup Section ;; ######################################################################## SECTION SETUP ALIGN=16 FLAT USE16 setup: xor edx, edx ; Enable Var MTRRs mov eax, 0x0806 ; WriteBack mov ecx, 0x2FF wrmsr mov ebx, cr0 or ebx, 0x00000021 ; Protect Mode On, Int 16 for FPU and ebx, 0x9FFFFFFF ; Turn Caches on mov cr0, ebx mov edx, cr4 or edx, 0x00000620 ; Enable PAE, SSE OSFXSR, SEE OSXMMEXCPT mov cr4, edx mov edx, pageMapL4 ; load pagetables mov cr3, edx mov ecx, 0x80000080 rdmsr ; Read EFER bts eax, 8 ; Enable Long Mode (LME=1) wrmsr ; Write EFER bts ebx, 31 ; Enable Paging (PG=1) mov cr0, ebx ;; At this point LME=1, PAE=1, PG=1, CS.L=0, CS.D=0 lgdt [pgdt] ; Set GDT lidt [pidt] ; Set IDT jmp 0x8 : long_mode long_mode: BITS 64 mov rax, qword test_code ; jmp to testcode jmp [rax] ;; ######################################################################## ;; Long Mode IDT ;; ######################################################################## SECTION IDTP ALIGN=16 FLAT USE64 ;; cdesc32 base, limit, dpl gdt0: dq 0 ; 0x0000 - Null descriptor cdesc64 zero, 0xFFFFF, 0 ; 0x0008 - Code Selector gdt_: ;; idesc64 offset, selector, dpl idt0: idesc64 isrL, 0x0008, 0 ; 0x00, 0 #DE, Divide Error idesc64 isrL, 0x0008, 0 ; 0x01, 1 #DB, Debug Fault idesc64 isrL, 0x0008, 0 ; 0x02, 2, ---, NMI idesc64 isrL, 0x0008, 0 ; 0x03, 3, #BP, Breakpoint idesc64 isrL, 0x0008, 0 ; 0x04, 4, #OF, INTO detected Overflow idesc64 isrL, 0x0008, 0 ; 0x05, 5, #BR, Bound Range Exceeded idesc64 isrL, 0x0008, 0 ; 0x06, 6, #UD, Invalid Opcode idesc64 isrL, 0x0008, 0 ; 0x07, 7, #NM, Device Not Available idesc64 isrL, 0x0008, 0 ; 0x08, 8, #DF, Double Fault idesc64 isrL, 0x0008, 0 ; 0x09 9, ---, Coprocessor Segment Overrun idesc64 isrL, 0x0008, 0 ; 0x0A, 10, #TS, Invalid TSS idesc64 isrL, 0x0008, 0 ; 0x0B, 11, #NP, Segment Not Present idesc64 isrL, 0x0008, 0 ; 0x0C, 12, #SS, Stack Fault idesc64 isrL, 0x0008, 0 ; 0x0D, 13, #GP, General Protection Fault idesc64 isrL, 0x0008, 0 ; 0x0E, 14, #PF, Page Fault idesc64 isrL, 0x0008, 0 ; 0x0F, 15, ---, Reserved idesc64 isrL, 0x0008, 0 ; 0x10, 16, #MF, Floating Point Fault idesc64 isrL, 0x0008, 0 ; 0x11, 17, #AC, Alignment Check idesc64 isrL, 0x0008, 0 ; 0x12 18, #MC, Machine Check idesc64 isrL, 0x0008, 0 ; 0x13, 19, #XF, SSE Fault idt_: pgdt: dw (gdt_ - gdt0) ; Limit dd gdt0 ; base pidt: dw (idt_ - idt0) ; Limit dd idt0 ; base isrL: mov eax, 0xDEADBEEF ; Default Interrupt Handler out 0x80, eax hlt ;; ######################################################################## ;; Real Mode IDT ;; ######################################################################## SECTION IDTR ABSOLUTE=0x00000000 FLAT USE16 ;; FORMAT IP:CS zero: dw isrR, 0 ; 0x00, 0 #DE, Divide Error dw isrR, 0 ; 0x01, 1 #DB, Debug Fault dw isrR, 0 ; 0x02, 2, ---, NMI dw isrR, 0 ; 0x03, 3, #BP, Breakpoint dw isrR, 0 ; 0x04, 4, #OF, INTO detected Overflow dw isrR, 0 ; 0x05, 5, #BR, Bound Range Exceeded dw isrR, 0 ; 0x06, 6, #UD, Invalid Opcode dw isrR, 0 ; 0x07, 7, #NM, Device Not Available dw isrR, 0 ; 0x08, 8, #DF, Double Fault dw isrR, 0 ; 0x09 9, ---, Coprocessor Segment Overrun dw isrR, 0 ; 0x0A, 10, #TS, Invalid TSS dw isrR, 0 ; 0x0B, 11, #NP, Segment Not Present dw isrR, 0 ; 0x0C, 12, #SS, Stack Fault dw isrR, 0 ; 0x0D, 13, #GP, General Protection Fault dw isrR, 0 ; 0x0E, 14, #PF, Page Fault dw isrR, 0 ; 0x0F, 15, ---, Reserved dw isrR, 0 ; 0x10, 16, #MF, Floating Point Fault dw isrR, 0 ; 0x11, 17, #AC, Alignment Check dw isrR, 0 ; 0x12 18, #MC, Machine Check dw isrR, 0 ; 0x13, 19, #XF, SSE Fault isrR: mov eax, 0xDEADBEEF ; Default Real Interrupt Handler out 0x80, eax hlt ;; ######################################################################## ;; 2 Meg Page Tables ;; ######################################################################## SECTION PAGE ALIGN=4096 FLAT pageDirE: %assign addr 0 %rep 512 ; pageEntry addr, nx, pat, g, d, a, pcd, pwt, u, w, p pageEntry2M addr, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1 ; Accessed, WB, User, Writable, Present %assign addr addr + 0x200000 %endrep pageDirP: %rep 512 ; pageDirPointer addr, nx, a, pcd, pwt, u, w, p pageDirectory2M pageDirE, 0, 1, 0, 0, 1, 1, 1 ; Accessed, WB, User, Writable, Present %endrep pageMapL4: %rep 512 ; pageDirectory addr, nx, a, pcd, pwt, u, w, p pageDirectory2M pageDirP, 0, 1, 0, 0, 1, 1, 1 ; Accessed, WB, User, Writable, Present %endrep ;; ######################################################################## ;; SMM Handler ;; ######################################################################## SECTION SMM ABSOLUTE=0x00038000 USE16 rsm ;; ######################################################################## ;; Reset Vector ;; ######################################################################## SECTION RESET ABSOLUTE=0xFFFFFFF0 USE16 jmp far setup