The core i386 NLKD additions. Signed-Off-By: Jan Beulich Index: 2.6.14-nlkd/arch/i386/Kconfig.debug =================================================================== --- 2.6.14-nlkd.orig/arch/i386/Kconfig.debug 2005-11-09 11:12:40.000000000 +0100 +++ 2.6.14-nlkd/arch/i386/Kconfig.debug 2005-11-04 16:19:32.000000000 +0100 @@ -1,6 +1,7 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +source "debug/Kconfig" config EARLY_PRINTK bool "Early printk" if EMBEDDED && DEBUG_KERNEL Index: 2.6.14-nlkd/arch/i386/kernel/asm-offsets.c =================================================================== --- 2.6.14-nlkd.orig/arch/i386/kernel/asm-offsets.c 2005-11-09 11:12:40.000000000 +0100 +++ 2.6.14-nlkd/arch/i386/kernel/asm-offsets.c 2005-11-04 16:19:32.000000000 +0100 @@ -4,6 +4,7 @@ * to extract and format the required data. */ +#include #include #include #include @@ -13,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)) @@ -70,4 +78,88 @@ void foo(void) DEFINE(PAGE_SIZE_asm, PAGE_SIZE); DEFINE(THREAD_SIZE_asm, THREAD_SIZE); DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL)); + +#ifdef CONFIG_NLKD + BLANK(); +# define TSS_DEF(f) DEFINE(TSS_##f, offsetof (struct tss_struct, f)) + TSS_DEF(back_link); + TSS_DEF(esp0); + TSS_DEF(ss0); + TSS_DEF(esp1); + TSS_DEF(ss1); + TSS_DEF(esp2); + TSS_DEF(ss2); + TSS_DEF(__cr3); + TSS_DEF(eip); + TSS_DEF(eflags); + TSS_DEF(eax); + TSS_DEF(ecx); + TSS_DEF(edx); + TSS_DEF(ebx); + TSS_DEF(esp); + TSS_DEF(ebp); + TSS_DEF(esi); + TSS_DEF(edi); + TSS_DEF(es); + TSS_DEF(cs); + TSS_DEF(ss); + TSS_DEF(ds); + TSS_DEF(fs); + TSS_DEF(gs); + TSS_DEF(ldt); +# undef TSS_DEF + + BLANK(); +# define FRAME_TYPE(t) DEFINE(IA32_##t, IA32_##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(COPROCESSOR_SEGMENT_OVERRUN); + 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); +# undef FRAME_TYPE + BLANK(); +# define FRAME_DEF(f) DEFINE(FRAME_##f, offsetof (struct ftaInterruptionCtx_s, f)) + FRAME_DEF(type); + FRAME_DEF(sub_type); + FRAME_DEF(state); + FRAME_DEF(esp); + FRAME_DEF(ss); + FRAME_DEF(fs); + FRAME_DEF(gs); + FRAME_DEF(ldtr); + FRAME_DEF(tr); + FRAME_DEF(cr0); + FRAME_DEF(cr2); + FRAME_DEF(cr3); + FRAME_DEF(cr4); + 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_LO, (uint32_t)CDE_VALID_SPINLOCK_SIGNATURE); + DEFINE(CDE_VALID_SPINLOCK_SIGNATURE_HI, CDE_VALID_SPINLOCK_SIGNATURE >> 32); + DEFINE(CDE_SPINLOCK_NOT_OWNED, CDE_SPINLOCK_NOT_OWNED); +#endif } Index: 2.6.14-nlkd/debug/nlkd/asm-ia32.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/debug/nlkd/asm-ia32.h 2005-11-07 12:11:32.000000000 +0100 @@ -0,0 +1,121 @@ +/***************************************************************************** + * + * File Name: asm-ia32.h + * Created by: Jan Beulich + * %version: 7 % + * %derived_by: jbeulich % + * %date_modified: Thu Nov 03 04:13:50 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_IA32_H) +#define ASM_IA32_H + +#include +#include + +#ifdef CONFIG_UNWIND_INFO +.equiv eh.eax, 0 +.equiv eh.ecx, 1 +.equiv eh.edx, 2 +.equiv eh.ebx, 3 +.equiv eh.esp, 4 +.equiv eh.ebp, 5 +.equiv eh.esi, 6 +.equiv eh.edi, 7 +.equiv eh.es, 8 +.equiv eh.cs, 9 +.equiv eh.ss, 10 +.equiv eh.ds, 11 +.equiv eh.fs, 12 +.equiv eh.gs, 13 + +# define SP esp +# define BP ebp +# define FLAGS eflags +.equiv .eh.stkword, dword +.equiv .eh.preserved, (1 << eh.ebx) | (1 << eh.ebp) | (1 << eh.esi) | (1 << eh.edi) \ + | (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 + mov sreg, aux + jmp skip + .previous + .section __ex_table, "a" + .align dword + .long set, adj + .previous +.endm + +.macro fnrstor loc:req + frstor loc +.endm + +.macro fxsr what:req, loc:req + LOCAL where, fix, done +where: + fx&what loc +done: + .section .fixup, "ax" +fix: + fn&what loc + jmp done + .previous + .section __ex_table, "a" + .align dword + .long where, fix + .previous +.endm + +.macro fxinit mxcsr:req + LOCAL where, fix +where: + ldmxcsr mxcsr +fix: + fninit + .section __ex_table, "a" + .align dword + .long where, fix + .previous +.endm + +#endif /* ASM_IA32_H */ Index: 2.6.14-nlkd/debug/nlkd/nlkdIA32.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/debug/nlkd/nlkdIA32.S 2005-10-07 17:19:06.000000000 +0200 @@ -0,0 +1,86 @@ +/***************************************************************************** + * + * File Name: nlkdIA32.S + * Created by: jbeulich + * %version: 2 % + * %derived_by: jbeulich % + * %date_modified: Fri Oct 07 09:18:56 2005 % + * + ****************************************************************************/ +/***************************************************************************** + * * + * Copyright (c) 2001-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-ia32.h" +#include + +//todo .file "nlkd" +.text + +// void nlkdDebugEvent(nint_t eventCode, ...); +.pubproc nlkdDebugEvent + cmp dword ptr [nlkdAgentCount], 0 + movsx eax, byte ptr [esp+dword] + jg _nlkdEnterDebuggerInstruction_ + test eax, eax + jg 0f + .hidentry _nlkdEnterDebuggerInstruction_ + int 3 +0: + jc 1f + ret +1: +#ifdef CONFIG_UNWIND_INFO +// Once we get here, the dual frame layout ceases to exist, +// and hence we can now express the (alternate) frame state. + .cfi_def_cfa esp, 2*dword + .cfi_offset eip, -2*dword +#endif + ret dword // discard eventCode for special case entries +.endp nlkdDebugEvent +// void nlkdEnterDebugger(void); +.pubproc nlkdEnterDebugger + mov eax, DEBUG_EVENT_ENTER_DEBUGGER +2: + push dword ptr [esp] // make stack frame consistent with nlkdDebugEvent + // (note that there's no point in using EHpush here + // because the .eh_frame unwind information can't + // express the dual (conditional upon EFLAGS.CF) + // frame layout at _nlkdEnterDebuggerInstruction_. + stc + mov [esp+dword], eax // store eventCode + jmp _nlkdEnterDebuggerInstruction_ +.endp nlkdEnterDebugger +// void nlkdPanic(const char*string, ...); +.pubproc nlkdPanic + mov eax, DEBUG_EVENT_PANIC + jmp 2b +.endp nlkdPanic +// void nlkdAssert(const char*string, const char*file, const char*func, nuint_t line); +.pubproc nlkdAssert + mov eax, DEBUG_EVENT_ASSERT + jmp 2b +.endp nlkdAssert Index: 2.6.14-nlkd/debug/nlkd/nlkdIA32.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/debug/nlkd/nlkdIA32.h 2005-10-10 14:52:40.000000000 +0200 @@ -0,0 +1,55 @@ +/***************************************************************************** + * + * File Name: nlkdIA32.h + * Created by: Jan Beulich + * %version: 1 % + * %derived_by: jbeulich % + * %date_modified: Mon Oct 10 06:52:33 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__("movl %0,%%db0" : : "r" (value)); break; + case 1: __asm__("movl %0,%%db1" : : "r" (value)); break; + case 2: __asm__("movl %0,%%db2" : : "r" (value)); break; + case 3: __asm__("movl %0,%%db3" : : "r" (value)); break; + case 6: __asm__("movl %0,%%db6" : : "r" (value)); break; + case 7: __asm__("movl %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.debugreg[7], 7); +} +#endif Index: 2.6.14-nlkd/include/asm-i386/fta-frame.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/include/asm-i386/fta-frame.h 2005-11-03 11:49:06.000000000 +0100 @@ -0,0 +1,177 @@ +/***************************************************************************** + * + * File Name: fta-frame.h + * Created by: Clyde Griffin + * Date created: 1/1/1999 + * + * %version: 7 % + * %derived_by: jbeulich % + * %date_modified: Thu Nov 03 03:48:54 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_I386_FTA_FRAME_H +#define _ASM_I386_FTA_FRAME_H + +/* values for ftaInterruptionCtx_s.state */ +#ifdef CONFIG_NLKD_FTA +# define FRAME_COMPLETE_BIT 0 +# define FRAME_COMPLETE (1 << FRAME_COMPLETE_BIT) +#endif + +# ifndef __ASSEMBLY__ +# include +# include + +struct ftaInterruptionCtx_s { + uint16_t type; /* Trap type */ + int8_t sub_type; /* Extended type */ + uint8_t state; /* Framework/Debugger only */ + uint32_t ec; /* Error code */ + uint32_t cr0; + uint32_t cr4; + uint32_t cr2; + uint32_t cr3; + uint64_t debugCtl; + uint32_t dr7; + union { + // fp/mmx/sse state (which requires 16-byte alignment and thus needs to be referenced indirectly) + fxsave_t *fp_mmx_xmm; + // fp/mmx state + fsave_t *fp_mmx; + }; + uint16_t ldtr; + uint16_t tr; + uint16_t fs; + uint16_t gs; + union { + uint32_t esp; + uint16_t sp; + }; + uint16_t ss, _ss_pad; + union { + struct pt_regs pt_regs; + struct { + union { + uint32_t ebx; + uint16_t bx; + struct { + uint8_t bl; + uint8_t bh; + }; + }; + union { + uint32_t ecx; + uint16_t cx; + struct { + uint8_t cl; + uint8_t ch; + }; + }; + union { + uint32_t edx; + uint16_t dx; + struct { + uint8_t dl; + uint8_t dh; + }; + }; + union { + uint32_t esi; + uint16_t si; + }; + union { + uint32_t edi; + uint16_t di; + }; + union { + uint32_t ebp; + uint16_t bp; + }; + union { + uint32_t eax; + uint16_t ax; + struct { + uint8_t al; + uint8_t ah; + }; + }; + union { + struct { + uint16_t ds, _ds_pad; + }; +# ifdef CONFIG_NLKD_FTA + uint32_t _type_raw; +# endif + }; + union { + struct { + uint16_t es, _es_pad; + }; +# ifdef CONFIG_NLKD_FTA + uint32_t _ebx_raw; +# endif + }; + union { + uint32_t orig_eax; +# ifdef CONFIG_NLKD_FTA + uint32_t _ec_raw; +# endif + }; + union { + uint32_t eip; + uint16_t ip; + }; + uint16_t cs, _cs_pad; + union { + uint32_t eflags; + uint16_t flags; + }; + /* + * From here on field presence dependent on the value in eflags + */ + union { + uint32_t r3_esp; + uint16_t r3_sp; + }; + uint16_t r3_ss, _r3_ss_pad; + }; +# ifdef CONFIG_NLKD_FTA + }; +# define FRAME_PTREGS(frame, field) (frame)->field +# else + } *pt_regs; +# define FRAME_PTREGS(frame, field) (frame)->pt_regs->field +# endif + /* This is only used in cloned frames. */ + uint32_t _fp_mmx_xmm_area_[(sizeof(fxsave_t) + 0xf) / sizeof(uint32_t)]; +}; +# endif /* __ASSEMBLY__ */ + +#endif /* _ASM_I386_FTA_FRAME_H */ Index: 2.6.14-nlkd/include/asm-i386/fta-type.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/include/asm-i386/fta-type.h 2005-06-27 13:56:50.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:21:26 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_I386_FTA_TYPE_H +#define _ASM_I386_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 +{ + IA32_DIVIDE_ERROR, + IA32_DEBUG, + IA32_NMI, + IA32_BREAKPOINT, + IA32_OVERFLOW, + IA32_BOUNDS_CHECK, + IA32_ILLEGAL_OPCODE, + IA32_DEVICE_NOT_AVAILABLE, + IA32_DOUBLE_FAULT, + IA32_COPROCESSOR_SEGMENT_OVERRUN, + IA32_INVALID_TSS, + IA32_SEGMENT_NOT_PRESENT, + IA32_STACK_FAULT, + IA32_GENERAL_PROTECTION_FAULT, + IA32_PAGE_FAULT, + IA32_RSVD_0F, + IA32_FP_ERROR, + IA32_ALIGNMENT_CHECK, + IA32_MACHINE_CHECK, + IA32_SIMD_FP_ERROR, + IA32_RSVD_14, + IA32_RSVD_15, + IA32_RSVD_16, + IA32_RSVD_17, + IA32_RSVD_18, + IA32_RSVD_19, + IA32_RSVD_1A, + IA32_RSVD_1B, + IA32_RSVD_1C, + IA32_RSVD_1D, + IA32_RSVD_1E, + IA32_RSVD_1F +}; + +#endif /* _ASM_I386_FTA_TYPE_H */ Index: 2.6.14-nlkd/include/asm-i386/ia_32.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2.6.14-nlkd/include/asm-i386/ia_32.h 2005-06-30 15:54:35.000000000 +0200 @@ -0,0 +1,907 @@ +/***************************************************************************** + * + * File Name: ia_32.h + * Created by: Clyde Griffin, Jan Beulich + * Date created: 21Feb2001 + * + * %version: 9 % + * %derived_by: jbeulich % + * %date_modified: Thu Jun 30 07:54:20 2005 % + * + *****************************************************************************/ +/***************************************************************************** + * * + * Copyright (c) 2001-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_IA_32_H +#define _ASM_IA_32_H + +#ifdef __ASSEMBLY__ +# define UINT64_C(v) (v) +#else +# include +#endif + +/* + * EFLAGS + */ +#define EFLAGS_MBZ 0xffc08028 +#define EFLAGS_MBS 0x00000002 +#define EFLAGS_CF 0 +#define EFLAGS_PF 2 +#define EFLAGS_AF 4 +#define EFLAGS_ZF 6 +#define EFLAGS_SF 7 +#define EFLAGS_TF 8 +#define EFLAGS_IF 9 +#define EFLAGS_DF 10 +#define EFLAGS_OF 11 +#define EFLAGS_IOPL 12 +#define EFLAGS_IOPL_LEN 2 +#define EFLAGS_NT 14 +#define EFLAGS_RF 16 +#define EFLAGS_VM 17 +#define EFLAGS_AC 18 +#define EFLAGS_VIF 19 +#define EFLAGS_VIP 20 +#define EFLAGS_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_AVAILTSS16 0x01 +# define DESCRIPTOR_LDT 0x02 +# define DESCRIPTOR_BUSYTSS16 0x03 +# define DESCRIPTOR_CALLGATE16 0x04 +# define DESCRIPTOR_TASKGATE 0x05 +# define DESCRIPTOR_INTGATE16 0x06 +# define DESCRIPTOR_TRAPGATE16 0x07 +# define DESCRIPTOR_AVAILTSS32 0x09 +# define DESCRIPTOR_BUSYTSS32 0x0b +# define DESCRIPTOR_CALLGATE32 0x0c +# define DESCRIPTOR_INTGATE32 0x0e +# define DESCRIPTOR_TRAPGATE32 0x0f +# define DESCRIPTOR_DATA_RO 0x10 +# define DESCRIPTOR_DATA_RO_ACC 0x11 +# define DESCRIPTOR_DATA_RW 0x12 +# define DESCRIPTOR_DATA_RW_ACC 0x13 +# define DESCRIPTOR_DOWN_RO 0x14 +# define DESCRIPTOR_DOWN_RO_ACC 0x15 +# define DESCRIPTOR_DOWN_RW 0x16 +# define DESCRIPTOR_DOWN_RW_ACC 0x17 +# define DESCRIPTOR_CODE_XO 0x18 +# define DESCRIPTOR_CODE_XO_ACC 0x19 +# define DESCRIPTOR_CODE_XR 0x1a +# define DESCRIPTOR_CODE_XR_ACC 0x1b +# define DESCRIPTOR_CONF_XO 0x1c +# define DESCRIPTOR_CONF_XO_ACC 0x1d +# define DESCRIPTOR_CONF_XR 0x1e +# define DESCRIPTOR_CONF_XR_ACC 0x1f +#define DESCRIPTOR_A 0 +#define DESCRIPTOR_W 1 +#define DESCRIPTOR_R 1 +#define DESCRIPTOR_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_D 14 +#define DESCRIPTOR_B 14 +#define DESCRIPTOR_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 0x1ffaffc0 +#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 0x00000fe7 +#define CR3_PWT 3 +#define CR3_PCD 4 +#define CR3_PHYS 12 +#define CR3_PHYS_LEN 20 + +#define PDBR_MBZ CR3_MBZ +#define PDBR_PWT CR3_PWT +#define PDBR_PCD CR3_PCD +#define PDBR_PHYS CR3_PHYS +#define PDBR_PHYS_LEN CR3_PHYS_LEN + +#define PDPTR_MBZ 0x00000007 +#define PDPTR_PWT CR3_PWT +#define PDPTR_PCD CR3_PCD +#define PDPTR_PHYS 5 +#define PDPTR_PHYS_LEN 27 + +/* + * Control Register 4 + */ +#define CR4_MBZ 0xfffff800 +#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 + +/* + * Page Directory Pointer Table Entry + */ +#define PDPTE_MBZ 0x000001e6 +#define PDPTE_MBS 0x00000001 +#define PDPTE_PWT 3 +#define PDPTE_PCD 4 +#define PDPTE_AVL 9 +#define PDPTE_AVL_LEN 3 +#define PDPTE_PHYS 12 +#define PDPTE_PHYS_LEN 40 + +/* + * Page Directory Entry + */ +#define PDE_MBZ 0x000001c0 +#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_NX 63 + +/* + * Page Table Entry + */ +#define PTE4K_MBZ 0x00000080 +#define PTE2M_MBZ 0x001fe000 +#define PTE2M_MBS (1U << PDE_LARGE_PTE) +#define PTE4M_MBZ 0x00000000 +#define PTE4M_MBS (1U << 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 PTE4M_PAT 12 +#define PTE4K_PHYS 12 +#define PTE4K_PHYS_LEN 40 +#define PTE2M_PHYS 21 +#define PTE2M_PHYS_LEN 31 +#define PTE4M_PHYS1 13 +#define PTE4M_PHYS1_LEN 9 +#define PTE4M_PHYS 22 +#define PTE4M_PHYS_LEN 10 +#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_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 4 +#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_IA64 30 +#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; + +/* + * FXSAVE / FXRSTOR layout + */ +typedef struct { + uint16_t fcw; + uint16_t fsw; + uint8_t ftw; + uint8_t _rsrvd1_; + uint16_t fop; + uint32_t fip; + uint16_t fcs; + uint16_t _rsrvd2_; + 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[8]; + uint8_t _rsrvd5_[14*16]; +} fxsave_t __attribute__((__aligned__(16))); + +#pragma pack(push, 2) + +/* + * FSAVE / FRSTOR layout + */ +typedef struct { + uint16_t fcw; + uint16_t _rsrvd1_; + uint16_t fsw; + uint16_t _rsrvd2_; + uint16_t ftw; + uint16_t _rsrvd3_; + uint32_t fip; + uint16_t fcs; + uint16_t fop:11; + uint16_t :5; + uint32_t fdp; + uint16_t fds; + uint16_t _rsrvd4_; + union { + struct { + uint64_t mant; + uint16_t exp:15; + int16_t sign:1; + } fp; + mmxreg_t mmx; + } reg[8]; +} fsave_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 baseMid; + union { + uint8_t attrLow; + DescriptorAttributes_t attr; + }; + union { + uint8_t attrHigh; + struct { + uint8_t limitHigh:4; + uint8_t avl:1; + uint8_t :1; + uint8_t d:1; + uint8_t g:1; + }; + }; + uint8_t baseHigh; + } segment; + struct { + uint16_t offsetLow; + uint16_t selector; + union { + uint16_t control; + struct { + uint8_t numParms:5; + uint8_t :3; + DescriptorAttributes_t attr; + }; + }; + uint16_t offsetHigh; + } gate; +} DescriptorTableEntry_t; + +#define IS_SEGMENT(d) (((d).segment.attrLow & 0x14) != 0x04) +#define IS_SEGMENT_EXEC(d) (((d).segment.attrLow & ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE))) \ + == ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE))) +#define IS_SEGMENT_READ(d) (((d).segment.attrLow & ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE))) \ + == (1U << DESCRIPTOR_S) \ + || ((d).segment.attrLow & ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE) | (1U << DESCRIPTOR_R))) \ + == ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE) | (1U << DESCRIPTOR_R))) +#define IS_SEGMENT_WRITE(d) (((d).segment.attrLow & ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE) | (1U << DESCRIPTOR_W))) \ + == ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_W))) +#define SEGMENT_BASE(d) ((d).segment.baseLow | ((uint32_t)(d).segment.baseMid << 16) | ((uint32_t)(d).segment.baseHigh << 24)) +#define SEGMENT_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) ((d).gate.offsetLow | ((uint32_t)(d).gate.offsetHigh << 16)) + +/* + * GDTR/IDTR memory format + */ +typedef struct { + uint16_t limit; + uint32_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 0U +# define FCW_PC_DOUBLE 2U +# define FCW_PC_EXTENDED 3U +#define FCW_RC 10 +#define FCW_RC_LEN 2 +/* The rounding control values are used for both FCW and MXCSR. */ +# define RC_NEAREST 0U +# define RC_DOWN 1U +# define RC_UP 2U +# define RC_CHOP 3U +# 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__ + +/* + * 32-bit Task State Segment layout + */ +typedef struct { + uint16_t backlink, _backlink_pad; + uint32_t esp0; + uint16_t ss0, _ss0_pad; + uint32_t esp1; + uint16_t ss1, _ss1_pad; + uint32_t esp2; + uint16_t ss2, _ss2_pad; + union { + uint32_t cr3; + uint32_t pdbr; + uint32_t pdptr; + }; + uint32_t eip; + uint32_t eflags; + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint16_t es, _es_pad; + uint16_t cs, _cs_pad; + uint16_t ss, _ss_pad; + uint16_t ds, _ds_pad; + uint16_t fs, _fs_pad; + uint16_t gs, _gs_pad; + uint16_t ldtr, _ldtr_pad; + uint16_t t:1; + uint16_t iobase; +} tss32_t; + +#endif + +/* + * MSR indexes + */ +#define IA32_TIMESTAMP_COUNTER 0x10 +#define IA32_PLATFORM_ID 0x17 +#define IA32_APIC_BASE 0x1b +#define IA32_BIOS_UPDATE_TRIG 0x79 +#define IA32_BIOS_SIGN_ID 0x8b +#define IA32_MTRRCAP 0xfe +#define IA32_MISC_CTL 0x119 +#define IA32_SYSENTER_CS 0x174 +#define IA32_SYSENTER_ESP 0x175 +#define IA32_SYSENTER_EIP 0x176 +#define IA32_MCG_CAP 0x179 +#define IA32_MCG_STATUS 0x17a +#define IA32_MCG_CTL 0x17b +#define IA32_MCG_EAX 0x180 +#define IA32_MCG_EBX 0x181 +#define IA32_MCG_ECX 0x182 +#define IA32_MCG_EDX 0x183 +#define IA32_MCG_ESI 0x184 +#define IA32_MCG_EDI 0x185 +#define IA32_MCG_EBP 0x186 +#define IA32_MCG_ESP 0x187 +#define IA32_MCG_EFLAGS 0x188 +#define IA32_MCG_EIP 0x189 +#define IA32_MCG_MISC 0x18a +#define IA32_TERM_CONTROL 0x19a +#define IA32_TERM_INTERRUPT 0x19b +#define IA32_TERM_STATUS 0x19c +#define IA32_MISC_ENAB 0x1a0 +#define IA32_DEBUGCTL 0x1d9 +#define IA32_MTRR_PHYSBASE0 0x200 +#define IA32_MTRR_PHYSMASK0 0x201 +#define IA32_MTRR_FIX64K_00000 0x250 +#define IA32_MTRR_FIX16K_80000 0x258 +#define IA32_MTRR_FIX16K_A0000 0x259 +#define IA32_MTRR_FIX4K_C0000 0x268 +#define IA32_MTRR_FIX4K_C8000 0x269 +#define IA32_MTRR_FIX4K_D0000 0x26a +#define IA32_MTRR_FIX4K_D8000 0x26b +#define IA32_MTRR_FIX4K_E0000 0x26c +#define IA32_MTRR_FIX4K_E8000 0x26d +#define IA32_MTRR_FIX4K_F0000 0x26e +#define IA32_MTRR_FIX4K_F8000 0x26f +#define IA32_CR_PAT 0x277 +#define IA32_MTRR_DEFTYPE 0x2ff +#define IA32_PEBS_ENABLE 0x3f1 +#define IA32_MCi_START 0x400 +# define IA32_MCi_STEP 4 +# define IA32_MCi_CTL_OFFSET 0 +# define IA32_MCi_STATUS_OFFSET 1 +# define IA32_MCi_ADDR_OFFSET 2 +# define IA32_MCi_MISC_OFFSET 3 +#define IA32_DTES_AREA 0x600 + +/* + * IA32_APIC_BASE + */ +#define APIC_BASE_BSP 8 +#define APIC_BASE_ENABLE 11 +#define APIC_BASE_BASE 12 +#define APIC_BASE_BASE_LEN 24 + +/* + * IA32_MTRRCAP + */ +#define MTRRCAP_VCNT 0 +#define MTRRCAP_VCNT_LEN 8 +#define MTRRCAP_FIX 8 +#define MTRRCAP_WC 10 + +/* + * IA32_DEBUGCTL + */ +#define DEBUGCTL_LBR 0 +#define DEBUGCTL_BTF 1 + +/* + * IA32_MTRR_DEFTYPE + */ +#define MTRR_DEFTYPE_TYPE 0 +#define MTRR_DEFTYPE_TYPE_LEN 8 +#define MTRR_DEFTYPE_FE 10 +#define MTRR_DEFTYPE_E 11 + +/* + * IA32_MTRR_PHYSBASEx + */ +#define MTRR_PHYSBASE_TYPE 0 +#define MTRR_PHYSBASE_TYPE_LEN 8 +#define MTRR_PHYSBASE_BASE 12 +#define MTRR_PHYSBASE_BASE_LEN 24 + +/* + * IA32_MTRR_PHYSMASKx + */ +#define MTRR_PHYSMASK_V 11 +#define MTRR_PHYSMASK_MASK 12 +#define MTRR_PHYSMASK_MASK_LEN 24 + +/* + * Memory Attributes (MTRRs & PAT) + */ +#define IA32_MA_UC 0x00 +#define IA32_MA_WC 0x01 +#define IA32_MA_WT 0x04 +#define IA32_MA_WP 0x05 +#define IA32_MA_WB 0x06 +#define IA32_MA_UC_MINUS 0x07 /* PAT only */ + +/* + * IA32_MCG_CAP + */ +#define IA32_MCG_CAP_COUNT 0 +#define IA32_MCG_CAP_COUNT_LEN 8 +#define IA32_MCG_CTL_P 8 + +/* + * IA32_MCG_STATUS + */ +#define IA32_MCG_STATUS_RIPV 0 +#define IA32_MCG_STATUS_EIPV 1 +#define IA32_MCG_STATUS_MCIP 2 + +/* + * IA32_MCi + */ +#define IA32_MCi_STATUS_MCA_EC 0 +#define IA32_MCi_STATUS_MCA_EC_LEN 16 +#define IA32_MCi_STATUS_MOD_EC 16 +#define IA32_MCi_STATUS_MOD_EC_LEN 16 +#define IA32_MCi_STATUS_PCC 57 +#define IA32_MCi_STATUS_ADDRV 58 +#define IA32_MCi_STATUS_MISCV 59 +#define IA32_MCi_STATUS_EN 60 +#define IA32_MCi_STATUS_UC 61 +#define IA32_MCi_STATUS_OVER 62 +#define IA32_MCi_STATUS_VAL 63 + +#endif /* _ASM_IA_32_H */