The core x86-64 NLKD additions. Signed-Off-By: Jan Beulich Index: 2.6.14-nlkd/arch/x86_64/Kconfig.debug =================================================================== --- 2.6.14-nlkd.orig/arch/x86_64/Kconfig.debug 2005-11-09 11:12:39.000000000 +0100 +++ 2.6.14-nlkd/arch/x86_64/Kconfig.debug 2005-11-04 16:19:33.000000000 +0100 @@ -1,6 +1,7 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +source "debug/Kconfig" # !SMP for now because the context switch early causes GPF in segment reloading # and the GS base checking does the wrong thing then, causing a hang. Index: 2.6.14-nlkd/arch/x86_64/kernel/asm-offsets.c =================================================================== --- 2.6.14-nlkd.orig/arch/x86_64/kernel/asm-offsets.c 2005-11-04 17:14:08.000000000 +0100 +++ 2.6.14-nlkd/arch/x86_64/kernel/asm-offsets.c 2005-11-04 17:14:08.000000000 +0100 @@ -14,6 +14,13 @@ #include #include #include +#ifdef CONFIG_NLKD +# include +# include +#endif +#if defined(CONFIG_CDE) || defined(CONFIG_CDE_MODULE) +# include <../debug/nlkd/cdelock.h> +#endif #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -39,6 +46,7 @@ int main(void) ENTRY(kernelstack); ENTRY(oldrsp); ENTRY(pcurrent); + ENTRY(data_offset); ENTRY(irqcount); ENTRY(cpunumber); ENTRY(irqstackptr); @@ -65,9 +73,71 @@ int main(void) DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); DEFINE(pbe_next, offsetof(struct pbe, next)); BLANK(); +#define ENTRY(f) DEFINE(TSS_##f, offsetof (struct tss_struct, f)) + ENTRY(rsp0); + ENTRY(rsp1); + ENTRY(rsp2); + ENTRY(ist); +#undef ENTRY + BLANK(); DEFINE(EXCEPTION_STACK_SIZE, EXCEPTION_STKSZ); #if DEBUG_STKSZ > EXCEPTION_STKSZ DEFINE(DEBUG_IST, DEBUG_STACK); #endif +#ifdef CONFIG_NLKD + DEFINE(NMI_IST, NMI_STACK); + BLANK(); +# define FRAME_TYPE(t) DEFINE(AMD64_##t, AMD64_##t) + FRAME_TYPE(DIVIDE_ERROR); + FRAME_TYPE(DEBUG); + FRAME_TYPE(NMI); + FRAME_TYPE(BREAKPOINT); + FRAME_TYPE(OVERFLOW); + FRAME_TYPE(BOUNDS_CHECK); + FRAME_TYPE(ILLEGAL_OPCODE); + FRAME_TYPE(DEVICE_NOT_AVAILABLE); + FRAME_TYPE(DOUBLE_FAULT); + FRAME_TYPE(INVALID_TSS); + FRAME_TYPE(SEGMENT_NOT_PRESENT); + FRAME_TYPE(STACK_FAULT); + FRAME_TYPE(GENERAL_PROTECTION_FAULT); + FRAME_TYPE(PAGE_FAULT); + FRAME_TYPE(FP_ERROR); + FRAME_TYPE(ALIGNMENT_CHECK); + FRAME_TYPE(MACHINE_CHECK); + FRAME_TYPE(SIMD_FP_ERROR); + BLANK(); +# undef FRAME_TYPE +# define FRAME_DEF(f) DEFINE(FRAME_##f, offsetof (struct ftaInterruptionCtx_s, f)) + FRAME_DEF(type); + FRAME_DEF(sub_type); + FRAME_DEF(state); + FRAME_DEF(es); + FRAME_DEF(ds); + FRAME_DEF(fs); + FRAME_DEF(gs); + FRAME_DEF(ldtr); + FRAME_DEF(tr); + FRAME_DEF(fs_base); + FRAME_DEF(gs_base); + FRAME_DEF(cr0); + FRAME_DEF(cr2); + FRAME_DEF(cr3); + FRAME_DEF(cr4); + FRAME_DEF(cr8); + FRAME_DEF(dr7); + FRAME_DEF(debugCtl); + FRAME_DEF(ec); + FRAME_DEF(pt_regs); + FRAME_DEF(fp_mmx_xmm); +# undef FRAME_DEF +#endif +#if defined(CONFIG_CDE) || defined(CONFIG_CDE_MODULE) + BLANK(); + DEFINE(CDESPINLOCK_signature, offsetof (cdeSpinLock_t, cdeSpinLockSignature)); + DEFINE(CDESPINLOCK_cpu, offsetof (cdeSpinLock_t, cdeSpinLockCpu)); + DEFINE(CDE_VALID_SPINLOCK_SIGNATURE, CDE_VALID_SPINLOCK_SIGNATURE); + DEFINE(CDE_SPINLOCK_NOT_OWNED, CDE_SPINLOCK_NOT_OWNED); +#endif return 0; } Index: 2.6.14-nlkd/debug/nlkd/asm-amd64.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/debug/nlkd/asm-amd64.h 2005-11-07 12:11:27.000000000 +0100 @@ -0,0 +1,100 @@ +/***************************************************************************** + * + * File Name: asm-amd64.h + * Created by: Jan Beulich + * %version: 7 % + * %derived_by: jbeulich % + * %date_modified: Thu Nov 03 04:13:21 2005 % + * + *****************************************************************************/ +/***************************************************************************** + * * + * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, contact Novell, Inc. * + * * + * To contact Novell about this file by physical or electronic mail, * + * you may find current contact information at www.novell.com. * + * * + *****************************************************************************/ +/***************************************************************************** + * + * File Description: + * + *****************************************************************************/ + +#if defined(__ASSEMBLY__) && !defined(ASM_AMD64_H) +#define ASM_AMD64_H + +#include +#include + +#ifdef CONFIG_UNWIND_INFO +.equiv eh.rax, 0 +.equiv eh.rcx, 1 +.equiv eh.rdx, 2 +.equiv eh.rbx, 3 +.equiv eh.rsp, 4 +.equiv eh.rbp, 5 +.equiv eh.rsi, 6 +.equiv eh.rdi, 7 +.equiv eh.r8, 8 +.equiv eh.r9, 9 +.equiv eh.r10, 10 +.equiv eh.r11, 11 +.equiv eh.r12, 12 +.equiv eh.r13, 13 +.equiv eh.r14, 14 +.equiv eh.r15, 15 +.equiv eh.es, 16 +.equiv eh.cs, 17 +.equiv eh.ss, 18 +.equiv eh.ds, 19 +.equiv eh.fs, 20 +.equiv eh.gs, 21 + +# define SP rsp +# define BP rbp +# define FLAGS rflags +.equiv .eh.stkword, qword +.equiv .eh.preserved, (1 << eh.rbx) | (1 << eh.rbp) | (1 << eh.r12) | (1 << eh.r13) | (1 << eh.r14) | (1 << eh.r15) \ + | (1 << eh.es) | (1 << eh.cs) | (1 << eh.ds) | (1 << eh.ss) | (1 << eh.fs) | (1 << eh.gs) +#endif + +#include "asm-x86.h" + +.ifndef PROCEDURE_ALIGN + .equiv PROCEDURE_ALIGN, 0x10 +.endif + +.macro load sreg:req, loc:req, aux:req + LOCAL set, adj, skip +set: + mov sreg, loc +skip: + .section .fixup, "ax" +adj: + xor aux, aux + .ifeqs "gs", "&sreg" + swapgs + .endif + mov sreg, aux + jmp skip + .previous + .section __ex_table, "a" + .align qword + .quad set, adj + .previous +.endm + +#endif /* ASM_AMD64_H */ Index: 2.6.14-nlkd/debug/nlkd/nlkdAMD64.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/debug/nlkd/nlkdAMD64.S 2005-10-07 17:18:42.000000000 +0200 @@ -0,0 +1,75 @@ +/***************************************************************************** + * + * File Name: nlkdAMD64.S + * Created by: jbeulich + * %version: 2 % + * %derived_by: jbeulich % + * %date_modified: Fri Oct 07 09:18:32 2005 % + * + ****************************************************************************/ +/***************************************************************************** + * * + * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved. * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, contact Novell, Inc. * + * * + * To contact Novell about this file by physical or electronic mail, * + * you may find current contact information at www.novell.com. * + * * + *****************************************************************************/ +/***************************************************************************** + * + * File Description: + * + ****************************************************************************/ + +.equiv PROCEDURE_ALIGN, 1 +#include "asm-amd64.h" +#include + +//todo .file "nlkd" +.text + +// void nlkdDebugEvent(nint_t eventCode, ...); +.pubproc nlkdDebugEvent + cmp dword ptr [rip+nlkdAgentCount], 0 + jg 0f + test di, di + jg 1f +0: + movsx eax, di + mov rdi, rsi + mov rsi, rdx + mov rdx, rcx + mov rcx, r8 + mov r8, r9 + .hidentry _nlkdEnterDebuggerInstruction_ + int 3 +1: + ret +.endp nlkdDebugEvent +// void nlkdEnterDebugger(void); +.pubproc nlkdEnterDebugger + mov eax, DEBUG_EVENT_ENTER_DEBUGGER + jmp _nlkdEnterDebuggerInstruction_ +.endp nlkdEnterDebugger +// void nlkdPanic(const char*string, ...); +.pubproc nlkdPanic + mov eax, DEBUG_EVENT_PANIC + jmp _nlkdEnterDebuggerInstruction_ +.endp nlkdPanic +// void nlkdAssert(const char*string, const char*file, const char*func, nuint_t line); +.pubproc nlkdAssert + mov eax, DEBUG_EVENT_ASSERT + jmp _nlkdEnterDebuggerInstruction_ +.endp nlkdAssert Index: 2.6.14-nlkd/debug/nlkd/nlkdAMD64.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/debug/nlkd/nlkdAMD64.h 2005-10-10 14:50:39.000000000 +0200 @@ -0,0 +1,55 @@ +/***************************************************************************** + * + * File Name: nlkdAMD64.h + * Created by: Jan Beulich + * %version: 1 % + * %derived_by: jbeulich % + * %date_modified: Mon Oct 10 06:50:19 2005 % + * + *****************************************************************************/ +/***************************************************************************** + * * + * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved. * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, contact Novell, Inc. * + * * + * To contact Novell about this file by physical or electronic mail, * + * you may find current contact information at www.novell.com. * + * * + *****************************************************************************/ +/***************************************************************************** + * + * File Description: + * + *****************************************************************************/ + +#ifndef CONFIG_CDE +static void _set_debugreg(uintptr_t value, nuint_t regnum) { + switch(regnum) { + case 0: __asm__("movq %0,%%db0" : : "r" (value)); break; + case 1: __asm__("movq %0,%%db1" : : "r" (value)); break; + case 2: __asm__("movq %0,%%db2" : : "r" (value)); break; + case 3: __asm__("movq %0,%%db3" : : "r" (value)); break; + case 6: __asm__("movq %0,%%db6" : : "r" (value)); break; + case 7: __asm__("movq %0,%%db7" : : "r" (value)); break; + } +} +static int _disable_debugreg(struct pt_regs *regs, nuint_t regnum) +{ + _set_debugreg(0, 7); +} +static int _restore_debugreg(void) +{ + _set_debugreg(current->thread.debugreg7, 7); +} +#endif Index: 2.6.14-nlkd/include/asm-x86_64/fta-frame.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/include/asm-x86_64/fta-frame.h 2005-11-03 11:51:11.000000000 +0100 @@ -0,0 +1,216 @@ +/***************************************************************************** + * + * File Name: fta-frame.h + * Created by: Clyde Griffin + * Date created: 1/1/1999 + * + * %version: 8 % + * %derived_by: jbeulich % + * %date_modified: Thu Nov 03 03:50:57 2005 % + * + *****************************************************************************/ +/***************************************************************************** + * * + * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved. * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, contact Novell, Inc. * + * * + * To contact Novell about this file by physical or electronic mail, * + * you may find current contact information at www.novell.com. * + * * + *****************************************************************************/ +/***************************************************************************** + * + * File Description: + * This module contains the definition of a trap frame. + * + *****************************************************************************/ + +#ifndef _ASM_X86_64_FTA_FRAME_H +#define _ASM_X86_64_FTA_FRAME_H + +/* values for ftaInterruptionCtx_s.state */ +# ifdef CONFIG_NLKD_FTA +# define FRAME_COMPLETE_BIT 0 +# define FRAME_COMPLETE (1 << FRAME_COMPLETE_BIT) +# define FRAME_NESTED_BIT 1 +# define FRAME_NESTED (1 << FRAME_NESTED_BIT) +# endif + +# include +# include + +# ifndef __ASSEMBLY__ + +struct ftaInterruptionCtx_s { + uint32_t type; /* Trap type */ + int16_t sub_type; /* Extended type */ + uint16_t state; /* Framework/Debugger only */ + uint64_t ec; /* Error code */ + uint64_t cr0; + uint64_t cr4; + uint64_t cr2; + uint64_t cr3; + uint64_t debugCtl; + uint64_t dr7; + uint16_t ldtr; + uint16_t tr; + uint32_t _spare_; + uint16_t ds; + uint16_t es; + uint16_t fs; + uint16_t gs; + uint64_t fs_base; + uint64_t gs_base; + fxsave_t fp_mmx_xmm; + uint64_t cr8; + union { + struct pt_regs pt_regs; + struct { + union { + uint64_t r15; + uint32_t r15d; + uint16_t r15w; + uint8_t r15b; + }; + union { + uint64_t r14; + uint32_t r14d; + uint16_t r14w; + uint8_t r14b; + }; + union { + uint64_t r13; + uint32_t r13d; + uint16_t r13w; + uint8_t r13b; + }; + union { + uint64_t r12; + uint32_t r12d; + uint16_t r12w; + uint8_t r12b; + }; + union { + uint64_t rbp; + uint32_t ebp; + uint16_t bp; + uint8_t bpl; + }; + union { + uint64_t rbx; + uint32_t ebx; + uint16_t bx; + struct { + uint8_t bl; + uint8_t bh; + }; + }; + union { + uint64_t r11; + uint32_t r11d; + uint16_t r11w; + uint8_t r11b; + }; + union { + uint64_t r10; + uint32_t r10d; + uint16_t r10w; + uint8_t r10b; + }; + union { + uint64_t r9; + uint32_t r9d; + uint16_t r9w; + uint8_t r9b; + }; + union { + uint64_t r8; + uint32_t r8d; + uint16_t r8w; + uint8_t r8b; + }; + union { + uint64_t rax; + uint32_t eax; + uint16_t ax; + struct { + uint8_t al; + uint8_t ah; + }; + }; + union { + uint64_t rcx; + uint32_t ecx; + uint16_t cx; + struct { + uint8_t cl; + uint8_t ch; + }; + }; + union { + uint64_t rdx; + uint32_t edx; + uint16_t dx; + struct { + uint8_t dl; + uint8_t dh; + }; + }; + union { + uint64_t rsi; + uint32_t esi; + uint16_t si; + uint8_t sil; + }; + union { + uint64_t rdi; + uint32_t edi; + uint16_t di; + uint8_t dil; + }; + union { + uint64_t orig_rax; +# ifdef CONFIG_NLKD_FTA + uint64_t _ec_raw; +# endif + }; + union { + uint64_t rip; + uint32_t eip; + }; + uint16_t cs, _cs_pad[3]; + union { + uint64_t rflags; + uint32_t eflags; + uint16_t flags; + }; + union { + uint64_t rsp; + uint32_t esp; + uint16_t sp; + uint8_t spl; + }; + uint16_t ss, _ss_pad[3]; + }; +# ifdef CONFIG_NLKD_FTA + }; +# define FRAME_PTREGS(frame, field) (frame)->field +# else + } *pt_regs; +# define FRAME_PTREGS(frame, field) (frame)->pt_regs->field +# endif +}; +# endif /* __ASSEMBLY__ */ + +#endif /* _ASM_X86_64_FTA_FRAME_H */ Index: 2.6.14-nlkd/include/asm-x86_64/fta-type.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/include/asm-x86_64/fta-type.h 2005-06-27 14:04:21.000000000 +0200 @@ -0,0 +1,89 @@ +/***************************************************************************** + * + * File Name: fta-type.h + * Created by: Clyde Griffin + * Date created: 1/1/1999 + * + * %version: 5 % + * %derived_by: jbeulich % + * %date_modified: Mon Jun 27 05:11:34 2005 % + * + *****************************************************************************/ +/***************************************************************************** + * * + * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved. * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, contact Novell, Inc. * + * * + * To contact Novell about this file by physical or electronic mail, * + * you may find current contact information at www.novell.com. * + * * + *****************************************************************************/ +/***************************************************************************** + * + * File Description: + * This module contains the definition of a trap frame. + * + *****************************************************************************/ + +#ifndef _ASM_X86_64_FTA_TYPE_H +#define _ASM_X86_64_FTA_TYPE_H + +/* + * ftaInterruptionId_t + * + * ftaInterruptionId_t uniquely identifies each type of interruption. + * + * NOTE: + * Interruption frames may be different for faults, traps, external + * interrupts and aborts. The consumer of an interruption frame + * needs to be aware of which interruption types are associated with + * with interruption frame types. + */ +enum ftaInterruptionId_e +{ + AMD64_DIVIDE_ERROR, + AMD64_DEBUG, + AMD64_NMI, + AMD64_BREAKPOINT, + AMD64_OVERFLOW, /* compatibility mode only */ + AMD64_BOUNDS_CHECK, /* compatibility mode only */ + AMD64_ILLEGAL_OPCODE, + AMD64_DEVICE_NOT_AVAILABLE, + AMD64_DOUBLE_FAULT, + AMD64_RSVD_09, + AMD64_INVALID_TSS, + AMD64_SEGMENT_NOT_PRESENT, + AMD64_STACK_FAULT, + AMD64_GENERAL_PROTECTION_FAULT, + AMD64_PAGE_FAULT, + AMD64_RSVD_0F, + AMD64_FP_ERROR, + AMD64_ALIGNMENT_CHECK, + AMD64_MACHINE_CHECK, + AMD64_SIMD_FP_ERROR, + AMD64_RSVD_14, + AMD64_RSVD_15, + AMD64_RSVD_16, + AMD64_RSVD_17, + AMD64_RSVD_18, + AMD64_RSVD_19, + AMD64_RSVD_1A, + AMD64_RSVD_1B, + AMD64_RSVD_1C, + AMD64_RSVD_1D, + AMD64_RSVD_1E, + AMD64_RSVD_1F +}; + +#endif /* _ASM_X86_64_FTA_TYPE_H */ Index: 2.6.14-nlkd/include/asm-x86_64/x86_64.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/include/asm-x86_64/x86_64.h 2005-11-03 11:51:44.000000000 +0100 @@ -0,0 +1,934 @@ +/***************************************************************************** + * + * File Name: x86_64.h + * Created by: Jan Beulich + * Date created: Wed Aug 28 02:58:50 2002 + * + * %version: 9 % + * %derived_by: jbeulich % + * %date_modified: Thu Nov 03 03:51:31 2005 % + * + *****************************************************************************/ +/***************************************************************************** + * * + * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved. * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, contact Novell, Inc. * + * * + * To contact Novell about this file by physical or electronic mail, * + * you may find current contact information at www.novell.com. * + * * + *****************************************************************************/ +/***************************************************************************** + * + * File Description: + * + *****************************************************************************/ + +#ifndef _ASM_X86_64_X86_64_H +#define _ASM_X86_64_X86_64_H + +#ifdef __ASSEMBLY__ +# define UINT64_C(v) (v) +#else +# include +#endif + +/* + * RFLAGS + */ +#define RFLAGS_MBZ UINT64_C(0xffffffffffc08028) +#define RFLAGS_MBS UINT64_C(0x0000000000000002) +#define RFLAGS_CF 0 +#define RFLAGS_PF 2 +#define RFLAGS_AF 4 +#define RFLAGS_ZF 6 +#define RFLAGS_SF 7 +#define RFLAGS_TF 8 +#define RFLAGS_IF 9 +#define RFLAGS_DF 10 +#define RFLAGS_OF 11 +#define RFLAGS_IOPL 12 +#define RFLAGS_IOPL_LEN 2 +#define RFLAGS_NT 14 +#define RFLAGS_RF 16 +#define RFLAGS_VM 17 +#define RFLAGS_AC 18 +#define RFLAGS_VIF 19 +#define RFLAGS_VIP 20 +#define RFLAGS_ID 21 + +/* + * Privilege levels + */ +#define PL_KERNEL 0 +#define PL_USER 3 + +/* + * Selector layout + */ +#define SELECTOR_RPL 0 +#define SELECTOR_RPL_LEN 2 +#define SELECTOR_TI 2 +#define SELECTOR_INDEX 3 +#define SELECTOR_INDEX_LEN 13 + +/* + * Descriptor Attributes + */ +#define DESCRIPTOR_TYPE 0 +#define DESCRIPTOR_TYPE_LEN 5 +# define DESCRIPTOR_INVALID 0x00 +# define DESCRIPTOR_LDT 0x02 +# define DESCRIPTOR_AVAILTSS 0x09 +# define DESCRIPTOR_BUSYTSS 0x0b +# define DESCRIPTOR_CALLGATE 0x0c +# define DESCRIPTOR_INTGATE 0x0e +# define DESCRIPTOR_TRAPGATE 0x0f +# define DESCRIPTOR_DATASEG 0x10 +# define DESCRIPTOR_CODESEG 0x18 +# define DESCRIPTOR_CONFORMING 0x1c +# define DESCR32_DATA_RO 0x10 +# define DESCR32_DATA_RO_ACC 0x11 +# define DESCR32_DATA_RW 0x12 +# define DESCR32_DATA_RW_ACC 0x13 +# define DESCR32_DOWN_RO 0x14 +# define DESCR32_DOWN_RO_ACC 0x15 +# define DESCR32_DOWN_RW 0x16 +# define DESCR32_DOWN_RW_ACC 0x17 +# define DESCR32_CODE_XO 0x18 +# define DESCR32_CODE_XO_ACC 0x19 +# define DESCR32_CODE_XR 0x1a +# define DESCR32_CODE_XR_ACC 0x1b +# define DESCR32_CONF_XO 0x1c +# define DESCR32_CONF_XO_ACC 0x1d +# define DESCR32_CONF_XR 0x1e +# define DESCR32_CONF_XR_ACC 0x1f +#define DESCR32_A 0 +#define DESCR32_W 1 +#define DESCR32_R 1 +#define DESCR32_E 2 +#define DESCRIPTOR_C 2 +#define DESCRIPTOR_CODE 3 +#define DESCRIPTOR_S 4 +#define DESCRIPTOR_DPL 5 +#define DESCRIPTOR_DPL_LEN 2 +#define DESCRIPTOR_P 7 + +#define DESCRIPTOR_AVL 12 +#define DESCRIPTOR_L 13 +#define DESCRIPTOR_D 14 +#define DESCR32_B 14 +#define DESCR32_G 15 + +/* + * Error code layout (different for Page Fault) + */ +#define EC_EXT 0 +#define EC_IDT 1 +#define EC_TI 2 +#define EC_SELECTOR_INDEX 3 +#define EC_SELECTOR_INDEX_LEN 13 + +/* + * Control Register 0 + */ +#define CR0_MBZ UINT64_C(0xffffffff1ffaffc0) +#define CR0_PE 0 +#define CR0_MP 1 +#define CR0_EM 2 +#define CR0_TS 3 +#define CR0_ET 4 +#define CR0_NE 5 +#define CR0_WP 16 +#define CR0_AM 18 +#define CR0_NW 29 +#define CR0_CD 30 +#define CR0_PG 31 + +/* + * Control Register 3 + */ +#define CR3_MBZ UINT64_C(0x0000000000000fe7) +#define CR3_PWT 3 +#define CR3_PCD 4 +#define CR3_PHYS 12 +#define CR3_PHYS_LEN 40 + +/* + * Control Register 4 + */ +#define CR4_MBZ UINT64_C(0xfffffffffffff800) +#define CR4_VME 0 +#define CR4_PVI 1 +#define CR4_TSD 2 +#define CR4_DE 3 +#define CR4_PSE 4 +#define CR4_PAE 5 +#define CR4_MCE 6 +#define CR4_PGE 7 +#define CR4_PCE 8 +#define CR4_OSFXSR 9 +#define CR4_OSXMMEXCPT 10 + +/* + * Control Register 8 + */ +#define CR8_MBZ UINT64_C(0xfffffffffffffff0) +#define CR8_TPR 0 +#define CR8_TPR_LEN 4 + +/* + * Page Directory Pointer Table Entry + */ +#define PML4E_MBZ UINT64_C(0x00000000000001c0) +#define PML4E_P 0 +#define PML4E_W 1 +#define PML4E_U 2 +#define PML4E_PWT 3 +#define PML4E_PCD 4 +#define PML4E_A 5 +#define PML4E_AVL 9 +#define PML4E_AVL_LEN 3 +#define PML4E_PHYS 12 +#define PML4E_PHYS_LEN 40 +#define PML4E_AVL2 52 +#define PML4E_AVL2_LEN 11 +#define PML4E_NX 63 + +/* + * Page Directory Pointer Table Entry + */ +#define PDPE_MBZ UINT64_C(0x00000000000001c0) +#define PDPE_P 0 +#define PDPE_W 1 +#define PDPE_U 2 +#define PDPE_PWT 3 +#define PDPE_PCD 4 +#define PDPE_A 5 +#define PDPE_AVL 9 +#define PDPE_AVL_LEN 3 +#define PDPE_PHYS 12 +#define PDPE_PHYS_LEN 40 +#define PDPE_AVL2 52 +#define PDPE_AVL2_LEN 11 +#define PDPE_NX 63 + +/* + * Page Directory Entry + */ +#define PDE_MBZ UINT64_C(0x00000000000001c0) +#define PDE_P 0 +#define PDE_W 1 +#define PDE_U 2 +#define PDE_PWT 3 +#define PDE_PCD 4 +#define PDE_A 5 +#define PDE_LARGE_PTE 7 +#define PDE_AVL 9 +#define PDE_AVL_LEN 3 +#define PDE_PHYS 12 +#define PDE_PHYS_LEN 40 +#define PDE_AVL2 52 +#define PDE_AVL2_LEN 11 +#define PDE_NX 63 + +/* + * Page Table Entry + */ +#define PTE4K_MBZ (UINT64_C(1) << PDE_LARGE_PTE) +#define PTE2M_MBZ UINT64_C(0x00000000001fe000) +#define PTE2M_MBS (UINT64_C(1) << PDE_LARGE_PTE) +#define PTE_P 0 +#define PTE_W 1 +#define PTE_U 2 +#define PTE_PWT 3 +#define PTE_PCD 4 +#define PTE_A 5 +#define PTE_D 6 +#define PTE4K_PAT 7 +#define PTE_G 8 +#define PTE_AVL 9 +#define PTE_AVL_LEN 3 +#define PTE2M_PAT 12 +#define PTE4K_PHYS 12 +#define PTE4K_PHYS_LEN 40 +#define PTE2M_PHYS 21 +#define PTE2M_PHYS_LEN 31 +#define PTE_AVL2 52 +#define PTE_AVL2_LEN 11 +#define PTE_NX 63 + +/* + * Debug Register 6 + */ +#define DR6_B0 0 +#define DR6_B1 1 +#define DR6_B2 2 +#define DR6_B3 3 +#define DR6_BD 13 +#define DR6_BS 14 +#define DR6_BT 15 + +/* + * Debug Register 7 + */ +#define DR7_RW_LEN 2 +# define DR7_RW_X 0U +# define DR7_RW_W 1U +# define DR7_RW_IO 2U +# define DR7_RW_RW 3U +#define DR7_LEN_LEN 2 +# define DR7_LEN_1 0U +# define DR7_LEN_2 1U +# define DR7_LEN_4 3U +# define DR7_LEN_8 2U +#define DR7_L0 0 +#define DR7_G0 1 +#define DR7_L1 2 +#define DR7_G1 3 +#define DR7_L2 4 +#define DR7_G2 5 +#define DR7_L3 6 +#define DR7_G3 7 +#define DR7_LE 8 +#define DR7_GE 9 +#define DR7_GD 13 +#define DR7_RW0 16 +#define DR7_RW0_LEN DR7_RW_LEN +#define DR7_LEN0 18 +#define DR7_LEN0_LEN DR7_LEN_LEN +#define DR7_RW1 20 +#define DR7_RW1_LEN DR7_RW_LEN +#define DR7_LEN1 22 +#define DR7_LEN1_LEN DR7_LEN_LEN +#define DR7_RW2 24 +#define DR7_RW2_LEN DR7_RW_LEN +#define DR7_LEN2 26 +#define DR7_LEN2_LEN DR7_LEN_LEN +#define DR7_RW3 28 +#define DR7_RW3_LEN DR7_RW_LEN +#define DR7_LEN3 30 +#define DR7_LEN3_LEN DR7_LEN_LEN + +/* + * CPUID return values + */ +#define CPUID1_EAX_STEPPING 0 +#define CPUID1_EAX_STEPPING_LEN 4 +#define CPUID1_EAX_MODEL 4 +#define CPUID1_EAX_MODEL_LEN 4 +#define CPUID1_EAX_FAMILY 8 +#define CPUID1_EAX_FAMILY_LEN 4 +#define CPUID1_EAX_TYPE 12 +#define CPUID1_EAX_TYPE_LEN 2 +#define CPUID1_EAX_XMODEL 16 +#define CPUID1_EAX_XMODEL_LEN 4 +#define CPUID1_EAX_XFAMILY 20 +#define CPUID1_EAX_XFAMILY_LEN 8 +#define CPUID1_EBX_BRAND 0 +#define CPUID1_EBX_BRAND_LEN 8 +#define CPUID1_EBX_CLFLSHSZ 8 +#define CPUID1_EBX_CLFLSHSZ_LEN 8 +#define CPUID1_EBX_LPPP 16 +#define CPUID1_EBX_LPPP_LEN 8 +#define CPUID1_EBX_LAPIC_ID 24 +#define CPUID1_EBX_LAPIC_ID_LEN 8 +#define CPUID1_ECX_SSE3 0 +#define CPUID1_ECX_MONITOR 3 +#define CPUID1_ECX_DSCPL 4 +#define CPUID1_ECX_EIST 7 +#define CPUID1_ECX_TM2 8 +#define CPUID1_ECX_CID 10 +#define CPUID1_ECX_CX16 13 +#define CPUID1_ECX_xTPR 14 +#define CPUID1_EDX_FPU 0 +#define CPUID1_EDX_VME 1 +#define CPUID1_EDX_DE 2 +#define CPUID1_EDX_PSE 3 +#define CPUID1_EDX_TSC 4 +#define CPUID1_EDX_MSR 5 +#define CPUID1_EDX_PAE 6 +#define CPUID1_EDX_MCE 7 +#define CPUID1_EDX_CX8 8 +#define CPUID1_EDX_APIC 9 +#define CPUID1_EDX_SEP 11 +#define CPUID1_EDX_MTRR 12 +#define CPUID1_EDX_PGE 13 +#define CPUID1_EDX_MCA 14 +#define CPUID1_EDX_CMOV 15 +#define CPUID1_EDX_PAT 16 +#define CPUID1_EDX_PSE36 17 +#define CPUID1_EDX_PSN 18 +#define CPUID1_EDX_CLFSH 19 +#define CPUID1_EDX_DS 21 +#define CPUID1_EDX_ACPI 22 +#define CPUID1_EDX_MMX 23 +#define CPUID1_EDX_FXSR 24 +#define CPUID1_EDX_SSE 25 +#define CPUID1_EDX_SSE2 26 +#define CPUID1_EDX_SS 27 +#define CPUID1_EDX_HTT 28 +#define CPUID1_EDX_TM 29 +#define CPUID1_EDX_PBE 31 + +#define CPUID2_RESERVED 31 + +#define CPUIDx1_AMD_EAX_STEPPING CPUID1_EAX_STEPPING +#define CPUIDx1_AMD_EAX_STEPPING_LEN CPUID1_EAX_STEPPING_LEN +#define CPUIDx1_AMD_EAX_MODEL CPUID1_EAX_MODEL +#define CPUIDx1_AMD_EAX_MODEL_LEN CPUID1_EAX_MODEL_LEN +#define CPUIDx1_AMD_EAX_FAMILY CPUID1_EAX_FAMILY +#define CPUIDx1_AMD_EAX_FAMILY_LEN CPUID1_EAX_FAMILY_LEN +#define CPUIDx1_AMD_EAX_TYPE CPUID1_EAX_TYPE +#define CPUIDx1_AMD_EAX_TYPE_LEN CPUID1_EAX_TYPE_LEN +#define CPUIDx1_AMD_EAX_XMODEL CPUID1_EAX_XMODEL +#define CPUIDx1_AMD_EAX_XMODEL_LEN CPUID1_EAX_XMODEL_LEN +#define CPUIDx1_AMD_EAX_XFAMILY CPUID1_EAX_XFAMILY +#define CPUIDx1_AMD_EAX_XFAMILY_LEN CPUID1_EAX_XFAMILY_LEN +#define CPUIDx1_AMD_EBX_BRAND 0 +#define CPUIDx1_AMD_EBX_BRAND_LEN 16 +#define CPUIDx1_ECX_LAHF 0 +#define CPUIDx1_ECX_CMP_LEGACY 1 +#define CPUIDx1_ECX_SVM 2 +#define CPUIDx1_ECX_EXT_APIC 3 +#define CPUIDx1_ECX_LOCK_MOV_CR 4 +#define CPUIDx1_ECX_3DNOW_PREFETCH 8 +#define CPUIDx1_EDX_FPU 0 +#define CPUIDx1_EDX_VME 1 +#define CPUIDx1_EDX_DE 2 +#define CPUIDx1_EDX_PSE 3 +#define CPUIDx1_EDX_TSC 4 +#define CPUIDx1_EDX_MSR 5 +#define CPUIDx1_EDX_PAE 6 +#define CPUIDx1_EDX_MCE 7 +#define CPUIDx1_EDX_CX8 8 +#define CPUIDx1_EDX_APIC 9 +#define CPUIDx1_EDX_SCR 11 +#define CPUIDx1_EDX_MTRR 12 +#define CPUIDx1_EDX_PGE 13 +#define CPUIDx1_EDX_MCA 14 +#define CPUIDx1_EDX_CMOV 15 +#define CPUIDx1_EDX_PAT 16 +#define CPUIDx1_EDX_PSE36 17 +#define CPUIDx1_EDX_NX 20 +#define CPUIDx1_EDX_MMX 22 +#define CPUIDx1_EDX_AMDMMX 23 +#define CPUIDx1_EDX_FXSR 24 +#define CPUIDx1_EDX_FXSROPT 25 +#define CPUIDx1_EDX_RDTSCP 27 +#define CPUIDx1_EDX_LM 29 +#define CPUIDx1_EDX_AMD3DNOW 30 +#define CPUIDx1_EDX_3DNOW 31 + +#define CPUIDx5_AMD_EAX_L1ITLB_2M_NUM 0 +#define CPUIDx5_AMD_EAX_L1ITLB_2M_NUM_LEN 8 +#define CPUIDx5_AMD_EAX_L1ITLB_2M_ASSOC 8 +#define CPUIDx5_AMD_EAX_L1ITLB_2M_ASSOC_LEN 8 +#define CPUIDx5_AMD_EAX_L1DTLB_2M_NUM 16 +#define CPUIDx5_AMD_EAX_L1DTLB_2M_NUM_LEN 8 +#define CPUIDx5_AMD_EAX_L1DTLB_2M_ASSOC 24 +#define CPUIDx5_AMD_EAX_L1DTLB_2M_ASSOC_LEN 8 +#define CPUIDx5_AMD_EBX_L1ITLB_4K_NUM 0 +#define CPUIDx5_AMD_EBX_L1ITLB_4K_NUM_LEN 8 +#define CPUIDx5_AMD_EBX_L1ITLB_4K_ASSOC 8 +#define CPUIDx5_AMD_EBX_L1ITLB_4K_ASSOC_LEN 8 +#define CPUIDx5_AMD_EBX_L1DTLB_4K_NUM 16 +#define CPUIDx5_AMD_EBX_L1DTLB_4K_NUM_LEN 8 +#define CPUIDx5_AMD_EBX_L1DTLB_4K_ASSOC 24 +#define CPUIDx5_AMD_EBX_L1DTLB_4K_ASSOC_LEN 8 +#define CPUIDx5_AMD_ECX_L1IC_LINESIZE 0 +#define CPUIDx5_AMD_ECX_L1IC_LINESIZE_LEN 8 +#define CPUIDx5_AMD_ECX_L1IC_ASSOC 8 +#define CPUIDx5_AMD_ECX_L1IC_ASSOC_LEN 8 +#define CPUIDx5_AMD_ECX_L1IC_LPT 16 +#define CPUIDx5_AMD_ECX_L1IC_LPT_LEN 8 +#define CPUIDx5_AMD_ECX_L1IC_SIZE 24 +#define CPUIDx5_AMD_ECX_L1IC_SIZE_LEN 8 +#define CPUIDx5_AMD_EDX_L1DC_LINESIZE 0 +#define CPUIDx5_AMD_EDX_L1DC_LINESIZE_LEN 8 +#define CPUIDx5_AMD_EDX_L1DC_ASSOC 8 +#define CPUIDx5_AMD_EDX_L1DC_ASSOC_LEN 8 +#define CPUIDx5_AMD_EDX_L1DC_LPT 16 +#define CPUIDx5_AMD_EDX_L1DC_LPT_LEN 8 +#define CPUIDx5_AMD_EDX_L1DC_SIZE 24 +#define CPUIDx5_AMD_EDX_L1DC_SIZE_LEN 8 + +#define CPUIDx6_AMD_EAX_L2ITLB_2M_NUM 0 +#define CPUIDx6_AMD_EAX_L2ITLB_2M_NUM_LEN 12 +#define CPUIDx6_AMD_EAX_L2ITLB_2M_ASSOC 12 +#define CPUIDx6_AMD_EAX_L2ITLB_2M_ASSOC_LEN 4 +#define CPUIDx6_AMD_EAX_L2DTLB_2M_NUM 16 +#define CPUIDx6_AMD_EAX_L2DTLB_2M_NUM_LEN 12 +#define CPUIDx6_AMD_EAX_L2DTLB_2M_ASSOC 28 +#define CPUIDx6_AMD_EAX_L2DTLB_2M_ASSOC_LEN 4 +#define CPUIDx6_AMD_EBX_L2ITLB_4K_NUM 0 +#define CPUIDx6_AMD_EBX_L2ITLB_4K_NUM_LEN 12 +#define CPUIDx6_AMD_EBX_L2ITLB_4K_ASSOC 12 +#define CPUIDx6_AMD_EBX_L2ITLB_4K_ASSOC_LEN 4 +#define CPUIDx6_AMD_EBX_L2DTLB_4K_NUM 16 +#define CPUIDx6_AMD_EBX_L2DTLB_4K_NUM_LEN 12 +#define CPUIDx6_AMD_EBX_L2DTLB_4K_ASSOC 28 +#define CPUIDx6_AMD_EBX_L2DTLB_4K_ASSOC_LEN 4 +#define CPUIDx6_AMD_ECX_L2UC_LINESIZE 0 +#define CPUIDx6_AMD_ECX_L2UC_LINESIZE_LEN 8 +#define CPUIDx6_AMD_ECX_L2UC_ASSOC 8 +#define CPUIDx6_AMD_ECX_L2UC_ASSOC_LEN 4 +#define CPUIDx6_AMD_ECX_L2UC_LPT 12 +#define CPUIDx6_AMD_ECX_L2UC_LPT_LEN 4 +#define CPUIDx6_AMD_ECX_L2UC_SIZE 16 +#define CPUIDx6_AMD_ECX_L2UC_SIZE_LEN 16 + +#define CPUIDx7_AMD_EDX_TS 0 +#define CPUIDx7_AMD_EDX_FID 1 +#define CPUIDx7_AMD_EDX_VID 2 +#define CPUIDx7_AMD_EDX_TTP 3 +#define CPUIDx7_AMD_EDX_TM 4 +#define CPUIDx7_AMD_EDX_STC 5 +#define CPUIDx7_AMD_EDX_100MHZ 6 + +#define CPUIDx8_EAX_PA_BITS 0 +#define CPUIDx8_EAX_PA_BITS_LEN 8 +#define CPUIDx8_EAX_VA_BITS 8 +#define CPUIDx8_EAX_VA_BITS_LEN 16 +#define CPUIDx8_ECX_MAX_CORE 0 +#define CPUIDx8_ECX_MAX_CORE_LEN 8 + +#define CPUIDxA_EAX_SVMREV 0 +#define CPUIDxA_EAX_SVMREV_LEN 8 +#define CPUIDxA_EAX_0 8 +#define CPUIDxA_EDX_NP 0 + +#ifndef __ASSEMBLY__ + +typedef union { + uint64_t q; + uint32_t d[2]; + uint16_t w[4]; + uint8_t b[8]; +} mmxreg_t; + +typedef union { + double dbl[2]; + float flt[4]; + uint64_t q[2]; + uint32_t d[4]; + uint16_t w[8]; + uint8_t b[16]; +} xmmreg_t __attribute__((__aligned__(16))); + +/* + * FXSAVE / FXRSTOR layout + */ +typedef struct { + uint16_t fcw; + uint16_t fsw; + uint8_t ftw; + uint8_t _rsrvd1_; + uint16_t fop; + union { + uint64_t rip; + struct { + uint32_t fip; + uint16_t fcs; + uint16_t _rsrvd2_; + }; + }; + union { + uint64_t rdp; + struct { + uint32_t fdp; + uint16_t fds; + uint16_t _rsrvd3_; + }; + }; + uint32_t mxcsr; + uint32_t mxcsr_mask; + union { + struct { + uint64_t mant; + uint32_t exp:15; + int32_t sign:1; + uint32_t _pad_; + } fp; + mmxreg_t mmx; + } reg[8]; + xmmreg_t xmm[16]; + uint8_t _rsrvd5_[6*16]; +} fxsave_t; + +/* + * Descriptor Attributes + */ +typedef struct { + uint8_t type:5; + uint8_t dpl:2; + uint8_t p:1; +} DescriptorAttributes_t; + +/* + * Descriptor Table Entry + */ +typedef union { + struct { + uint16_t limitLow; + uint16_t baseLow; + uint8_t baseMidLo; + union { + uint8_t attrLow; + DescriptorAttributes_t attr; + }; + union { + uint8_t attrHigh; + struct { + uint8_t limitHigh:4; + uint8_t avl:1; + uint8_t l:1; + uint8_t d:1; + uint8_t g:1; + }; + }; + uint8_t baseMidHi; + uint32_t baseHigh; + uint32_t mbz; + } segment; + struct { + uint16_t offsetLow; + uint16_t selector; + union { + uint16_t control; + struct { + union { + struct { + uint8_t ist:3; + uint8_t :5; + }; + struct { + uint8_t numParm32:5; + uint8_t :3; + }; + }; + DescriptorAttributes_t attr; + }; + }; + uint16_t offsetMid; + uint32_t offsetHigh; + uint32_t mbz; + } gate; +} DescriptorTableEntry_t; + +# define IS_SEGMENT(d) (((d).segment.attrLow & 0x14) != 0x04) +# define IS_SEGMENT_EXEC(d) (!((d).segment.attrLow & (1U << DESCRIPTOR_S)) \ + && ((d).segment.l || ((d).segment.attrLow & (1U << DESCR32_CODE)))) +# define IS_SEGMENT_READ(d) (!((d).segment.attrLow & (1U << DESCRIPTOR_S)) \ + && ((d).segment.l \ + || !((d).segment.attrLow & (1U << DESCR32_CODE)) \ + || ((d).segment.attrLow & (1U << DESCR32_R)))) +# define IS_SEGMENT_WRITE(d) (!((d).segment.attrLow & (1U << DESCRIPTOR_S)) \ + && ((d).segment.l \ + || (!((d).segment.attrLow & (1U << DESCR32_CODE)) \ + && ((d).segment.attrLow & (1U << DESCR32_W))))) +# define SEGMENT_BASE(d) (((d).segment.attrLow & (1U << DESCRIPTOR_S)) ? 0 : \ + (d).segment.baseLow | ((uint64_t)(d).segment.baseMidLo << 16) \ + | ((uint64_t)(d).segment.baseMidHi << 24) | ((uint64_t)(d).segment.baseHigh << 32)) +# define SEG32_BASE(d) ((d).segment.baseLow | ((uint32_t)(d).segment.baseMidLo << 16) | ((uint32_t)(d).segment.baseMidHi << 24)) +# define SEG32_LIMIT(d) ((d).segment.g \ + ? ((uint32_t)(d).segment.limitLow << 12) | ((uint32_t)(d).segment.limitHigh << 28) | 0xfff \ + : (d).segment.limitLow | ((uint32_t)(d).segment.limitHigh << 16)) + +# define IS_GATE(d) (((d).gate.control & 0x1400) == 0x0400) +# define GATE_SELECTOR(d) ((d).gate.selector) +# define GATE_OFFSET(d) ((uint64_t)(d).gate.offsetLow | ((uint64_t)(d).gate.offsetMid << 16) | ((uint64_t)(d).gate.offsetHigh << 32)) +# define GATE32_OFFSET(d) ((uint32_t)(d).gate.offsetLow | ((uint32_t)(d).gate.offsetMid << 16)) + +# pragma pack(push, 2) + +/* + * GDTR/IDTR memory format + */ +typedef struct { + uint16_t limit; + uint64_t base; +} PseudoDescriptor_t; + +# pragma pack(pop) + +#endif /* __ASSEMBLY__ */ + +/* + * FPU Control Word + */ +#define FCW_MBZ 0xe0c0 +#define FCW_IM 0 +#define FCW_DM 1 +#define FCW_ZM 2 +#define FCW_OM 3 +#define FCW_UM 4 +#define FCW_PM 5 +#define FCW_PC 8 +#define FCW_PC_LEN 2 +# define FCW_PC_SINGLE 0 +# define FCW_PC_DOUBLE 2 +# define FCW_PC_EXTENDED 3 +#define FCW_RC 10 +#define FCW_RC_LEN 2 +/* The rounding control values are used for both FCW and MXCSR. */ +# define RC_NEAREST 0 +# define RC_DOWN 1 +# define RC_UP 2 +# define RC_CHOP 3 +# define RC_TRUNCATE RC_CHOP +#define FCW_X 12 + +/* + * FPU Status Word + */ +#define FSW_IE 0 +#define FSW_DE 1 +#define FSW_ZE 2 +#define FSW_OE 3 +#define FSW_UE 4 +#define FSW_PE 5 +#define FSW_SF 6 +#define FSW_ES 7 +#define FSW_C0 8 +#define FSW_C1 9 +#define FSW_C2 10 +#define FSW_TOP 11 +#define FSW_TOP_LEN 3 +#define FSW_C3 14 +#define FSW_B 15 + +/* + * FPU Tag Word + */ +#define FTW_TAG_LEN 2 +# define FTW_VALID 0U +# define FTW_ZERO 1U +# define FTW_SPECIAL 2U +# define FTW_EMPTY 3U + +/* + * MMX Control and Status Register + */ +#define MXCSR_IE 0 +#define MXCSR_DE 1 +#define MXCSR_ZE 2 +#define MXCSR_OE 3 +#define MXCSR_UE 4 +#define MXCSR_PE 5 +#define MXCSR_DAZ 6 +#define MXCSR_IM 7 +#define MXCSR_DM 8 +#define MXCSR_ZM 9 +#define MXCSR_OM 10 +#define MXCSR_UM 11 +#define MXCSR_PM 12 +#define MXCSR_RC 13 +#define MXCSR_RC_LEN 2 +#define MXCSR_FZ 15 + +#ifndef __ASSEMBLY__ +# pragma pack(push, 4) + +/* + * 64-bit Task State Segment layout + */ +typedef struct { + uint32_t _mbz1_; + uint64_t rsp0; + uint64_t rsp1; + uint64_t rsp2; + uint64_t _mbz2_; + uint64_t ist[7]; + uint64_t _mbz3_; + uint16_t _mbz4_; + uint16_t iobase; +} tss64_t; + +# pragma pack(pop) +#endif + +/* + * MSR indexes + */ +#define X86_TSC 0x10 +#define X86_MTRRCAP 0xfe +#define X86_SYSENTER_CS 0x174 +#define X86_SYSENTER_ESP 0x175 +#define X86_SYSENTER_EIP 0x176 +#define X86_MCG_CAP 0x179 +#define X86_MCG_STATUS 0x17a +#define X86_MCG_CTL 0x17b +#define X86_DEBUGCTL 0x1d9 +#define X86_LBF 0x1db +#define X86_LBT 0x1dc +#define X86_LIF 0x1dd +#define X86_LIT 0x1de +#define X86_MTRR_PHYSBASE0 0x200 +#define X86_MTRR_PHYSMASK0 0x201 +#define X86_MTRR_FIX64K_00000 0x250 +#define X86_MTRR_FIX16K_80000 0x258 +#define X86_MTRR_FIX16K_A0000 0x259 +#define X86_MTRR_FIX4K_C0000 0x268 +#define X86_MTRR_FIX4K_C8000 0x269 +#define X86_MTRR_FIX4K_D0000 0x26a +#define X86_MTRR_FIX4K_D8000 0x26b +#define X86_MTRR_FIX4K_E0000 0x26c +#define X86_MTRR_FIX4K_E8000 0x26d +#define X86_MTRR_FIX4K_F0000 0x26e +#define X86_MTRR_FIX4K_F8000 0x26f +#define X86_CR_PAT 0x277 +#define X86_MTRR_DEFTYPE 0x2ff +#define X86_MCi_START 0x400 +# define X86_MCi_STEP 4 +# define X86_MCi_CTL_OFFSET 0 +# define X86_MCi_STATUS_OFFSET 1 +# define X86_MCi_ADDR_OFFSET 2 +# define X86_MCi_MISC_OFFSET 3 +#define X86_EFER 0xC0000080 +#define X86_STAR 0xC0000081 +#define X86_LSTAR 0xC0000082 +#define X86_CSTAR 0xC0000083 +#define X86_SF_MASK 0xC0000084 +#define X86_FS_BASE 0xC0000100 +#define X86_GS_BASE 0xC0000101 +#define X86_KERNEL_GS_BASE 0xC0000102 +#define X86_SYSCFG 0xC0010010 +#define X86_IORRBASE0 0xC0010016 +#define X86_IORRMASK0 0xC0010017 +#define X86_IORRBASE1 0xC0010018 +#define X86_IORRMASK1 0xC0010019 +#define X86_TOP_MEM 0xC001001a +#define X86_TOP_MEM2 0xC001001d + +/* + * X86_MTRRCAP + */ +#define MTRRCAP_VCNT 0 +#define MTRRCAP_VCNT_LEN 8 +#define MTRRCAP_FIX 8 +#define MTRRCAP_WC 10 + +/* + * X86_DEBUGCTL + */ +#define DEBUGCTL_LBR 0 +#define DEBUGCTL_BTF 1 +#define DEBUGCTL_PB0 2 +#define DEBUGCTL_PB1 3 +#define DEBUGCTL_PB2 4 +#define DEBUGCTL_PB3 5 + +/* + * X86_MTRR_DEFTYPE + */ +#define MTRR_DEFTYPE_TYPE 0 +#define MTRR_DEFTYPE_TYPE_LEN 8 +#define MTRR_DEFTYPE_FE 10 +#define MTRR_DEFTYPE_E 11 + +/* + * X86_MTRR_PHYSBASEx + */ +#define MTRR_PHYSBASE_TYPE 0 +#define MTRR_PHYSBASE_TYPE_LEN 8 +#define MTRR_PHYSBASE_BASE 12 +#define MTRR_PHYSBASE_BASE_LEN 40 + +/* + * X86_MTRR_PHYSMASKx + */ +#define MTRR_PHYSMASK_V 11 +#define MTRR_PHYSMASK_MASK 12 +#define MTRR_PHYSMASK_MASK_LEN 40 + +/* + * Memory Attributes (MTRRs & PAT) + */ +#define X86_MA_UC 0x00 +#define X86_MA_WC 0x01 +#define X86_MA_WT 0x04 +#define X86_MA_WP 0x05 +#define X86_MA_WB 0x06 +#define X86_MA_UC_MINUS 0x07 /* PAT only */ +#define X86_MA_WRMEM 0x08 /* mask, fixed-range MTRRs (and IORRs) only */ +#define X86_MA_RDMEM 0x10 /* mask, fixed-range MTRRs (and IORRs) only */ + +/* + * X86_MCG_CAP + */ +#define X86_MCG_CAP_COUNT 0 +#define X86_MCG_CAP_COUNT_LEN 8 +#define X86_MCG_CTL_P 8 + +/* + * X86_MCG_STATUS + */ +#define X86_MCG_STATUS_RIPV 0 +#define X86_MCG_STATUS_EIPV 1 +#define X86_MCG_STATUS_MCIP 2 + +/* + * X86_MCi + */ +#define X86_MCi_STATUS_MCA_EC 0 +#define X86_MCi_STATUS_MCA_EC_LEN 16 +#define X86_MCi_STATUS_MOD_EC 16 +#define X86_MCi_STATUS_MOD_EC_LEN 16 +#define X86_MCi_STATUS_PCC 57 +#define X86_MCi_STATUS_ADDRV 58 +#define X86_MCi_STATUS_MISCV 59 +#define X86_MCi_STATUS_EN 60 +#define X86_MCi_STATUS_UC 61 +#define X86_MCi_STATUS_OVER 62 +#define X86_MCi_STATUS_VAL 63 + +/* + * X86_EFER + */ +#define X86_EFER_SCE 0 +#define X86_EFER_LME 8 +#define X86_EFER_LMA 10 +#define X86_EFER_NXE 11 + +/* + * X86_SYSCFG + */ +#define X86_SYSCFG_MFDE 18 +#define X86_SYSCFG_MFDM 19 +#define X86_SYSCFG_MVDM 20 +#define X86_SYSCFG_TOM2 21 + +/* + * X86_IORR_PHYSBASEx + */ +#define MTRR_PHYSBASE_WRMEM 3 +#define MTRR_PHYSBASE_RDMEM 4 +#define MTRR_PHYSBASE_BASE 12 +#define MTRR_PHYSBASE_LEN 40 + +/* + * X86_IORR_PHYSMASKx + */ +#define MTRR_PHYSMASK_V 11 +#define MTRR_PHYSMASK_BASE 12 +#define MTRR_PHYSMASK_LEN 40 + +/* + * X86_TOP_MEMx + */ +#define X86_TOP_MEM_PHYS 23 +#define X86_TOP_MEM_LEN 29 + +#endif /* _ASM_X86_64_X86_64_H */