/*++ Copyright (c) 2015 Minoca Corp. This file is licensed under the terms of the GNU General Public License version 3. Alternative licensing terms are available. Contact info@minocacorp.com for details. See the LICENSE file at the root of this project for complete licensing information. Module Name: x64.inc Abstract: This module contains common definitions for the 64-bit x86 architecture. Author: Evan Green 17-Jan-2015 Environment: Any --*/ // // ------------------------------------------------------------------ Includes // #include // // --------------------------------------------------------------- Definitions // // // Basic constants. // #define FALSE 0 #define TRUE 1 #define EXCEPTION_NMI 0x02 #define EXCEPTION_BREAK 0x03 #define EXCEPTION_SINGLE_STEP 0x04 #define EXCEPTION_ACCESS_VIOLATION 0x05 #define EXCEPTION_ASSERTION_FAILURE 0x07 #define EXCEPTION_DOUBLE_FAULT 0x0C #define CONTEXT_SWAP_MAGIC 0x5A4A3A2A // // Relevant TSS structure definitions. // #define TSS_RSP0 0x04 // // Processor block offsets. // #define PROCESSOR_BLOCK_TSS 0x10 // // Definition for the TRAP_FRAME structure and the exception stack directly // above it. // #define TRAP_DS 0 #define TRAP_ES 4 #define TRAP_FS 8 #define TRAP_GS 12 #define TRAP_PADDING 16 #define TRAP_RAX 24 #define TRAP_RBX 32 #define TRAP_RCX 40 #define TRAP_RDX 48 #define TRAP_RSI 56 #define TRAP_RDI 64 #define TRAP_RBP 72 #define TRAP_R8 80 #define TRAP_R9 88 #define TRAP_R10 96 #define TRAP_R11 104 #define TRAP_R12 112 #define TRAP_R13 120 #define TRAP_R14 128 #define TRAP_R15 136 #define TRAP_ERRORCODE 144 #define TRAP_RIP 152 #define TRAP_CS 160 #define TRAP_RFLAGS 168 #define TRAP_RSP 176 #define TRAP_SS 184 #define TRAP_FRAME_SIZE 192 // // Define the system call numbers used by assembly, and some relevant // structure sizes. // #define SystemCallRestoreContext 1 #define SystemCallForkProcess 2 #define PROCESSOR_CONTEXT_SIZE 284 #define SIGNAL_CONTEXT_SIZE 48 // // Define the minimum and maximum external interrupt vectors. // #define MINIMUM_VECTOR 0x30 #define MAXIMUM_VECTOR 0xFF // // APIC End Of Interrupt Offset. // #define APIC_EOI_OFFSET 0x0B // // -------------------------------------------------------------------- Macros // // // This macro goes at the start of every assembly file. // #define ASSEMBLY_FILE_HEADER \ .text ; \ .code64 // // This macro loads DS, ES, and GS with the correct values for the kernel. // #define LOAD_KERNEL_DATA_SEGMENTS \ movw $KERNEL_DS, %ax ; \ mov %ax, %ds ; \ mov %ax, %ss ; \ mov %ax, %es ; \ xorl %eax, %eax ; \ mov %ax, %fs ; \ mov %ax, %gs ; #if defined(__WINNT__) || defined(__CYGWIN__) #define FUNCTION(_Name) \ _Name: \ .def _##_Name; .scl 2; .type 32; .endef ; \ .global _##_Name ; \ _##_Name: #define PROTECTED_FUNCTION(_Name) FUNCTION(_Name) #define EXPORTED_FUNCTION(_Name) FUNCTION(_Name) #define END_FUNCTION(_Name) #elif defined(__ELF__) // // This macro defines a function, callable from C code in any module and // capable of being overridden by other functions. // #define EXPORTED_FUNCTION(_Name) \ .func _Name ; \ .type _Name, %function ; \ .cfi_startproc ; \ .cfi_def_cfa %rsp, 8 ; \ .cfi_offset %rip, -8 ; \ .global _Name ; \ _Name: // // This macro defines a function, callable from C code in the current module // only. // #define FUNCTION(_Name) \ .hidden _Name ; \ EXPORTED_FUNCTION(_Name) // // This macro defines a function, callable from C code in any module but always // called locally in the current module. // #define PROTECTED_FUNCTION(_Name) \ .protected _Name ; \ EXPORTED_FUNCTION(_Name) #define END_FUNCTION(_Name) \ .size _Name, .-_Name ; \ .endfunc ; \ .cfi_endproc #elif defined(__APPLE__) #define FUNCTION(_Name) \ .global _##_Name ; \ _##_Name: #define PROTECTED_FUNCTION(_Name) FUNCTION(_Name) #define EXPORTED_FUNCTION(_Name) FUNCTION(_Name) #define END_FUNCTION(_Name) #else #define FUNCTION(_Name) \ .global _Name ; \ _Name: #define PROTECTED_FUNCTION(_Name) FUNCTION(_Name) #define EXPORTED_FUNCTION(_Name) FUNCTION(_Name) #define END_FUNCTION(_Name) #endif // // This macro sets the call frame information so that the debugger can unwind // a trap frame. It assumes the CFA register is esp, and sets the CFA to the // base of the trap frame just to make things easier. // #define CFI_TRAP_FRAME_PUSHED \ .cfi_def_cfa_offset 0 ; \ .cfi_offset %rax, TRAP_RAX ; \ .cfi_offset %rbx, TRAP_RBX ; \ .cfi_offset %rcx, TRAP_RCX ; \ .cfi_offset %rdx, TRAP_RDX ; \ .cfi_offset %rsi, TRAP_RSI ; \ .cfi_offset %rdi, TRAP_RDI ; \ .cfi_offset %rbp, TRAP_RBP ; \ .cfi_offset %r8, TRAP_R8 ; \ .cfi_offset %r9, TRAP_R9 ; \ .cfi_offset %r10, TRAP_R10 ; \ .cfi_offset %r11, TRAP_R11 ; \ .cfi_offset %r12, TRAP_R12 ; \ .cfi_offset %r13, TRAP_R13 ; \ .cfi_offset %r14, TRAP_R14 ; \ .cfi_offset %r15, TRAP_R15 ; \ .cfi_offset %rip, TRAP_RIP ; \ .cfi_offset %rsp, TRAP_RSP ; \ .cfi_offset %rflags, TRAP_RFLAGS // // This macro sets the call frame information just after a trap frame was // restored. It indicates to the debugger that most registers are now in their // proper place. It assumes the CFA register is esp+0. // #define CFI_TRAP_FRAME_POPPED \ .cfi_same_value %rax ; \ .cfi_same_value %rbx ; \ .cfi_same_value %rcx ; \ .cfi_same_value %rdx ; \ .cfi_same_value %rsi ; \ .cfi_same_value %rdi ; \ .cfi_same_value %rbp ; \ .cfi_same_value %r8 ; \ .cfi_same_value %r9 ; \ .cfi_same_value %r10 ; \ .cfi_same_value %r11 ; \ .cfi_same_value %r12 ; \ .cfi_same_value %r13 ; \ .cfi_same_value %r14 ; \ .cfi_same_value %r15 ; \ .cfi_offset %rip, 0 // // Define .cfi directives, macroed so they can be excised if unneeded. // #define CFI_DEF_CFA(_Register, _Offset) .cfi_def_cfa _Register, _Offset #define CFI_DEF_CFA_OFFSET(_Offset) .cfi_def_cfa_offset _Offset #define CFI_ADJUST_CFA_OFFSET(_Amount) .cfi_adjust_cfa_offset _Amount #define CFI_OFFSET(_Register, _Offset) .cfi_offset _Register, _Offset #define CFI_UNDEFINED(_Register) .cfi_undefined _Register #define CFI_SAME_VALUE(_Register) .cfi_same_value _Register