/*++ BUILD Version: 0002 // Increment this if a change has global effects Copyright (c) Microsoft Corporation. All rights reserved. Module Name: nti386.h Abstract: User-mode visible i386 specific i386 structures and constants Author: Mark Lucovsky (markl) 30-Nov-1989 Revision History: Bryan Willman (bryanwi) 8-Jan-90 port to the 386 --*/ #ifndef _NTI386_ #define _NTI386_ #if _MSC_VER > 1000 #pragma once #endif #ifdef __cplusplus extern "C" { #endif // begin_ntddk begin_wdm begin_nthal begin_winnt begin_ntminiport begin_wx86 #ifdef _X86_ // // Disable these two pragmas that evaluate to "sti" "cli" on x86 so that driver // writers to not leave them inadvertantly in their code. // #if !defined(MIDL_PASS) #if !defined(RC_INVOKED) #if _MSC_VER >= 1200 #pragma warning(push) #endif #pragma warning(disable:4164) // disable C4164 warning so that apps that // build with /Od don't get weird errors ! #ifdef _M_IX86 #pragma function(_enable) #pragma function(_disable) #endif #if _MSC_VER >= 1200 #pragma warning(pop) #else #pragma warning(default:4164) // reenable C4164 warning #endif #endif #endif #if !defined(MIDL_PASS) || defined(_M_IX86) #if (_MSC_FULL_VER >= 13012035) // // Define bit scan intrinsics. // //#define BitScanForward _BitScanForward //#define BitScanReverse _BitScanReverse //BOOLEAN //_BitScanForward ( // OUT ULONG *Index, // IN ULONG Mask // ); //BOOLEAN //_BitScanReverse ( // OUT ULONG *Index, // IN ULONG Mask // ); //#pragma intrinsic(_BitScanForward) //#pragma intrinsic(_BitScanReverse) // // Define FS referencing intrinsics // #ifdef __cplusplus extern "C" { #endif UCHAR __readfsbyte ( IN ULONG Offset ); USHORT __readfsword ( IN ULONG Offset ); ULONG __readfsdword ( IN ULONG Offset ); VOID __writefsbyte ( IN ULONG Offset, IN UCHAR Data ); VOID __writefsword ( IN ULONG Offset, IN USHORT Data ); VOID __writefsdword ( IN ULONG Offset, IN ULONG Data ); #ifdef __cplusplus } #endif #pragma intrinsic(__readfsbyte) #pragma intrinsic(__readfsword) #pragma intrinsic(__readfsdword) #pragma intrinsic(__writefsbyte) #pragma intrinsic(__writefsword) #pragma intrinsic(__writefsdword) #endif #endif // end_ntddk end_wdm end_nthal end_winnt end_ntminiport end_wx86 // // Values put in ExceptionRecord.ExceptionInformation[0] // First parameter is always in ExceptionInformation[1], // Second parameter is always in ExceptionInformation[2] // #define BREAKPOINT_BREAK 0 #define BREAKPOINT_PRINT 1 #define BREAKPOINT_PROMPT 2 #define BREAKPOINT_LOAD_SYMBOLS 3 #define BREAKPOINT_UNLOAD_SYMBOLS 4 #define BREAKPOINT_COMMAND_STRING 5 // // Define Address of User Shared Data // #define MM_SHARED_USER_DATA_VA 0x7FFE0000 #define USER_SHARED_DATA ((KUSER_SHARED_DATA * const)MM_SHARED_USER_DATA_VA) // Add definitions for quick user mode test of i386 system architecture type #ifndef IsNEC_98 #define IsNEC_98 (USER_SHARED_DATA->AlternativeArchitecture == NEC98x86) #endif #ifndef IsNotNEC_98 #define IsNotNEC_98 (USER_SHARED_DATA->AlternativeArchitecture != NEC98x86) #endif #ifndef SetNEC_98 #define SetNEC_98 #endif #if defined(MIDL_PASS) || !defined(_M_IX86) struct _TEB * NTAPI NtCurrentTeb( void ); #else #define PcTeb 0x18 #if (_MSC_FULL_VER >= 13012035) _inline struct _TEB * NtCurrentTeb( void ) { return (struct _TEB *) (ULONG_PTR) __readfsdword (PcTeb); } #else #if _MSC_VER >= 1200 #pragma warning(push) #endif #pragma warning (disable:4035) // disable 4035 (function must return something) _inline struct _TEB * NtCurrentTeb( void ) { __asm mov eax, fs:[PcTeb] } #if _MSC_VER >= 1200 #pragma warning(pop) #else #pragma warning (default:4035) // reenable it #endif #endif #endif // defined(MIDL_PASS) || defined(__cplusplus) || !defined(_M_IX86) // begin_ntddk begin_nthal // // Size of kernel mode stack. // #define KERNEL_STACK_SIZE 12288 // // Define size of large kernel mode stack for callbacks. // #define KERNEL_LARGE_STACK_SIZE 61440 // // Define number of pages to initialize in a large kernel stack. // #define KERNEL_LARGE_STACK_COMMIT 12288 // end_ntddk end_nthal #define DOUBLE_FAULT_STACK_SIZE KERNEL_STACK_SIZE // // Call frame record definition. // // There is no standard call frame for NT/386, but there is a linked // list structure used to register exception handlers, this is it. // // begin_nthal // // Exception Registration structure // typedef struct _EXCEPTION_REGISTRATION_RECORD { struct _EXCEPTION_REGISTRATION_RECORD *Next; PEXCEPTION_ROUTINE Handler; } EXCEPTION_REGISTRATION_RECORD; typedef EXCEPTION_REGISTRATION_RECORD *PEXCEPTION_REGISTRATION_RECORD; // // Define constants for system IDTs // #define MAXIMUM_IDTVECTOR 0xff #define MAXIMUM_PRIMARY_VECTOR 0xff #define PRIMARY_VECTOR_BASE 0x30 // 0-2f are x86 trap vectors // begin_ntddk #ifdef _X86_ // end_ntddk // begin_ntddk begin_winnt #if !defined(MIDL_PASS) && defined(_M_IX86) FORCEINLINE VOID MemoryBarrier ( VOID ) { LONG Barrier; __asm { xchg Barrier, eax } } #define YieldProcessor() __asm { rep nop } // // Prefetch is not supported on all x86 procssors. // #define PreFetchCacheLine(l, a) // // PreFetchCacheLine level defines. // #define PF_TEMPORAL_LEVEL_1 #define PF_NON_TEMPORAL_LEVEL_ALL // end_ntddk #if (_MSC_FULL_VER >= 13012035) _inline PVOID GetFiberData( void ) { return *(PVOID *) (ULONG_PTR) __readfsdword (0x10);} _inline PVOID GetCurrentFiber( void ) { return (PVOID) (ULONG_PTR) __readfsdword (0x10);} #else #if _MSC_VER >= 1200 #pragma warning(push) #endif #pragma warning (disable:4035) // disable 4035 (function must return something) _inline PVOID GetFiberData( void ) { __asm { mov eax, fs:[0x10] mov eax,[eax] } } _inline PVOID GetCurrentFiber( void ) { __asm mov eax, fs:[0x10] } #if _MSC_VER >= 1200 #pragma warning(pop) #else #pragma warning (default:4035) // Reenable it #endif #endif // begin_ntddk #endif // begin_wx86 // // Define the size of the 80387 save area, which is in the context frame. // #define SIZE_OF_80387_REGISTERS 80 // // The following flags control the contents of the CONTEXT structure. // #if !defined(RC_INVOKED) #define CONTEXT_i386 0x00010000 // this assumes that i386 and #define CONTEXT_i486 0x00010000 // i486 have identical context records // end_wx86 #define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP #define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI #define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L) // DS, ES, FS, GS #define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L) // 387 state #define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7 #define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386 | 0x00000020L) // cpu specific extensions #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER |\ CONTEXT_SEGMENTS) #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS) // begin_wx86 #endif #define MAXIMUM_SUPPORTED_EXTENSION 512 typedef struct _FLOATING_SAVE_AREA { ULONG ControlWord; ULONG StatusWord; ULONG TagWord; ULONG ErrorOffset; ULONG ErrorSelector; ULONG DataOffset; ULONG DataSelector; UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]; ULONG Cr0NpxState; } FLOATING_SAVE_AREA; typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA; // // Context Frame // // This frame has a several purposes: 1) it is used as an argument to // NtContinue, 2) is is used to constuct a call frame for APC delivery, // and 3) it is used in the user level thread creation routines. // // The layout of the record conforms to a standard call frame. // typedef struct _CONTEXT { // // The flags values within this flag control the contents of // a CONTEXT record. // // If the context record is used as an input parameter, then // for each portion of the context record controlled by a flag // whose value is set, it is assumed that that portion of the // context record contains valid context. If the context record // is being used to modify a threads context, then only that // portion of the threads context will be modified. // // If the context record is used as an IN OUT parameter to capture // the context of a thread, then only those portions of the thread's // context corresponding to set flags will be returned. // // The context record is never used as an OUT only parameter. // ULONG ContextFlags; // // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT // included in CONTEXT_FULL. // ULONG Dr0; ULONG Dr1; ULONG Dr2; ULONG Dr3; ULONG Dr6; ULONG Dr7; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_FLOATING_POINT. // FLOATING_SAVE_AREA FloatSave; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_SEGMENTS. // ULONG SegGs; ULONG SegFs; ULONG SegEs; ULONG SegDs; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_INTEGER. // ULONG Edi; ULONG Esi; ULONG Ebx; ULONG Edx; ULONG Ecx; ULONG Eax; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_CONTROL. // ULONG Ebp; ULONG Eip; ULONG SegCs; // MUST BE SANITIZED ULONG EFlags; // MUST BE SANITIZED ULONG Esp; ULONG SegSs; // // This section is specified/returned if the ContextFlags word // contains the flag CONTEXT_EXTENDED_REGISTERS. // The format and contexts are processor specific // UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; } CONTEXT; typedef CONTEXT *PCONTEXT; // begin_ntminiport #endif //_X86_ // end_ntddk end_nthal end_winnt end_ntminiport end_wx86 // // Define the size of FP registers in the FXSAVE format // #define SIZE_OF_FX_REGISTERS 128 // // Format of data for fnsave/frstor instruction // typedef struct _FNSAVE_FORMAT { ULONG ControlWord; ULONG StatusWord; ULONG TagWord; ULONG ErrorOffset; ULONG ErrorSelector; ULONG DataOffset; ULONG DataSelector; UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]; } FNSAVE_FORMAT, *PFNSAVE_FORMAT; // // Format of data for fxsave/fxrstor instruction // #include "pshpack1.h" typedef struct _FXSAVE_FORMAT { USHORT ControlWord; USHORT StatusWord; USHORT TagWord; USHORT ErrorOpcode; ULONG ErrorOffset; ULONG ErrorSelector; ULONG DataOffset; ULONG DataSelector; ULONG MXCsr; ULONG MXCsrMask; UCHAR RegisterArea[SIZE_OF_FX_REGISTERS]; UCHAR Reserved3[SIZE_OF_FX_REGISTERS]; UCHAR Reserved4[224]; UCHAR Align16Byte[8]; } FXSAVE_FORMAT, *PFXSAVE_FORMAT; #include "poppack.h" // // Union for FLOATING_SAVE_AREA and MMX_FLOATING_SAVE_AREA // typedef struct _FX_SAVE_AREA { union { FNSAVE_FORMAT FnArea; FXSAVE_FORMAT FxArea; } U; ULONG NpxSavedCpu; // Cpu that last did fxsave for this thread ULONG Cr0NpxState; // Has to be the last field because of the // Boot thread } FX_SAVE_AREA, *PFX_SAVE_AREA; #define CONTEXT_TO_PROGRAM_COUNTER(Context) ((Context)->Eip) #define PROGRAM_COUNTER_TO_CONTEXT(Context, ProgramCounter) ((Context)->Eip = (ProgramCounter)) #define CONTEXT_LENGTH (sizeof(CONTEXT)) #define CONTEXT_ALIGN (sizeof(ULONG)) #define CONTEXT_ROUND (CONTEXT_ALIGN - 1) // begin_wx86 // // GDT selectors - These defines are R0 selector numbers, which means // they happen to match the byte offset relative to // the base of the GDT. // #define KGDT_NULL 0 #define KGDT_R0_CODE 8 #define KGDT_R0_DATA 16 #define KGDT_R3_CODE 24 #define KGDT_R3_DATA 32 #define KGDT_TSS 40 #define KGDT_R0_PCR 48 #define KGDT_R3_TEB 56 #define KGDT_VDM_TILE 64 #define KGDT_LDT 72 #define KGDT_DF_TSS 80 #define KGDT_NMI_TSS 88 // end_wx86 #ifdef ABIOS // // raid 72661 shielint Should be NEW os2ldr. The ABIOS ifdef will be // removed once we switch to new os2ldr. // #define KGDT_ALIAS 0x70 #define KGDT_NUMBER 11 #else #define KGDT_NUMBER 10 #endif // // LDT descriptor entry // // begin_winnt begin_wx86 #ifndef _LDT_ENTRY_DEFINED #define _LDT_ENTRY_DEFINED typedef struct _LDT_ENTRY { USHORT LimitLow; USHORT BaseLow; union { struct { UCHAR BaseMid; UCHAR Flags1; // Declare as bytes to avoid alignment UCHAR Flags2; // Problems. UCHAR BaseHi; } Bytes; struct { ULONG BaseMid : 8; ULONG Type : 5; ULONG Dpl : 2; ULONG Pres : 1; ULONG LimitHi : 4; ULONG Sys : 1; ULONG Reserved_0 : 1; ULONG Default_Big : 1; ULONG Granularity : 1; ULONG BaseHi : 8; } Bits; } HighWord; } LDT_ENTRY, *PLDT_ENTRY; #endif // end_winnt end_wx86 // // Process Ldt Information // NtQueryInformationProcess using ProcessLdtInformation // typedef struct _LDT_INFORMATION { ULONG Start; ULONG Length; LDT_ENTRY LdtEntries[1]; } PROCESS_LDT_INFORMATION, *PPROCESS_LDT_INFORMATION; // // Process Ldt Size // NtSetInformationProcess using ProcessLdtSize // typedef struct _LDT_SIZE { ULONG Length; } PROCESS_LDT_SIZE, *PPROCESS_LDT_SIZE; // // Thread Descriptor Table Entry // NtQueryInformationThread using ThreadDescriptorTableEntry // // begin_windbgkd #ifndef _DESCRIPTOR_TABLE_ENTRY_DEFINED #define _DESCRIPTOR_TABLE_ENTRY_DEFINED typedef struct _DESCRIPTOR_TABLE_ENTRY { ULONG Selector; LDT_ENTRY Descriptor; } DESCRIPTOR_TABLE_ENTRY, *PDESCRIPTOR_TABLE_ENTRY; #endif // _DESCRIPTOR_TABLE_ENTRY_DEFINED // end_windbgkd // begin_ntddk begin_wdm begin_nthal #endif // _X86_ // end_ntddk end_wdm end_nthal PVOID RtlLookupFunctionTable ( IN PVOID ControlPc, OUT PVOID *ImageBase, OUT PULONG SizeOfTable ); // // Additional information supplied in QuerySectionInformation for images. // #define SECTION_ADDITIONAL_INFO_USED 0 #ifdef __cplusplus } #endif #endif // _NTI386_