Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

i386.h

Go to the documentation of this file.
00001 /*++ BUILD Version: 0014 // Increment this if a change has global effects 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 i386.h 00008 00009 Abstract: 00010 00011 This module contains the i386 hardware specific header file. 00012 00013 Author: 00014 00015 David N. Cutler (davec) 2-Aug-1989 00016 00017 Revision History: 00018 00019 25-Jan-1990 shielint 00020 00021 Added definitions for 8259 ports and commands and 00022 macros for 8259 irq# and system irql conversion. 00023 00024 --*/ 00025 00026 #ifndef _i386_ 00027 #define _i386_ 00028 00029 00030 // begin_ntddk begin_wdm begin_nthal begin_ntndis 00031 00032 #if defined(_X86_) 00033 00034 // 00035 // Types to use to contain PFNs and their counts. 00036 // 00037 00038 typedef ULONG PFN_COUNT; 00039 00040 typedef LONG SPFN_NUMBER, *PSPFN_NUMBER; 00041 typedef ULONG PFN_NUMBER, *PPFN_NUMBER; 00042 00043 // 00044 // Define maximum size of flush multiple TB request. 00045 // 00046 00047 #define FLUSH_MULTIPLE_MAXIMUM 16 00048 00049 // 00050 // Indicate that the i386 compiler supports the pragma textout construct. 00051 // 00052 00053 #define ALLOC_PRAGMA 1 00054 // 00055 // Indicate that the i386 compiler supports the DATA_SEG("INIT") and 00056 // DATA_SEG("PAGE") pragmas 00057 // 00058 00059 #define ALLOC_DATA_PRAGMA 1 00060 00061 // end_ntddk end_nthal end_ntndis end_wdm 00062 00063 00064 // NOTE - KiPcr is only useful for PCR references where we know we 00065 // won't get context switched between the call to it and the 00066 // variable reference, OR, were we don't care, (ie TEB pointer) 00067 00068 // BUGBUG bryanwi 11 june 90 - we must not macro out things we export 00069 // Things like KeFlushIcache and KeFlushDcache cannot be macroed 00070 // out because external code (like drivers) will want to import 00071 // them by name. Therefore, the defines below that turn them into 00072 // nothing are inappropriate. But this isn't going to hurt us right 00073 // now. 00074 00075 // BUGBUG kenr - remove this PIC stuff from i386.h! 00076 00077 00078 // 00079 // Interrupt controller register addresses. 00080 // 00081 00082 #define PIC1_PORT0 0x20 // master PIC 00083 #define PIC1_PORT1 0x21 00084 #define PIC2_PORT0 0x0A0 // slave PIC 00085 #define PIC2_PORT1 0x0A1 00086 00087 // 00088 // Commands for Interrupt Controller 00089 // 00090 00091 #define PIC1_EOI_MASK 0x60 00092 #define PIC2_EOI 0x62 00093 #define OCW2_NON_SPECIFIC_EOI 0x20 00094 #define OCW3_READ_ISR 0xb 00095 #define OCW3_READ_IRR 0xa 00096 00097 00098 // 00099 // Length on interrupt object dispatch code in longwords. 00100 // BUGBUG shielint Reserve 9*4 space for ABIOS stack mapping. If NO 00101 // ABIOS support the size of DISPATCH_LENGTH should be 74. 00102 // 00103 00104 // begin_nthal 00105 00106 #define NORMAL_DISPATCH_LENGTH 106 // ntddk wdm 00107 #define DISPATCH_LENGTH NORMAL_DISPATCH_LENGTH // ntddk wdm 00108 00109 00110 // 00111 // Define constants to access the bits in CR0. 00112 // 00113 00114 #define CR0_PG 0x80000000 // paging 00115 #define CR0_ET 0x00000010 // extension type (80387) 00116 #define CR0_TS 0x00000008 // task switched 00117 #define CR0_EM 0x00000004 // emulate math coprocessor 00118 #define CR0_MP 0x00000002 // math present 00119 #define CR0_PE 0x00000001 // protection enable 00120 00121 // 00122 // More CR0 bits; these only apply to the 80486. 00123 // 00124 00125 #define CR0_CD 0x40000000 // cache disable 00126 #define CR0_NW 0x20000000 // not write-through 00127 #define CR0_AM 0x00040000 // alignment mask 00128 #define CR0_WP 0x00010000 // write protect 00129 #define CR0_NE 0x00000020 // numeric error 00130 00131 // 00132 // CR4 bits; These only apply to Pentium 00133 // 00134 #define CR4_VME 0x00000001 // V86 mode extensions 00135 #define CR4_PVI 0x00000002 // Protected mode virtual interrupts 00136 #define CR4_TSD 0x00000004 // Time stamp disable 00137 #define CR4_DE 0x00000008 // Debugging Extensions 00138 #define CR4_PSE 0x00000010 // Page size extensions 00139 #define CR4_PAE 0x00000020 // Physical address extensions 00140 #define CR4_MCE 0x00000040 // Machine check enable 00141 #define CR4_PGE 0x00000080 // Page global enable 00142 #define CR4_FXSR 0x00000200 // FXSR used by OS 00143 #define CR4_XMMEXCPT 0x00000400 // XMMI used by OS 00144 00145 // begin_ntddk begin_wdm 00146 // 00147 // STATUS register for each MCA bank. 00148 // 00149 00150 typedef union _MCI_STATS { 00151 struct { 00152 USHORT McaCod; 00153 USHORT MsCod; 00154 ULONG OtherInfo : 25; 00155 ULONG Damage : 1; 00156 ULONG AddressValid : 1; 00157 ULONG MiscValid : 1; 00158 ULONG Enabled : 1; 00159 ULONG UnCorrected : 1; 00160 ULONG OverFlow : 1; 00161 ULONG Valid : 1; 00162 } MciStats; 00163 00164 ULONGLONG QuadPart; 00165 00166 } MCI_STATS, *PMCI_STATS; 00167 00168 // end_ntddk end_wdm 00169 // end_nthal 00170 00171 // 00172 // Define constants to access ThNpxState 00173 // 00174 00175 #define NPX_STATE_NOT_LOADED (CR0_TS | CR0_MP) 00176 #define NPX_STATE_LOADED 0 00177 00178 // 00179 // External references to the labels defined in int.asm 00180 // 00181 00182 extern ULONG KiInterruptTemplate[NORMAL_DISPATCH_LENGTH]; 00183 extern PULONG KiInterruptTemplateObject; 00184 extern PULONG KiInterruptTemplateDispatch; 00185 extern PULONG KiInterruptTemplate2ndDispatch; 00186 00187 // begin_ntddk begin_wdm begin_nthal 00188 // 00189 // Interrupt Request Level definitions 00190 // 00191 00192 #define PASSIVE_LEVEL 0 // Passive release level 00193 #define LOW_LEVEL 0 // Lowest interrupt level 00194 #define APC_LEVEL 1 // APC interrupt level 00195 #define DISPATCH_LEVEL 2 // Dispatcher level 00196 00197 #define PROFILE_LEVEL 27 // timer used for profiling. 00198 #define CLOCK1_LEVEL 28 // Interval clock 1 level - Not used on x86 00199 #define CLOCK2_LEVEL 28 // Interval clock 2 level 00200 #define IPI_LEVEL 29 // Interprocessor interrupt level 00201 #define POWER_LEVEL 30 // Power failure level 00202 #define HIGH_LEVEL 31 // Highest interrupt level 00203 #define SYNCH_LEVEL (IPI_LEVEL-1) // synchronization level 00204 // end_ntddk end_wdm 00205 00206 #define KiSynchIrql SYNCH_LEVEL // enable portable code 00207 00208 // 00209 // Machine type definitions 00210 // BUGBUG shielint This is temporary definitions. 00211 // 00212 00213 #define MACHINE_TYPE_ISA 0 00214 #define MACHINE_TYPE_EISA 1 00215 #define MACHINE_TYPE_MCA 2 00216 00217 // end_nthal 00218 // 00219 // The previous values and the following are or'ed in KeI386MachineType. 00220 // The latter section can be removed once PC/AT style computers become 00221 // dominant in Japan. (DavidGoe) 00222 // 00223 00224 #define MACHINE_TYPE_PC_AT_COMPATIBLE 0x00000000 00225 #define MACHINE_TYPE_PC_9800_COMPATIBLE 0x00000100 00226 #define MACHINE_TYPE_FMR_COMPATIBLE 0x00000200 00227 00228 extern ULONG KeI386MachineType; 00229 00230 // begin_nthal 00231 // 00232 // Define constants used in selector tests. 00233 // 00234 // RPL_MASK is the real value for extracting RPL values. IT IS THE WRONG 00235 // CONSTANT TO USE FOR MODE TESTING. 00236 // 00237 // MODE_MASK is the value for deciding the current mode. 00238 // WARNING: MODE_MASK assumes that all code runs at either ring-0 00239 // or ring-3. Ring-1 or Ring-2 support will require changing 00240 // this value and all of the code that refers to it. 00241 00242 #define MODE_MASK 1 00243 #define RPL_MASK 3 00244 00245 // 00246 // SEGMENT_MASK is used to throw away trash part of segment. Part always 00247 // pushes or pops 32 bits to/from stack, but if it's a segment value, 00248 // high order 16 bits are trash. 00249 // 00250 00251 #define SEGMENT_MASK 0xffff 00252 00253 // 00254 // Startup count value for KeStallExecution. This value is used 00255 // until KiInitializeStallExecution can compute the real one. 00256 // Pick a value long enough for very fast processors. 00257 // 00258 00259 #define INITIAL_STALL_COUNT 100 00260 00261 // end_nthal 00262 00263 // 00264 // begin_nthal 00265 // 00266 // Macro to extract the high word of a long offset 00267 // 00268 00269 #define HIGHWORD(l) \ 00270 ((USHORT)(((ULONG)(l)>>16) & 0xffff)) 00271 00272 // 00273 // Macro to extract the low word of a long offset 00274 // 00275 00276 #define LOWWORD(l) \ 00277 ((USHORT)((ULONG)l & 0x0000ffff)) 00278 00279 // 00280 // Macro to combine two USHORT offsets into a long offset 00281 // 00282 00283 #if !defined(MAKEULONG) 00284 00285 #define MAKEULONG(x, y) \ 00286 (((((ULONG)(x))<<16) & 0xffff0000) | \ 00287 ((ULONG)(y) & 0xffff)) 00288 00289 #endif 00290 00291 // end_nthal 00292 00293 // 00294 // Request a software interrupt. 00295 // 00296 00297 #define KiRequestSoftwareInterrupt(RequestIrql) \ 00298 HalRequestSoftwareInterrupt( RequestIrql ) 00299 00300 // begin_ntddk begin_wdm begin_nthal begin_ntndis 00301 00302 // 00303 // I/O space read and write macros. 00304 // 00305 // These have to be actual functions on the 386, because we need 00306 // to use assembler, but cannot return a value if we inline it. 00307 // 00308 // The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space. 00309 // (Use x86 move instructions, with LOCK prefix to force correct behavior 00310 // w.r.t. caches and write buffers.) 00311 // 00312 // The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space. 00313 // (Use x86 in/out instructions.) 00314 // 00315 00316 NTHALAPI 00317 UCHAR 00318 READ_REGISTER_UCHAR( 00319 PUCHAR Register 00320 ); 00321 00322 NTHALAPI 00323 USHORT 00324 READ_REGISTER_USHORT( 00325 PUSHORT Register 00326 ); 00327 00328 NTHALAPI 00329 ULONG 00330 READ_REGISTER_ULONG( 00331 PULONG Register 00332 ); 00333 00334 NTHALAPI 00335 VOID 00336 READ_REGISTER_BUFFER_UCHAR( 00337 PUCHAR Register, 00338 PUCHAR Buffer, 00339 ULONG Count 00340 ); 00341 00342 NTHALAPI 00343 VOID 00344 READ_REGISTER_BUFFER_USHORT( 00345 PUSHORT Register, 00346 PUSHORT Buffer, 00347 ULONG Count 00348 ); 00349 00350 NTHALAPI 00351 VOID 00352 READ_REGISTER_BUFFER_ULONG( 00353 PULONG Register, 00354 PULONG Buffer, 00355 ULONG Count 00356 ); 00357 00358 00359 NTHALAPI 00360 VOID 00361 WRITE_REGISTER_UCHAR( 00362 PUCHAR Register, 00363 UCHAR Value 00364 ); 00365 00366 NTHALAPI 00367 VOID 00368 WRITE_REGISTER_USHORT( 00369 PUSHORT Register, 00370 USHORT Value 00371 ); 00372 00373 NTHALAPI 00374 VOID 00375 WRITE_REGISTER_ULONG( 00376 PULONG Register, 00377 ULONG Value 00378 ); 00379 00380 NTHALAPI 00381 VOID 00382 WRITE_REGISTER_BUFFER_UCHAR( 00383 PUCHAR Register, 00384 PUCHAR Buffer, 00385 ULONG Count 00386 ); 00387 00388 NTHALAPI 00389 VOID 00390 WRITE_REGISTER_BUFFER_USHORT( 00391 PUSHORT Register, 00392 PUSHORT Buffer, 00393 ULONG Count 00394 ); 00395 00396 NTHALAPI 00397 VOID 00398 WRITE_REGISTER_BUFFER_ULONG( 00399 PULONG Register, 00400 PULONG Buffer, 00401 ULONG Count 00402 ); 00403 00404 NTHALAPI 00405 UCHAR 00406 READ_PORT_UCHAR( 00407 PUCHAR Port 00408 ); 00409 00410 NTHALAPI 00411 USHORT 00412 READ_PORT_USHORT( 00413 PUSHORT Port 00414 ); 00415 00416 NTHALAPI 00417 ULONG 00418 READ_PORT_ULONG( 00419 PULONG Port 00420 ); 00421 00422 NTHALAPI 00423 VOID 00424 READ_PORT_BUFFER_UCHAR( 00425 PUCHAR Port, 00426 PUCHAR Buffer, 00427 ULONG Count 00428 ); 00429 00430 NTHALAPI 00431 VOID 00432 READ_PORT_BUFFER_USHORT( 00433 PUSHORT Port, 00434 PUSHORT Buffer, 00435 ULONG Count 00436 ); 00437 00438 NTHALAPI 00439 VOID 00440 READ_PORT_BUFFER_ULONG( 00441 PULONG Port, 00442 PULONG Buffer, 00443 ULONG Count 00444 ); 00445 00446 NTHALAPI 00447 VOID 00448 WRITE_PORT_UCHAR( 00449 PUCHAR Port, 00450 UCHAR Value 00451 ); 00452 00453 NTHALAPI 00454 VOID 00455 WRITE_PORT_USHORT( 00456 PUSHORT Port, 00457 USHORT Value 00458 ); 00459 00460 NTHALAPI 00461 VOID 00462 WRITE_PORT_ULONG( 00463 PULONG Port, 00464 ULONG Value 00465 ); 00466 00467 NTHALAPI 00468 VOID 00469 WRITE_PORT_BUFFER_UCHAR( 00470 PUCHAR Port, 00471 PUCHAR Buffer, 00472 ULONG Count 00473 ); 00474 00475 NTHALAPI 00476 VOID 00477 WRITE_PORT_BUFFER_USHORT( 00478 PUSHORT Port, 00479 PUSHORT Buffer, 00480 ULONG Count 00481 ); 00482 00483 NTHALAPI 00484 VOID 00485 WRITE_PORT_BUFFER_ULONG( 00486 PULONG Port, 00487 PULONG Buffer, 00488 ULONG Count 00489 ); 00490 00491 // end_ntndis 00492 // 00493 // Get data cache fill size. 00494 // 00495 00496 #define KeGetDcacheFillSize() 1L 00497 00498 // end_ntddk end_wdm end_nthal 00499 00500 // 00501 // Fill TB entry. 00502 // 00503 00504 #define KeFillEntryTb(Pte, Virtual, Invalid) \ 00505 if (Invalid != FALSE) { \ 00506 Ke386InvalidateTb (Virtual); \ 00507 } 00508 00509 #if !defined(MIDL_PASS) && defined(_M_IX86) && !defined(_CROSS_PLATFORM_) 00510 00511 __inline 00512 VOID 00513 Ke386InvalidateTb ( 00514 IN PVOID Virtual 00515 ) 00516 { 00517 __asm { 00518 mov eax, Virtual 00519 invlpg [eax] 00520 } 00521 } 00522 00523 #endif 00524 00525 // 00526 // Data cache, instruction cache, I/O buffer, and write buffer flush routine 00527 // prototypes. 00528 // 00529 00530 // 386 and 486 have transparent caches, so these are noops. 00531 00532 #define KeSweepDcache(AllProcessors) 00533 #define KeSweepCurrentDcache() 00534 00535 #define KeSweepIcache(AllProcessors) 00536 #define KeSweepCurrentIcache() 00537 00538 #define KeSweepIcacheRange(AllProcessors, BaseAddress, Length) 00539 00540 // begin_ntddk begin_wdm begin_nthal begin_ntndis 00541 00542 #define KeFlushIoBuffers(Mdl, ReadOperation, DmaOperation) 00543 00544 // end_ntddk end_wdm end_ntndis 00545 00546 #define KeYieldProcessor() __asm { rep nop } 00547 00548 // end_nthal 00549 00550 // 00551 // Define executive macros for acquiring and releasing executive spinlocks. 00552 // These macros can ONLY be used by executive components and NOT by drivers. 00553 // Drivers MUST use the kernel interfaces since they must be MP enabled on 00554 // all systems. 00555 // 00556 // KeRaiseIrql is one instruction longer than KeAcquireSpinLock on x86 UP. 00557 // KeLowerIrql and KeReleaseSpinLock are the same. 00558 // 00559 00560 #if defined(NT_UP) && !DBG && !defined(_NTDDK_) && !defined(_NTIFS_) 00561 00562 #if !defined(_NTDRIVER_) 00563 #define ExAcquireSpinLock(Lock, OldIrql) (*OldIrql) = KeRaiseIrqlToDpcLevel(); 00564 #define ExReleaseSpinLock(Lock, OldIrql) KeLowerIrql((OldIrql)) 00565 #else 00566 #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql)) 00567 #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql)) 00568 #endif 00569 #define ExAcquireSpinLockAtDpcLevel(Lock) 00570 #define ExReleaseSpinLockFromDpcLevel(Lock) 00571 00572 #else 00573 00574 // begin_wdm begin_ntddk 00575 00576 #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql)) 00577 #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql)) 00578 #define ExAcquireSpinLockAtDpcLevel(Lock) KeAcquireSpinLockAtDpcLevel(Lock) 00579 #define ExReleaseSpinLockFromDpcLevel(Lock) KeReleaseSpinLockFromDpcLevel(Lock) 00580 00581 // end_wdm end_ntddk 00582 00583 #endif 00584 00585 // 00586 // The acquire and release fast lock macros disable and enable interrupts 00587 // on UP nondebug systems. On MP or debug systems, the spinlock routines 00588 // are used. 00589 // 00590 // N.B. Extreme caution should be observed when using these routines. 00591 // 00592 00593 #if defined(_M_IX86) && !defined(USER_MODE_CODE) 00594 00595 #pragma warning(disable:4164) 00596 #pragma intrinsic(_disable) 00597 #pragma intrinsic(_enable) 00598 #pragma warning(default:4164) 00599 00600 #endif 00601 00602 #if defined(NT_UP) && !DBG && !defined(USER_MODE_CODE) 00603 #define ExAcquireFastLock(Lock, OldIrql) _disable() 00604 #else 00605 #define ExAcquireFastLock(Lock, OldIrql) \ 00606 ExAcquireSpinLock(Lock, OldIrql) 00607 #endif 00608 00609 #if defined(NT_UP) && !DBG && !defined(USER_MODE_CODE) 00610 #define ExReleaseFastLock(Lock, OldIrql) _enable() 00611 #else 00612 #define ExReleaseFastLock(Lock, OldIrql) \ 00613 ExReleaseSpinLock(Lock, OldIrql) 00614 #endif 00615 00616 // 00617 // The following function prototypes must be in this module so that the 00618 // above macros can call them directly. 00619 // 00620 // begin_nthal 00621 00622 VOID 00623 FASTCALL 00624 KiAcquireSpinLock ( 00625 IN PKSPIN_LOCK SpinLock 00626 ); 00627 00628 VOID 00629 FASTCALL 00630 KiReleaseSpinLock ( 00631 IN PKSPIN_LOCK SpinLock 00632 ); 00633 00634 // end_nthal 00635 00636 // 00637 // KeTestSpinLock may be used to spin at low IRQL until the lock is 00638 // available. The IRQL must then be raised and the lock acquired with 00639 // KeTryToAcquireSpinLock. If that fails, lower the IRQL and start again. 00640 // 00641 00642 #if defined(NT_UP) 00643 00644 #define KeTestSpinLock(SpinLock) (TRUE) 00645 00646 #else 00647 00648 BOOLEAN 00649 FASTCALL 00650 KeTestSpinLock ( 00651 IN PKSPIN_LOCK SpinLock 00652 ); 00653 00654 #endif 00655 00656 // 00657 // Define query system time macro. 00658 // 00659 00660 #define KiQuerySystemTime(CurrentTime) \ 00661 while (TRUE) { \ 00662 (CurrentTime)->HighPart = SharedUserData->SystemTime.High1Time; \ 00663 (CurrentTime)->LowPart = SharedUserData->SystemTime.LowPart; \ 00664 if ((CurrentTime)->HighPart == SharedUserData->SystemTime.High2Time) break; \ 00665 _asm { rep nop } \ 00666 } 00667 // 00668 // Define query tick count macro. 00669 // 00670 00671 #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) 00672 00673 // begin_wdm begin_ntddk 00674 00675 #define KeQueryTickCount(CurrentCount ) { \ 00676 volatile PKSYSTEM_TIME _TickCount = *((PKSYSTEM_TIME *)(&KeTickCount)); \ 00677 while (TRUE) { \ 00678 (CurrentCount)->HighPart = _TickCount->High1Time; \ 00679 (CurrentCount)->LowPart = _TickCount->LowPart; \ 00680 if ((CurrentCount)->HighPart == _TickCount->High2Time) break; \ 00681 _asm { rep nop } \ 00682 } \ 00683 } 00684 00685 // end_wdm end_ntddk 00686 00687 #else 00688 00689 // begin_nthal 00690 #define KiQueryTickCount(CurrentCount) \ 00691 while (TRUE) { \ 00692 (CurrentCount)->HighPart = KeTickCount.High1Time; \ 00693 (CurrentCount)->LowPart = KeTickCount.LowPart; \ 00694 if ((CurrentCount)->HighPart == KeTickCount.High2Time) break; \ 00695 _asm { rep nop } \ 00696 } 00697 00698 VOID 00699 KeQueryTickCount ( 00700 OUT PLARGE_INTEGER CurrentCount 00701 ); 00702 00703 // end_nthal 00704 #endif 00705 00706 #define KiQueryLowTickCount() KeTickCount.LowPart 00707 00708 // 00709 // Define query interrupt time macro. 00710 // 00711 00712 #define KiQueryInterruptTime(CurrentTime) \ 00713 while (TRUE) { \ 00714 (CurrentTime)->HighPart = SharedUserData->InterruptTime.High1Time; \ 00715 (CurrentTime)->LowPart = SharedUserData->InterruptTime.LowPart; \ 00716 if ((CurrentTime)->HighPart == SharedUserData->InterruptTime.High2Time) break; \ 00717 _asm { rep nop } \ 00718 } 00719 00720 00721 // begin_nthal 00722 // 00723 // 386 hardware structures 00724 // 00725 00726 // 00727 // A Page Table Entry on an Intel 386/486 has the following definition. 00728 // 00729 // **** NOTE A PRIVATE COPY OF THIS EXISTS IN THE MM\I386 DIRECTORY! **** 00730 // **** ANY CHANGES NEED TO BE MADE TO BOTH HEADER FILES. **** 00731 // 00732 00733 00734 typedef struct _HARDWARE_PTE_X86 { 00735 ULONG Valid : 1; 00736 ULONG Write : 1; 00737 ULONG Owner : 1; 00738 ULONG WriteThrough : 1; 00739 ULONG CacheDisable : 1; 00740 ULONG Accessed : 1; 00741 ULONG Dirty : 1; 00742 ULONG LargePage : 1; 00743 ULONG Global : 1; 00744 ULONG CopyOnWrite : 1; // software field 00745 ULONG Prototype : 1; // software field 00746 ULONG reserved : 1; // software field 00747 ULONG PageFrameNumber : 20; 00748 } HARDWARE_PTE_X86, *PHARDWARE_PTE_X86; 00749 00750 typedef struct _HARDWARE_PTE_X86PAE { 00751 union { 00752 struct { 00753 ULONGLONG Valid : 1; 00754 ULONGLONG Write : 1; 00755 ULONGLONG Owner : 1; 00756 ULONGLONG WriteThrough : 1; 00757 ULONGLONG CacheDisable : 1; 00758 ULONGLONG Accessed : 1; 00759 ULONGLONG Dirty : 1; 00760 ULONGLONG LargePage : 1; 00761 ULONGLONG Global : 1; 00762 ULONGLONG CopyOnWrite : 1; // software field 00763 ULONGLONG Prototype : 1; // software field 00764 ULONGLONG reserved0 : 1; // software field 00765 ULONGLONG PageFrameNumber : 24; 00766 ULONGLONG reserved1 : 28; // software field 00767 }; 00768 struct { 00769 ULONG LowPart; 00770 ULONG HighPart; 00771 }; 00772 }; 00773 } HARDWARE_PTE_X86PAE, *PHARDWARE_PTE_X86PAE; 00774 00775 #if !defined (_X86PAE_) 00776 typedef HARDWARE_PTE_X86 HARDWARE_PTE; 00777 typedef PHARDWARE_PTE_X86 PHARDWARE_PTE; 00778 #else 00779 typedef HARDWARE_PTE_X86PAE HARDWARE_PTE; 00780 typedef PHARDWARE_PTE_X86PAE PHARDWARE_PTE; 00781 #endif 00782 00783 // 00784 // GDT Entry 00785 // 00786 00787 typedef struct _KGDTENTRY { 00788 USHORT LimitLow; 00789 USHORT BaseLow; 00790 union { 00791 struct { 00792 UCHAR BaseMid; 00793 UCHAR Flags1; // Declare as bytes to avoid alignment 00794 UCHAR Flags2; // Problems. 00795 UCHAR BaseHi; 00796 } Bytes; 00797 struct { 00798 ULONG BaseMid : 8; 00799 ULONG Type : 5; 00800 ULONG Dpl : 2; 00801 ULONG Pres : 1; 00802 ULONG LimitHi : 4; 00803 ULONG Sys : 1; 00804 ULONG Reserved_0 : 1; 00805 ULONG Default_Big : 1; 00806 ULONG Granularity : 1; 00807 ULONG BaseHi : 8; 00808 } Bits; 00809 } HighWord; 00810 } KGDTENTRY, *PKGDTENTRY; 00811 00812 #define TYPE_CODE 0x10 // 11010 = Code, Readable, NOT Conforming, Accessed 00813 #define TYPE_DATA 0x12 // 10010 = Data, ReadWrite, NOT Expanddown, Accessed 00814 #define TYPE_TSS 0x01 // 01001 = NonBusy TSS 00815 #define TYPE_LDT 0x02 // 00010 = LDT 00816 00817 #define DPL_USER 3 00818 #define DPL_SYSTEM 0 00819 00820 #define GRAN_BYTE 0 00821 #define GRAN_PAGE 1 00822 00823 #define SELECTOR_TABLE_INDEX 0x04 00824 00825 // 00826 // Entry of Interrupt Descriptor Table (IDTENTRY) 00827 // 00828 00829 typedef struct _KIDTENTRY { 00830 USHORT Offset; 00831 USHORT Selector; 00832 USHORT Access; 00833 USHORT ExtendedOffset; 00834 } KIDTENTRY; 00835 00836 typedef KIDTENTRY *PKIDTENTRY; 00837 00838 00839 // 00840 // TSS (Task switch segment) NT only uses to control stack switches. 00841 // 00842 // The only fields we actually care about are Esp0, Ss0, the IoMapBase 00843 // and the IoAccessMaps themselves. 00844 // 00845 // 00846 // N.B. Size of TSS must be <= 0xDFFF 00847 // 00848 00849 // 00850 // The interrupt direction bitmap is used on Pentium to allow 00851 // the processor to emulate V86 mode software interrupts for us. 00852 // There is one for each IOPM. It is located by subtracting 00853 // 32 from the IOPM base in the Tss. 00854 // 00855 #define INT_DIRECTION_MAP_SIZE 32 00856 typedef UCHAR KINT_DIRECTION_MAP[INT_DIRECTION_MAP_SIZE]; 00857 00858 #define IOPM_COUNT 1 // Number of i/o access maps that 00859 // exist (in addition to 00860 // IO_ACCESS_MAP_NONE) 00861 00862 #define IO_ACCESS_MAP_NONE 0 00863 00864 #define IOPM_SIZE 8192 // Size of map callers can set. 00865 00866 #define PIOPM_SIZE 8196 // Size of structure we must allocate 00867 // to hold it. 00868 00869 typedef UCHAR KIO_ACCESS_MAP[IOPM_SIZE]; 00870 00871 typedef KIO_ACCESS_MAP *PKIO_ACCESS_MAP; 00872 00873 typedef struct _KiIoAccessMap { 00874 KINT_DIRECTION_MAP DirectionMap; 00875 UCHAR IoMap[PIOPM_SIZE]; 00876 } KIIO_ACCESS_MAP; 00877 00878 00879 typedef struct _KTSS { 00880 00881 USHORT Backlink; 00882 USHORT Reserved0; 00883 00884 ULONG Esp0; 00885 USHORT Ss0; 00886 USHORT Reserved1; 00887 00888 ULONG NotUsed1[4]; 00889 00890 ULONG CR3; 00891 00892 ULONG Eip; 00893 00894 ULONG NotUsed2[9]; 00895 00896 USHORT Es; 00897 USHORT Reserved2; 00898 00899 USHORT Cs; 00900 USHORT Reserved3; 00901 00902 USHORT Ss; 00903 USHORT Reserved4; 00904 00905 USHORT Ds; 00906 USHORT Reserved5; 00907 00908 USHORT Fs; 00909 USHORT Reserved6; 00910 00911 USHORT Gs; 00912 USHORT Reserved7; 00913 00914 USHORT LDT; 00915 USHORT Reserved8; 00916 00917 USHORT Flags; 00918 00919 USHORT IoMapBase; 00920 00921 KIIO_ACCESS_MAP IoMaps[IOPM_COUNT]; 00922 00923 // 00924 // This is the Software interrupt direction bitmap associated with 00925 // IO_ACCESS_MAP_NONE 00926 // 00927 KINT_DIRECTION_MAP IntDirectionMap; 00928 } KTSS, *PKTSS; 00929 00930 00931 #define KiComputeIopmOffset(MapNumber) \ 00932 (MapNumber == IO_ACCESS_MAP_NONE) ? \ 00933 (USHORT)(sizeof(KTSS)) : \ 00934 (USHORT)(FIELD_OFFSET(KTSS, IoMaps[MapNumber-1].IoMap)) 00935 00936 // begin_windbgkd 00937 00938 #ifdef _X86_ 00939 // 00940 // Special Registers for i386 00941 // 00942 00943 typedef struct _DESCRIPTOR { 00944 USHORT Pad; 00945 USHORT Limit; 00946 ULONG Base; 00947 } KDESCRIPTOR, *PKDESCRIPTOR; 00948 00949 typedef struct _KSPECIAL_REGISTERS { 00950 ULONG Cr0; 00951 ULONG Cr2; 00952 ULONG Cr3; 00953 ULONG Cr4; 00954 ULONG KernelDr0; 00955 ULONG KernelDr1; 00956 ULONG KernelDr2; 00957 ULONG KernelDr3; 00958 ULONG KernelDr6; 00959 ULONG KernelDr7; 00960 KDESCRIPTOR Gdtr; 00961 KDESCRIPTOR Idtr; 00962 USHORT Tr; 00963 USHORT Ldtr; 00964 ULONG Reserved[6]; 00965 } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; 00966 00967 // 00968 // Processor State frame: Before a processor freezes itself, it 00969 // dumps the processor state to the processor state frame for 00970 // debugger to examine. 00971 // 00972 00973 typedef struct _KPROCESSOR_STATE { 00974 struct _CONTEXT ContextFrame; 00975 struct _KSPECIAL_REGISTERS SpecialRegisters; 00976 } KPROCESSOR_STATE, *PKPROCESSOR_STATE; 00977 #endif // _X86_ 00978 // end_windbgkd 00979 00980 // 00981 // Processor Control Block (PRCB) 00982 // 00983 00984 #define PRCB_MAJOR_VERSION 1 00985 #define PRCB_MINOR_VERSION 1 00986 #define PRCB_BUILD_DEBUG 0x0001 00987 #define PRCB_BUILD_UNIPROCESSOR 0x0002 00988 00989 typedef struct _KPRCB { 00990 00991 // 00992 // Start of the architecturally defined section of the PRCB. This section 00993 // may be directly addressed by vendor/platform specific HAL code and will 00994 // not change from version to version of NT. 00995 // 00996 USHORT MinorVersion; 00997 USHORT MajorVersion; 00998 00999 struct _KTHREAD *CurrentThread; 01000 struct _KTHREAD *NextThread; 01001 struct _KTHREAD *IdleThread; 01002 01003 CCHAR Number; 01004 CCHAR Reserved; 01005 USHORT BuildType; 01006 KAFFINITY SetMember; 01007 01008 CCHAR CpuType; 01009 CCHAR CpuID; 01010 USHORT CpuStep; 01011 01012 struct _KPROCESSOR_STATE ProcessorState; 01013 01014 ULONG KernelReserved[16]; // For use by the kernel 01015 ULONG HalReserved[16]; // For use by Hal 01016 01017 // 01018 // Per processor lock queue entries. 01019 // 01020 01021 KSPIN_LOCK_QUEUE LockQueue[16]; 01022 01023 // End of the architecturally defined section of the PRCB. 01024 // end_nthal 01025 01026 struct _KTHREAD *NpxThread; 01027 01028 ULONG InterruptCount; // per processor counts 01029 ULONG KernelTime; 01030 ULONG UserTime; 01031 ULONG DpcTime; 01032 ULONG InterruptTime; 01033 ULONG ApcBypassCount; 01034 ULONG DpcBypassCount; 01035 ULONG AdjustDpcThreshold; 01036 ULONG DebugDpcTime; // per dpc tick count 01037 ULONG Spare2[4]; 01038 01039 ULONG ThreadStartCount[2]; // perf data 01040 01041 01042 // MP tuning.. 01043 01044 // 01045 // Per-processor data for various hot code which resides in the 01046 // kernel image. We give each processor it's own copy of the data 01047 // to lessen the caching impact of sharing the data between multiple 01048 // processors. 01049 // 01050 01051 // 01052 // Spares (formerly fsrtl filelock free lists) 01053 // 01054 01055 PVOID SpareHotData[2]; 01056 01057 // 01058 // Cache manager performance counters. 01059 // 01060 01061 ULONG CcFastReadNoWait; 01062 ULONG CcFastReadWait; 01063 ULONG CcFastReadNotPossible; 01064 ULONG CcCopyReadNoWait; 01065 ULONG CcCopyReadWait; 01066 ULONG CcCopyReadNoWaitMiss; 01067 01068 // 01069 // Kernel performance counters. 01070 // 01071 01072 ULONG KeAlignmentFixupCount; 01073 ULONG KeContextSwitches; 01074 ULONG KeDcacheFlushCount; 01075 ULONG KeExceptionDispatchCount; 01076 ULONG KeFirstLevelTbFills; 01077 ULONG KeFloatingEmulationCount; 01078 ULONG KeIcacheFlushCount; 01079 ULONG KeSecondLevelTbFills; 01080 ULONG KeSystemCalls; 01081 01082 // 01083 // Reserved for future counters. 01084 // 01085 01086 ULONG ReservedCounter[8]; 01087 01088 // 01089 // I/O system per processor single entry lookaside lists. 01090 // 01091 01092 PVOID SmallIrpFreeEntry; 01093 PVOID LargeIrpFreeEntry; 01094 PVOID MdlFreeEntry; 01095 01096 // 01097 // Object manager per processor single entry lookaside lists. 01098 // 01099 01100 PVOID CreateInfoFreeEntry; 01101 PVOID NameBufferFreeEntry; 01102 01103 // 01104 // Cache manager per processor single entry lookaside lists. 01105 // 01106 01107 PVOID SharedCacheMapEntry; 01108 01109 // 01110 // Cache pad. 01111 // 01112 01113 ULONG CachePad0[2]; 01114 01115 // 01116 // Nonpaged per processor lookaside lists. 01117 // 01118 01119 PP_LOOKASIDE_LIST PPLookasideList[16]; 01120 01121 // 01122 // Nonpaged per processor small pool lookaside lists. 01123 // 01124 01125 PP_LOOKASIDE_LIST PPNPagedLookasideList[POOL_SMALL_LISTS]; 01126 01127 // 01128 // Paged per processor small pool lookaside lists. 01129 // 01130 01131 PP_LOOKASIDE_LIST PPPagedLookasideList[POOL_SMALL_LISTS]; 01132 01133 // 01134 // Reserved Pad. 01135 // 01136 01137 UCHAR ReservedPad[16 * 8]; 01138 01139 // 01140 // MP interprocessor request packet and summary. 01141 // 01142 // N.B. This is carefully aligned to be on a cache line boundary. 01143 // 01144 01145 volatile PVOID CurrentPacket[3]; 01146 volatile KAFFINITY TargetSet; 01147 volatile PKIPI_WORKER WorkerRoutine; 01148 volatile ULONG IpiFrozen; 01149 ULONG CachePad1[2]; 01150 01151 // 01152 // MP interprocessor request summary and packet address. 01153 // 01154 01155 volatile ULONG RequestSummary; 01156 volatile struct _KPRCB *SignalDone; 01157 volatile ULONG ReverseStall; 01158 PVOID IpiFrame; 01159 ULONG CachePad2[4]; 01160 01161 // 01162 // DPC interrupt requested. 01163 // 01164 01165 ULONG DpcInterruptRequested; 01166 01167 // 01168 // Per processor chained interrupt list. 01169 // (This is not here for any performance reason, it seemed reasonable 01170 // to use a cache pad dword for something useful). 01171 // 01172 01173 PVOID ChainedInterruptList; 01174 ULONG CachePad3[2]; 01175 01176 // 01177 // DPC batching parameters. 01178 // 01179 01180 ULONG MaximumDpcQueueDepth; 01181 ULONG MinimumDpcRate; 01182 ULONG CachePad4[2]; 01183 01184 // 01185 // DPC list head, spinlock, and count. 01186 // 01187 01188 LIST_ENTRY DpcListHead; 01189 ULONG DpcQueueDepth; 01190 ULONG DpcRoutineActive; 01191 ULONG DpcCount; 01192 ULONG DpcLastCount; 01193 ULONG DpcRequestRate; 01194 PVOID DpcStack; 01195 01196 ULONG KernelReserved2[10]; 01197 KSPIN_LOCK DpcLock; 01198 01199 // 01200 // Debug & processor information 01201 // 01202 01203 BOOLEAN SkipTick; 01204 UCHAR VendorString[13]; 01205 ULONG MHz; 01206 ULONG FeatureBits; 01207 LARGE_INTEGER UpdateSignature; 01208 01209 // 01210 // QuantumEnd indicator 01211 // 01212 01213 ULONG QuantumEnd; 01214 01215 // 01216 // Processors power state 01217 // 01218 01219 PROCESSOR_POWER_STATE PowerState; 01220 01221 // 01222 // Npx save area 01223 // 01224 FX_SAVE_AREA NpxSaveArea; 01225 01226 // begin_nthal 01227 } KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB; 01228 01229 // begin_ntddk 01230 01231 // 01232 // Processor Control Region Structure Definition 01233 // 01234 01235 #define PCR_MINOR_VERSION 1 01236 #define PCR_MAJOR_VERSION 1 01237 01238 typedef struct _KPCR { 01239 01240 // 01241 // Start of the architecturally defined section of the PCR. This section 01242 // may be directly addressed by vendor/platform specific HAL code and will 01243 // not change from version to version of NT. 01244 // 01245 01246 NT_TIB NtTib; 01247 struct _KPCR *SelfPcr; // flat address of this PCR 01248 struct _KPRCB *Prcb; // pointer to Prcb 01249 KIRQL Irql; 01250 ULONG IRR; 01251 ULONG IrrActive; 01252 ULONG IDR; 01253 ULONG Reserved2; 01254 01255 struct _KIDTENTRY *IDT; 01256 struct _KGDTENTRY *GDT; 01257 struct _KTSS *TSS; 01258 USHORT MajorVersion; 01259 USHORT MinorVersion; 01260 KAFFINITY SetMember; 01261 ULONG StallScaleFactor; 01262 UCHAR DebugActive; 01263 UCHAR Number; 01264 01265 // end_ntddk 01266 01267 UCHAR VdmAlert; 01268 UCHAR Reserved[1]; // dword align 01269 ULONG KernelReserved[15]; // For use by the kernel 01270 ULONG SecondLevelCacheSize; 01271 ULONG HalReserved[16]; // For use by Hal 01272 01273 // End of the architecturally defined section of the PCR. 01274 // end_nthal 01275 01276 ULONG InterruptMode; 01277 UCHAR Spare1; 01278 ULONG KernelReserved2[17]; 01279 struct _KPRCB PrcbData; 01280 01281 // begin_nthal begin_ntddk 01282 } KPCR; 01283 typedef KPCR *PKPCR; 01284 01285 // end_nthal end_ntddk 01286 01287 01288 // 01289 // Sanitize segCS and eFlags based on a processor mode. 01290 // 01291 // If kernel mode, 01292 // force CPL == 0 01293 // 01294 // If user mode, 01295 // force CPL == 3 01296 // 01297 01298 #define SANITIZE_SEG(segCS, mode) (\ 01299 ((mode) == KernelMode ? \ 01300 ((0x00000000L) | ((segCS) & 0xfffc)) : \ 01301 ((0x00000003L) | ((segCS) & 0xffff)))) 01302 01303 // 01304 // If kernel mode, then 01305 // let caller specify Carry, Parity, AuxCarry, Zero, Sign, Trap, 01306 // Direction, Overflow, Interrupt, AlignCheck. 01307 // 01308 // If user mode, then 01309 // let caller specify Carry, Parity, AuxCarry, Zero, Sign, Trap, 01310 // Direction, Overflow, AlignCheck. 01311 // force Interrupts on. 01312 // 01313 01314 #define EFLAGS_DF_MASK 0x00000400L 01315 #define EFLAGS_INTERRUPT_MASK 0x00000200L 01316 #define EFLAGS_V86_MASK 0x00020000L 01317 #define EFLAGS_ALIGN_CHECK 0x00040000L 01318 #define EFLAGS_IOPL_MASK 0x00003000L 01319 #define EFLAGS_VIF 0x00080000L 01320 #define EFLAGS_VIP 0x00100000L 01321 #define EFLAGS_USER_SANITIZE 0x003e0dd7L 01322 01323 #define SANITIZE_FLAGS(eFlags, mode) (\ 01324 ((mode) == KernelMode ? \ 01325 ((0x00000000L) | ((eFlags) & 0x003e0fd7)) : \ 01326 ((((eFlags) & EFLAGS_V86_MASK) && KeI386VdmIoplAllowed) ? \ 01327 (((eFlags) & KeI386EFlagsAndMaskV86) | KeI386EFlagsOrMaskV86) : \ 01328 ((EFLAGS_INTERRUPT_MASK) | ((eFlags) & EFLAGS_USER_SANITIZE))))) 01329 01330 // 01331 // Masks for Dr7 and sanitize macros for various Dr registers. 01332 // 01333 01334 #define DR6_LEGAL 0x0000e00f 01335 01336 #define DR7_LEGAL 0xffff0155 // R/W, LEN for Dr0-Dr4, 01337 // Local enable for Dr0-Dr4, 01338 // Le for "perfect" trapping 01339 01340 #define DR7_ACTIVE 0x00000055 // If any of these bits are set, a Dr is active 01341 01342 #define SANITIZE_DR6(Dr6, mode) ((Dr6 & DR6_LEGAL)); 01343 01344 #define SANITIZE_DR7(Dr7, mode) ((Dr7 & DR7_LEGAL)); 01345 01346 #define SANITIZE_DRADDR(DrReg, mode) ( \ 01347 (mode) == KernelMode ? \ 01348 (DrReg) : \ 01349 (((PVOID)DrReg <= MM_HIGHEST_USER_ADDRESS) ? \ 01350 (DrReg) : \ 01351 (0) \ 01352 ) \ 01353 ) 01354 01355 // 01356 // Define macro to clear reserved bits from MXCSR so that we don't 01357 // GP fault when doing an FRSTOR 01358 // 01359 #define SANITIZE_MXCSR(_mxcsr_) ((_mxcsr_) & 0xFFBF) 01360 01361 // 01362 // Nonvolatile context pointers 01363 // 01364 // BUGBUG bryanwi 21 feb 90 - This is bogus. The 386 doesn't have 01365 // enough nonvolatile context to make this 01366 // structure worthwhile. Can't declare a 01367 // field to be void, so declare a Junk structure 01368 // instead. 01369 01370 typedef struct _KNONVOLATILE_CONTEXT_POINTERS { 01371 ULONG Junk; 01372 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; 01373 01374 // begin_nthal 01375 // 01376 // Trap frame 01377 // 01378 // NOTE - We deal only with 32bit registers, so the assembler equivalents 01379 // are always the extended forms. 01380 // 01381 // NOTE - Unless you want to run like slow molasses everywhere in the 01382 // the system, this structure must be of DWORD length, DWORD 01383 // aligned, and its elements must all be DWORD aligned. 01384 // 01385 // NOTE WELL - 01386 // 01387 // The i386 does not build stack frames in a consistent format, the 01388 // frames vary depending on whether or not a privilege transition 01389 // was involved. 01390 // 01391 // In order to make NtContinue work for both user mode and kernel 01392 // mode callers, we must force a canonical stack. 01393 // 01394 // If we're called from kernel mode, this structure is 8 bytes longer 01395 // than the actual frame! 01396 // 01397 // WARNING: 01398 // 01399 // KTRAP_FRAME_LENGTH needs to be 16byte integral (at present.) 01400 // 01401 01402 typedef struct _KTRAP_FRAME { 01403 01404 01405 // 01406 // Following 4 values are only used and defined for DBG systems, 01407 // but are always allocated to make switching from DBG to non-DBG 01408 // and back quicker. They are not DEVL because they have a non-0 01409 // performance impact. 01410 // 01411 01412 ULONG DbgEbp; // Copy of User EBP set up so KB will work. 01413 ULONG DbgEip; // EIP of caller to system call, again, for KB. 01414 ULONG DbgArgMark; // Marker to show no args here. 01415 ULONG DbgArgPointer; // Pointer to the actual args 01416 01417 // 01418 // Temporary values used when frames are edited. 01419 // 01420 // 01421 // NOTE: Any code that want's ESP must materialize it, since it 01422 // is not stored in the frame for kernel mode callers. 01423 // 01424 // And code that sets ESP in a KERNEL mode frame, must put 01425 // the new value in TempEsp, make sure that TempSegCs holds 01426 // the real SegCs value, and put a special marker value into SegCs. 01427 // 01428 01429 ULONG TempSegCs; 01430 ULONG TempEsp; 01431 01432 // 01433 // Debug registers. 01434 // 01435 01436 ULONG Dr0; 01437 ULONG Dr1; 01438 ULONG Dr2; 01439 ULONG Dr3; 01440 ULONG Dr6; 01441 ULONG Dr7; 01442 01443 // 01444 // Segment registers 01445 // 01446 01447 ULONG SegGs; 01448 ULONG SegEs; 01449 ULONG SegDs; 01450 01451 // 01452 // Volatile registers 01453 // 01454 01455 ULONG Edx; 01456 ULONG Ecx; 01457 ULONG Eax; 01458 01459 // 01460 // Nesting state, not part of context record 01461 // 01462 01463 ULONG PreviousPreviousMode; 01464 01465 PEXCEPTION_REGISTRATION_RECORD ExceptionList; 01466 // Trash if caller was user mode. 01467 // Saved exception list if caller 01468 // was kernel mode or we're in 01469 // an interrupt. 01470 01471 // 01472 // FS is TIB/PCR pointer, is here to make save sequence easy 01473 // 01474 01475 ULONG SegFs; 01476 01477 // 01478 // Non-volatile registers 01479 // 01480 01481 ULONG Edi; 01482 ULONG Esi; 01483 ULONG Ebx; 01484 ULONG Ebp; 01485 01486 // 01487 // Control registers 01488 // 01489 01490 ULONG ErrCode; 01491 ULONG Eip; 01492 ULONG SegCs; 01493 ULONG EFlags; 01494 01495 ULONG HardwareEsp; // WARNING - segSS:esp are only here for stacks 01496 ULONG HardwareSegSs; // that involve a ring transition. 01497 01498 ULONG V86Es; // these will be present for all transitions from 01499 ULONG V86Ds; // V86 mode 01500 ULONG V86Fs; 01501 ULONG V86Gs; 01502 } KTRAP_FRAME; 01503 01504 01505 typedef KTRAP_FRAME *PKTRAP_FRAME; 01506 typedef KTRAP_FRAME *PKEXCEPTION_FRAME; 01507 01508 #define KTRAP_FRAME_LENGTH (sizeof(KTRAP_FRAME)) 01509 #define KTRAP_FRAME_ALIGN (sizeof(ULONG)) 01510 #define KTRAP_FRAME_ROUND (KTRAP_FRAME_ALIGN-1) 01511 01512 // 01513 // Bits forced to 0 in SegCs if Esp has been edited. 01514 // 01515 01516 #define FRAME_EDITED 0xfff8 01517 01518 // end_nthal 01519 01520 // 01521 // The frame saved by KiCallUserMode is defined here to allow 01522 // the kernel debugger to trace the entire kernel stack 01523 // when usermode callouts are pending. 01524 // 01525 01526 typedef struct _KCALLOUT_FRAME { 01527 ULONG InStk; // saved initial stack address 01528 ULONG TrFr; // saved callback trap frame 01529 ULONG CbStk; // saved callback stack address 01530 ULONG Edi; // saved nonvolatile registers 01531 ULONG Esi; // 01532 ULONG Ebx; // 01533 ULONG Ebp; // 01534 ULONG Ret; // saved return address 01535 ULONG OutBf; // address to store output buffer 01536 ULONG OutLn; // address to store output length 01537 } KCALLOUT_FRAME; 01538 01539 typedef KCALLOUT_FRAME *PKCALLOUT_FRAME; 01540 01541 01542 // 01543 // BUGBUG shielint The second level vectors have not been defined. 01544 // 01545 01546 // #define MAXIMUM_VECTOR 0x20 // Maximum Interrupt Vector 01547 01548 01549 // 01550 // Switch Frame 01551 // 01552 // 386 doesn't have an "exception frame", and doesn't normally make 01553 // any use of nonvolatile context register structures. 01554 // 01555 // However, swapcontext in ctxswap.c and KeInitializeThread in 01556 // thredini.c need to share common stack structure used at thread 01557 // startup and switch time. 01558 // 01559 // This is that structure. 01560 // 01561 01562 typedef struct _KSWITCHFRAME { 01563 ULONG ExceptionList; 01564 ULONG Eflags; 01565 ULONG RetAddr; 01566 } KSWITCHFRAME, *PKSWITCHFRAME; 01567 01568 01569 // 01570 // Various 387 defines 01571 // 01572 01573 #define I386_80387_NP_VECTOR 0x07 // trap 7 when hardware not present 01574 01575 // begin_ntddk begin_wdm 01576 // 01577 // The non-volatile 387 state 01578 // 01579 01580 typedef struct _KFLOATING_SAVE { 01581 ULONG ControlWord; 01582 ULONG StatusWord; 01583 ULONG ErrorOffset; 01584 ULONG ErrorSelector; 01585 ULONG DataOffset; // Not used in wdm 01586 ULONG DataSelector; 01587 ULONG Cr0NpxState; 01588 ULONG Spare1; // Not used in wdm 01589 } KFLOATING_SAVE, *PKFLOATING_SAVE; 01590 01591 // end_ntddk end_wdm 01592 01593 // 01594 // i386 Profile values 01595 // 01596 01597 #define DEFAULT_PROFILE_INTERVAL 39063 01598 01599 // 01600 // The minimum acceptable profiling interval is set to 1221 which is the 01601 // fast RTC clock rate we can get. If this 01602 // value is too small, the system will run very slowly. 01603 // 01604 01605 #define MINIMUM_PROFILE_INTERVAL 1221 01606 01607 01608 // begin_ntddk begin_wdm begin_nthal begin_ntndis 01609 // 01610 // i386 Specific portions of mm component 01611 // 01612 01613 // 01614 // Define the page size for the Intel 386 as 4096 (0x1000). 01615 // 01616 01617 #define PAGE_SIZE 0x1000 01618 01619 // 01620 // Define the number of trailing zeroes in a page aligned virtual address. 01621 // This is used as the shift count when shifting virtual addresses to 01622 // virtual page numbers. 01623 // 01624 01625 #define PAGE_SHIFT 12L 01626 01627 // end_ntndis end_wdm 01628 // 01629 // Define the number of bits to shift to right justify the Page Directory Index 01630 // field of a PTE. 01631 // 01632 01633 #define PDI_SHIFT_X86 22 01634 #define PDI_SHIFT_X86PAE 21 01635 01636 #if !defined (_X86PAE_) 01637 #define PDI_SHIFT PDI_SHIFT_X86 01638 #else 01639 #define PDI_SHIFT PDI_SHIFT_X86PAE 01640 #define PPI_SHIFT 30 01641 #endif 01642 01643 // 01644 // Define the number of bits to shift to right justify the Page Table Index 01645 // field of a PTE. 01646 // 01647 01648 #define PTI_SHIFT 12 01649 01650 // 01651 // Define the highest user address and user probe address. 01652 // 01653 01654 // end_ntddk end_nthal 01655 01656 #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) 01657 01658 // begin_ntddk begin_nthal 01659 01660 extern PVOID *MmHighestUserAddress; 01661 extern PVOID *MmSystemRangeStart; 01662 extern ULONG *MmUserProbeAddress; 01663 01664 #define MM_HIGHEST_USER_ADDRESS *MmHighestUserAddress 01665 #define MM_SYSTEM_RANGE_START *MmSystemRangeStart 01666 #define MM_USER_PROBE_ADDRESS *MmUserProbeAddress 01667 01668 // end_ntddk end_nthal 01669 01670 #else 01671 01672 extern PVOID MmHighestUserAddress; 01673 extern PVOID MmSystemRangeStart; 01674 extern ULONG MmUserProbeAddress; 01675 01676 #define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress 01677 #define MM_SYSTEM_RANGE_START MmSystemRangeStart 01678 #define MM_USER_PROBE_ADDRESS MmUserProbeAddress 01679 01680 #endif 01681 01682 // begin_ntddk begin_nthal 01683 // 01684 // The lowest user address reserves the low 64k. 01685 // 01686 01687 #define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 01688 01689 // 01690 // The lowest address for system space. 01691 // 01692 01693 #if !defined (_X86PAE_) 01694 #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000 01695 #else 01696 #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 01697 #endif 01698 01699 // begin_wdm 01700 01701 #define MmGetProcedureAddress(Address) (Address) 01702 #define MmLockPagableCodeSection(Address) MmLockPagableDataSection(Address) 01703 01704 // end_ntddk end_wdm 01705 01706 // 01707 // Define the number of bits to shift to right justify the Page Directory Index 01708 // field of a PTE. 01709 // 01710 01711 #define PDI_SHIFT_X86 22 01712 #define PDI_SHIFT_X86PAE 21 01713 01714 #if !defined (_X86PAE_) 01715 #define PDI_SHIFT PDI_SHIFT_X86 01716 #else 01717 #define PDI_SHIFT PDI_SHIFT_X86PAE 01718 #define PPI_SHIFT 30 01719 #endif 01720 01721 // 01722 // Define the number of bits to shift to right justify the Page Table Index 01723 // field of a PTE. 01724 // 01725 01726 #define PTI_SHIFT 12 01727 01728 // 01729 // Define page directory and page base addresses. 01730 // 01731 01732 #define PDE_BASE_X86 0xc0300000 01733 #define PDE_BASE_X86PAE 0xc0600000 01734 01735 #if !defined (_X86PAE_) 01736 #define PDE_BASE PDE_BASE_X86 01737 #else 01738 #define PDE_BASE PDE_BASE_X86PAE 01739 #endif 01740 #define PTE_BASE 0xc0000000 01741 01742 // end_nthal 01743 01744 // 01745 // Define virtual base and alternate virtual base of kernel. 01746 // 01747 01748 #define KSEG0_BASE 0x80000000 01749 #define ALTERNATE_BASE (0xe1000000 - 64 * 1024 * 1024) 01750 01751 // 01752 // Define macro to initialize directory table base. 01753 // 01754 01755 #define INITIALIZE_DIRECTORY_TABLE_BASE(dirbase,pfn) \ 01756 *((PULONG)(dirbase)) = ((pfn) << PAGE_SHIFT) 01757 01758 01759 // begin_nthal 01760 // 01761 // Location of primary PCR (used only for UP kernel & hal code) 01762 // 01763 01764 // addressed from 0xffdf0000 - 0xffdfffff are reserved for the system 01765 // (ie, not for use by the hal) 01766 01767 #define KI_BEGIN_KERNEL_RESERVED 0xffdf0000 01768 #define KIP0PCRADDRESS 0xffdff000 01769 01770 // begin_ntddk 01771 01772 #define KI_USER_SHARED_DATA 0xffdf0000 01773 #define SharedUserData ((KUSER_SHARED_DATA * const) KI_USER_SHARED_DATA) 01774 01775 // 01776 // Result type definition for i386. (Machine specific enumerate type 01777 // which is return type for portable exinterlockedincrement/decrement 01778 // procedures.) In general, you should use the enumerated type defined 01779 // in ex.h instead of directly referencing these constants. 01780 // 01781 01782 // Flags loaded into AH by LAHF instruction 01783 01784 #define EFLAG_SIGN 0x8000 01785 #define EFLAG_ZERO 0x4000 01786 #define EFLAG_SELECT (EFLAG_SIGN | EFLAG_ZERO) 01787 01788 #define RESULT_NEGATIVE ((EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) 01789 #define RESULT_ZERO ((~EFLAG_SIGN & EFLAG_ZERO) & EFLAG_SELECT) 01790 #define RESULT_POSITIVE ((~EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) 01791 01792 // 01793 // Convert various portable ExInterlock APIs into their architectural 01794 // equivalents. 01795 // 01796 01797 #define ExInterlockedIncrementLong(Addend,Lock) \ 01798 Exfi386InterlockedIncrementLong(Addend) 01799 01800 #define ExInterlockedDecrementLong(Addend,Lock) \ 01801 Exfi386InterlockedDecrementLong(Addend) 01802 01803 #define ExInterlockedExchangeUlong(Target,Value,Lock) \ 01804 Exfi386InterlockedExchangeUlong(Target,Value) 01805 01806 // begin_wdm 01807 01808 #define ExInterlockedAddUlong ExfInterlockedAddUlong 01809 #define ExInterlockedInsertHeadList ExfInterlockedInsertHeadList 01810 #define ExInterlockedInsertTailList ExfInterlockedInsertTailList 01811 #define ExInterlockedRemoveHeadList ExfInterlockedRemoveHeadList 01812 #define ExInterlockedPopEntryList ExfInterlockedPopEntryList 01813 #define ExInterlockedPushEntryList ExfInterlockedPushEntryList 01814 01815 // end_wdm 01816 01817 // 01818 // Prototypes for architectural specific versions of Exi386 Api 01819 // 01820 01821 // 01822 // Interlocked result type is portable, but its values are machine specific. 01823 // Constants for value are in i386.h, mips.h, etc. 01824 // 01825 01826 typedef enum _INTERLOCKED_RESULT { 01827 ResultNegative = RESULT_NEGATIVE, 01828 ResultZero = RESULT_ZERO, 01829 ResultPositive = RESULT_POSITIVE 01830 } INTERLOCKED_RESULT; 01831 01832 NTKERNELAPI 01833 INTERLOCKED_RESULT 01834 FASTCALL 01835 Exfi386InterlockedIncrementLong ( 01836 IN PLONG Addend 01837 ); 01838 01839 NTKERNELAPI 01840 INTERLOCKED_RESULT 01841 FASTCALL 01842 Exfi386InterlockedDecrementLong ( 01843 IN PLONG Addend 01844 ); 01845 01846 NTKERNELAPI 01847 LARGE_INTEGER 01848 ExInterlockedExchangeAddLargeInteger ( 01849 IN PLARGE_INTEGER Addend, 01850 IN LARGE_INTEGER Increment, 01851 IN PKSPIN_LOCK Lock 01852 ); 01853 01854 NTKERNELAPI 01855 ULONG 01856 FASTCALL 01857 Exfi386InterlockedExchangeUlong ( 01858 IN PULONG Target, 01859 IN ULONG Value 01860 ); 01861 01862 // 01863 // Intrinsic interlocked functions 01864 // 01865 01866 #if (defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) || defined(NO_INTERLOCKED_INTRINSICS)) && !defined(_WINBASE_) 01867 01868 // begin_wdm 01869 01870 NTKERNELAPI 01871 LONG 01872 FASTCALL 01873 InterlockedIncrement( 01874 IN PLONG Addend 01875 ); 01876 01877 NTKERNELAPI 01878 LONG 01879 FASTCALL 01880 InterlockedDecrement( 01881 IN PLONG Addend 01882 ); 01883 01884 NTKERNELAPI 01885 LONG 01886 FASTCALL 01887 InterlockedExchange( 01888 IN OUT PLONG Target, 01889 IN LONG Value 01890 ); 01891 01892 #define InterlockedExchangePointer(Target, Value) \ 01893 (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value)) 01894 01895 LONG 01896 FASTCALL 01897 InterlockedExchangeAdd( 01898 IN OUT PLONG Addend, 01899 IN LONG Increment 01900 ); 01901 01902 NTKERNELAPI 01903 LONG 01904 FASTCALL 01905 InterlockedCompareExchange( 01906 IN OUT PLONG Destination, 01907 IN LONG ExChange, 01908 IN LONG Comperand 01909 ); 01910 01911 #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \ 01912 (PVOID)InterlockedCompareExchange((PLONG)Destination, (LONG)ExChange, (LONG)Comperand) 01913 01914 // end_wdm 01915 01916 #endif 01917 01918 // end_ntddk end_nthal 01919 01920 // 01921 // UP/MP versions of interlocked intrinsics for use within ntoskrnl.exe. 01922 // 01923 // N.B. FASTCALL does NOT work with inline functions. 01924 // 01925 01926 #if !defined(_NTDDK_) && !defined(_NTIFS_) && !defined(_NTHAL_) && !defined(_WINBASE_) 01927 #if defined(_M_IX86) && !defined(_CROSS_PLATFORM_) 01928 01929 #pragma warning(disable:4035) // wdm re-enable below 01930 01931 #if !defined(MIDL_PASS) // wdm 01932 01933 #if !defined(NO_INTERLOCKED_INTRINSICS) 01934 #if defined(NT_UP) 01935 01936 __inline 01937 LONG 01938 FASTCALL 01939 InterlockedIncrement( 01940 IN PLONG Addend 01941 ) 01942 { 01943 __asm { 01944 mov eax, 1 01945 mov ecx, Addend 01946 xadd [ecx], eax 01947 inc eax 01948 } 01949 } 01950 01951 __inline 01952 LONG 01953 FASTCALL 01954 InterlockedDecrement( 01955 IN PLONG Addend 01956 ) 01957 { 01958 __asm { 01959 mov eax, -1 01960 mov ecx, Addend 01961 xadd [ecx], eax 01962 dec eax 01963 } 01964 } 01965 01966 __inline 01967 LONG 01968 FASTCALL 01969 InterlockedExchange( 01970 IN OUT PLONG Target, 01971 IN LONG Value 01972 ) 01973 { 01974 __asm { 01975 mov edx, Value 01976 mov ecx, Target 01977 mov eax, [ecx] 01978 ie: cmpxchg [ecx], edx 01979 jnz short ie 01980 } 01981 } 01982 01983 #define InterlockedExchangePointer(Target, Value) \ 01984 (PVOID)InterlockedExchange((PLONG)Target, (LONG)Value) 01985 01986 __inline 01987 LONG 01988 FASTCALL 01989 InterlockedExchangeAdd( 01990 IN OUT PLONG Addend, 01991 IN LONG Increment 01992 ) 01993 { 01994 __asm { 01995 mov eax, Increment 01996 mov ecx, Addend 01997 xadd [ecx], eax 01998 } 01999 } 02000 02001 __inline 02002 LONG 02003 FASTCALL 02004 InterlockedCompareExchange( 02005 IN OUT PLONG Destination, 02006 IN LONG Exchange, 02007 IN LONG Comperand 02008 ) 02009 { 02010 __asm { 02011 mov eax, Comperand 02012 mov ecx, Destination 02013 mov edx, Exchange 02014 cmpxchg [ecx], edx 02015 } 02016 } 02017 02018 #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \ 02019 (PVOID)InterlockedCompareExchange((PLONG)Destination, (LONG)ExChange, (LONG)Comperand) 02020 02021 #else 02022 02023 __inline 02024 LONG 02025 FASTCALL 02026 InterlockedIncrement( 02027 IN PLONG Addend 02028 ) 02029 { 02030 __asm { 02031 mov eax, 1 02032 mov ecx, Addend 02033 lock xadd [ecx], eax 02034 inc eax 02035 } 02036 } 02037 02038 __inline 02039 LONG 02040 FASTCALL 02041 InterlockedDecrement( 02042 IN PLONG Addend 02043 ) 02044 { 02045 __asm { 02046 mov eax, -1 02047 mov ecx, Addend 02048 lock xadd [ecx], eax 02049 dec eax 02050 } 02051 } 02052 02053 __inline 02054 LONG 02055 FASTCALL 02056 InterlockedExchange( 02057 IN OUT PLONG Target, 02058 IN LONG Value 02059 ) 02060 { 02061 __asm { 02062 mov eax, Value 02063 mov ecx, Target 02064 xchg [ecx], eax 02065 } 02066 } 02067 02068 #define InterlockedExchangePointer(Target, Value) \ 02069 (PVOID)InterlockedExchange((PLONG)Target, (LONG)Value) 02070 02071 // begin_wdm 02072 02073 __inline 02074 LONG 02075 FASTCALL 02076 InterlockedExchangeAdd( 02077 IN OUT PLONG Addend, 02078 IN LONG Increment 02079 ) 02080 { 02081 __asm { 02082 mov eax, Increment 02083 mov ecx, Addend 02084 lock xadd [ecx], eax 02085 } 02086 } 02087 02088 02089 // end_wdm 02090 02091 __inline 02092 LONG 02093 FASTCALL 02094 InterlockedCompareExchange( 02095 IN OUT PLONG Destination, 02096 IN LONG Exchange, 02097 IN LONG Comperand 02098 ) 02099 { 02100 __asm { 02101 mov eax, Comperand 02102 mov ecx, Destination 02103 mov edx, Exchange 02104 lock cmpxchg [ecx], edx 02105 } 02106 } 02107 02108 #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \ 02109 (PVOID)InterlockedCompareExchange((PLONG)Destination, (LONG)ExChange, (LONG)Comperand) 02110 02111 #endif // wdm 02112 #endif 02113 #endif 02114 02115 #pragma warning(default:4035) // wdm 02116 02117 #endif 02118 #endif 02119 02120 // 02121 // Structure for Ldt information in x86 processes 02122 // 02123 02124 typedef struct _LDTINFORMATION { 02125 ULONG Size; 02126 ULONG AllocatedSize; 02127 PLDT_ENTRY Ldt; 02128 } LDTINFORMATION, *PLDTINFORMATION; 02129 02130 // 02131 // SetProcessInformation Structure for ProcessSetIoHandlers info class 02132 // 02133 02134 typedef struct _PROCESS_IO_PORT_HANDLER_INFORMATION { 02135 BOOLEAN Install; // true if handlers to be installed 02136 ULONG NumEntries; 02137 ULONG Context; 02138 PEMULATOR_ACCESS_ENTRY EmulatorAccessEntries; 02139 } PROCESS_IO_PORT_HANDLER_INFORMATION, *PPROCESS_IO_PORT_HANDLER_INFORMATION; 02140 02141 02142 // 02143 // Vdm Objects and Io handling structure 02144 // 02145 02146 typedef struct _VDM_IO_HANDLER_FUNCTIONS { 02147 PDRIVER_IO_PORT_ULONG UlongIo; 02148 PDRIVER_IO_PORT_ULONG_STRING UlongStringIo; 02149 PDRIVER_IO_PORT_USHORT UshortIo[2]; 02150 PDRIVER_IO_PORT_USHORT_STRING UshortStringIo[2]; 02151 PDRIVER_IO_PORT_UCHAR UcharIo[4]; 02152 PDRIVER_IO_PORT_UCHAR_STRING UcharStringIo[4]; 02153 } VDM_IO_HANDLER_FUNCTIONS, *PVDM_IO_HANDLER_FUNCTIONS; 02154 02155 typedef struct _VDM_IO_HANDLER { 02156 struct _VDM_IO_HANDLER *Next; 02157 ULONG PortNumber; 02158 VDM_IO_HANDLER_FUNCTIONS IoFunctions[2]; 02159 } VDM_IO_HANDLER, *PVDM_IO_HANDLER; 02160 02161 02162 02163 // begin_nthal begin_ntddk begin_wdm 02164 02165 #if !defined(MIDL_PASS) && defined(_M_IX86) 02166 02167 // 02168 // i386 function definitions 02169 // 02170 02171 #pragma warning(disable:4035) // re-enable below 02172 02173 // end_ntddk end_wdm 02174 02175 #if NT_UP 02176 #define _PCR ds:[KIP0PCRADDRESS] 02177 #else 02178 #define _PCR fs:[0] // ntddk 02179 #endif 02180 02181 // 02182 // Get address of current processor block. 02183 // 02184 // WARNING: This inline macro can only be used by the kernel or hal 02185 // 02186 #define KiPcr() KeGetPcr() 02187 __inline PKPCR KeGetPcr(VOID) 02188 { 02189 #if NT_UP 02190 __asm { mov eax, KIP0PCRADDRESS } 02191 #else 02192 __asm { mov eax, _PCR KPCR.SelfPcr } 02193 #endif 02194 } 02195 02196 // 02197 // Get address of current processor block. 02198 // 02199 // WARNING: This inline macro can only be used by the kernel or hal 02200 // 02201 __inline PKPRCB KeGetCurrentPrcb (VOID) 02202 { 02203 __asm { mov eax, _PCR KPCR.Prcb } 02204 } 02205 02206 // begin_ntddk begin_wdm 02207 02208 // 02209 // Get current IRQL. 02210 // 02211 // On x86 this function resides in the HAL 02212 // 02213 02214 NTHALAPI 02215 KIRQL 02216 KeGetCurrentIrql(); 02217 02218 // end_wdm 02219 // 02220 // Get the current processor number 02221 // 02222 02223 __inline ULONG KeGetCurrentProcessorNumber(VOID) 02224 { 02225 __asm { movzx eax, _PCR KPCR.Number } 02226 } 02227 02228 // end_nthal end_ntddk 02229 // 02230 // Get address of current kernel thread object. 02231 // 02232 // WARNING: This inline macro can not be used for device drivers or HALs 02233 // they must call the kernel function KeGetCurrentThread. 02234 // WARNING: This inline macro is always MP enabled because filesystems 02235 // utilize it 02236 // 02237 __inline struct _KTHREAD *KeGetCurrentThread (VOID) 02238 { 02239 __asm { mov eax, fs:[0] KPCR.PrcbData.CurrentThread } 02240 } 02241 02242 // 02243 // If processor executing DPC? 02244 // WARNING: This inline macro is always MP enabled because filesystems 02245 // utilize it 02246 // 02247 __inline ULONG KeIsExecutingDpc(VOID) 02248 { 02249 __asm { mov eax, fs:[0] KPCR.PrcbData.DpcRoutineActive } 02250 } 02251 02252 // begin_nthal begin_ntddk begin_wdm 02253 02254 #endif // !defined(MIDL_PASS) && defined(_M_IX86) 02255 02256 // end_nthal end_ntddk end_wdm 02257 02258 // 02259 // Get previous processor mode. 02260 // 02261 // WARNING: This inline macro can not be used for device drivers or HALs 02262 // 02263 // KPROCESSOR_MODE 02264 // KeGetPreviousMode(); 02265 #define KeGetPreviousMode() (KeGetCurrentThread()->PreviousMode) 02266 02267 // begin_nthal 02268 // 02269 // Macro to set address of a trap/interrupt handler to IDT 02270 // 02271 #define KiSetHandlerAddressToIDT(Vector, HandlerAddress) \ 02272 KeGetPcr()->IDT[Vector].ExtendedOffset = HIGHWORD(HandlerAddress); \ 02273 KeGetPcr()->IDT[Vector].Offset = LOWWORD(HandlerAddress); 02274 02275 // 02276 // Macro to return address of a trap/interrupt handler in IDT 02277 // 02278 #define KiReturnHandlerAddressFromIDT(Vector) \ 02279 MAKEULONG(KiPcr()->IDT[Vector].ExtendedOffset, KiPcr()->IDT[Vector].Offset) 02280 02281 #pragma warning(default:4035) 02282 // end_nthal 02283 02284 //++ 02285 // 02286 // BOOLEAN 02287 // KiIsThreadNumericStateSaved( 02288 // IN PKTHREAD Address 02289 // ) 02290 // 02291 //-- 02292 #define KiIsThreadNumericStateSaved(a) \ 02293 (a->NpxState != NPX_STATE_LOADED) 02294 02295 //++ 02296 // 02297 // VOID 02298 // KiRundownThread( 02299 // IN PKTHREAD Address 02300 // ) 02301 // 02302 //-- 02303 02304 #if defined(NT_UP) 02305 02306 // 02307 // On UP x86 systems, FP state is lazy saved and loaded. If this 02308 // thread owns the current FP context, clear the ownership field 02309 // so we will not try to save to this thread after it has been 02310 // terminated. 02311 // 02312 02313 #define KiRundownThread(a) \ 02314 if (KeGetCurrentPrcb()->NpxThread == (a)) { \ 02315 KeGetCurrentPrcb()->NpxThread = NULL; \ 02316 } 02317 02318 #else 02319 02320 #define KiRundownThread(a) 02321 02322 #endif 02323 02324 // 02325 // functions specific to 386 structure 02326 // 02327 02328 VOID 02329 KiSetIRR ( 02330 IN ULONG SWInterruptMask 02331 ); 02332 02333 VOID 02334 KiInitializeGDT ( 02335 IN OUT PKGDTENTRY Gdt, 02336 IN USHORT GdtLimit, 02337 IN PKPCR Pcr, 02338 IN USHORT PcrLimit, 02339 IN PKTSS Tss, 02340 IN USHORT TssLimit, 02341 IN USHORT TebLimit 02342 ); 02343 02344 VOID 02345 KiInitializeGdtEntry ( 02346 OUT PKGDTENTRY GdtEntry, 02347 IN ULONG Base, 02348 IN ULONG Limit, 02349 IN USHORT Type, 02350 IN USHORT Dpl, 02351 IN USHORT Granularity 02352 ); 02353 02354 // 02355 // Procedures to support frame manipulation 02356 // 02357 02358 ULONG 02359 KiEspFromTrapFrame( 02360 IN PKTRAP_FRAME TrapFrame 02361 ); 02362 02363 VOID 02364 KiEspToTrapFrame( 02365 IN PKTRAP_FRAME TrapFrame, 02366 IN ULONG Esp 02367 ); 02368 02369 ULONG 02370 KiSegSsFromTrapFrame( 02371 IN PKTRAP_FRAME TrapFrame 02372 ); 02373 02374 VOID 02375 KiSegSsToTrapFrame( 02376 IN PKTRAP_FRAME TrapFrame, 02377 IN ULONG SegSs 02378 ); 02379 02380 // 02381 // Define prototypes for i386 specific clock and profile interrupt routines. 02382 // 02383 02384 VOID 02385 KiUpdateRunTime ( 02386 VOID 02387 ); 02388 02389 VOID 02390 KiUpdateSystemTime ( 02391 VOID 02392 ); 02393 02394 // begin_ntddk begin_wdm 02395 02396 NTKERNELAPI 02397 NTSTATUS 02398 NTAPI 02399 KeSaveFloatingPointState ( 02400 OUT PKFLOATING_SAVE FloatSave 02401 ); 02402 02403 NTKERNELAPI 02404 NTSTATUS 02405 NTAPI 02406 KeRestoreFloatingPointState ( 02407 IN PKFLOATING_SAVE FloatSave 02408 ); 02409 02410 // end_ntddk end_wdm 02411 // begin_nthal 02412 02413 VOID 02414 KeProfileInterrupt ( 02415 IN KIRQL OldIrql, 02416 IN KTRAP_FRAME TrapFrame 02417 ); 02418 02419 NTKERNELAPI 02420 VOID 02421 KeProfileInterruptWithSource ( 02422 IN struct _KTRAP_FRAME *TrapFrame, 02423 IN KPROFILE_SOURCE ProfileSource 02424 ); 02425 02426 VOID 02427 KeUpdateRuntime ( 02428 IN KIRQL OldIrql, 02429 IN KTRAP_FRAME TrapFrame 02430 ); 02431 02432 VOID 02433 KeUpdateSystemTime ( 02434 IN KIRQL OldIrql, 02435 IN KTRAP_FRAME TrapFrame 02436 ); 02437 02438 // begin_ntddk begin_wdm begin_ntndis 02439 02440 #endif // defined(_X86_) 02441 02442 // end_nthal end_ntddk end_wdm end_ntndis 02443 02444 // begin_nthal begin_ntddk 02445 02446 // Use the following for kernel mode runtime checks of X86 system architecture 02447 02448 #ifdef _X86_ 02449 02450 #ifdef IsNEC_98 02451 #undef IsNEC_98 02452 #endif 02453 02454 #ifdef IsNotNEC_98 02455 #undef IsNotNEC_98 02456 #endif 02457 02458 #ifdef SetNEC_98 02459 #undef SetNEC_98 02460 #endif 02461 02462 #ifdef SetNotNEC_98 02463 #undef SetNotNEC_98 02464 #endif 02465 02466 #define IsNEC_98 (SharedUserData->AlternativeArchitecture == NEC98x86) 02467 #define IsNotNEC_98 (SharedUserData->AlternativeArchitecture != NEC98x86) 02468 #define SetNEC_98 SharedUserData->AlternativeArchitecture = NEC98x86 02469 #define SetNotNEC_98 SharedUserData->AlternativeArchitecture = StandardDesign 02470 02471 #endif 02472 02473 // end_nthal end_ntddk 02474 02475 // 02476 // i386 arch. specific kernel functions. 02477 // 02478 02479 VOID 02480 Ke386SetLdtProcess ( 02481 struct _KPROCESS *Process, 02482 PLDT_ENTRY Ldt, 02483 ULONG Limit 02484 ); 02485 02486 VOID 02487 Ke386SetDescriptorProcess ( 02488 struct _KPROCESS *Process, 02489 ULONG Offset, 02490 LDT_ENTRY LdtEntry 02491 ); 02492 02493 VOID 02494 Ke386GetGdtEntryThread ( 02495 struct _KTHREAD *Thread, 02496 ULONG Offset, 02497 PKGDTENTRY Descriptor 02498 ); 02499 02500 BOOLEAN 02501 Ke386SetIoAccessMap ( 02502 ULONG MapNumber, 02503 PKIO_ACCESS_MAP IoAccessMap 02504 ); 02505 02506 BOOLEAN 02507 Ke386QueryIoAccessMap ( 02508 ULONG MapNumber, 02509 PKIO_ACCESS_MAP IoAccessMap 02510 ); 02511 02512 BOOLEAN 02513 Ke386IoSetAccessProcess ( 02514 struct _KPROCESS *Process, 02515 ULONG MapNumber 02516 ); 02517 02518 VOID 02519 Ke386SetIOPL( 02520 struct _KPROCESS *Process 02521 ); 02522 02523 NTSTATUS 02524 Ke386CallBios ( 02525 IN ULONG BiosCommand, 02526 IN OUT PCONTEXT BiosArguments 02527 ); 02528 02529 VOID 02530 KiEditIopmDpc ( 02531 IN struct _KDPC *Dpc, 02532 IN PVOID DeferredContext, 02533 IN PVOID SystemArgument1, 02534 IN PVOID SystemArgument2 02535 ); 02536 02537 BOOLEAN 02538 Ki386GetSelectorParameters( 02539 IN USHORT Selector, 02540 OUT PULONG Flags, 02541 OUT PULONG Base, 02542 OUT PULONG Limit 02543 ); 02544 02545 NTSTATUS 02546 Ke386SetVdmInterruptHandler ( 02547 IN struct _KPROCESS *Process, 02548 IN ULONG Interrupt, 02549 IN USHORT Selector, 02550 IN ULONG Offset, 02551 IN BOOLEAN Gate32 02552 ); 02553 02554 // 02555 // i386 ABIOS specific routines. 02556 // 02557 02558 NTSTATUS 02559 KeI386GetLid( 02560 IN USHORT DeviceId, 02561 IN USHORT RelativeLid, 02562 IN BOOLEAN SharedLid, 02563 IN struct _DRIVER_OBJECT *DeviceObject, 02564 OUT PUSHORT LogicalId 02565 ); 02566 02567 NTSTATUS 02568 KeI386ReleaseLid( 02569 IN USHORT LogicalId, 02570 IN struct _DRIVER_OBJECT *DeviceObject 02571 ); 02572 02573 NTSTATUS 02574 KeI386AbiosCall( 02575 IN USHORT LogicalId, 02576 IN struct _DRIVER_OBJECT *DriverObject, 02577 IN PUCHAR RequestBlock, 02578 IN USHORT EntryPoint 02579 ); 02580 02581 // 02582 // i386 misc routines 02583 // 02584 NTSTATUS 02585 KeI386AllocateGdtSelectors( 02586 OUT PUSHORT SelectorArray, 02587 IN USHORT NumberOfSelectors 02588 ); 02589 02590 VOID 02591 KeI386Call16BitFunction ( 02592 IN OUT PCONTEXT Regs 02593 ); 02594 02595 USHORT 02596 KeI386Call16BitCStyleFunction ( 02597 IN ULONG EntryOffset, 02598 IN ULONG EntrySelector, 02599 IN PUCHAR Parameters, 02600 IN ULONG Size 02601 ); 02602 02603 NTSTATUS 02604 KeI386FlatToGdtSelector( 02605 IN ULONG SelectorBase, 02606 IN USHORT Length, 02607 IN USHORT Selector 02608 ); 02609 02610 NTSTATUS 02611 KeI386ReleaseGdtSelectors( 02612 OUT PUSHORT SelectorArray, 02613 IN USHORT NumberOfSelectors 02614 ); 02615 02616 NTSTATUS 02617 KeI386SetGdtSelector ( 02618 ULONG Selector, 02619 PKGDTENTRY GdtValue 02620 ); 02621 02622 02623 VOID 02624 KeOptimizeProcessorControlState ( 02625 VOID 02626 ); 02627 02628 // 02629 // i386 Vdm specific functions 02630 // 02631 BOOLEAN 02632 Ke386VdmInsertQueueApc ( 02633 IN PKAPC Apc, 02634 IN struct _KTHREAD *Thread, 02635 IN KPROCESSOR_MODE ApcMode, 02636 IN PKKERNEL_ROUTINE KernelRoutine, 02637 IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, 02638 IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL, 02639 IN PVOID NormalContext OPTIONAL, 02640 IN KPRIORITY Increment 02641 ); 02642 02643 VOID 02644 Ke386VdmClearApcObject ( 02645 IN PKAPC Apc 02646 ); 02647 02648 VOID 02649 KeI386VdmInitialize ( 02650 VOID 02651 ); 02652 02653 // 02654 // x86 functions for special instructions 02655 // 02656 02657 VOID 02658 CPUID ( 02659 ULONG InEax, 02660 PULONG OutEax, 02661 PULONG OutEbx, 02662 PULONG OutEcx, 02663 PULONG OutEdx 02664 ); 02665 02666 LONGLONG 02667 RDTSC ( 02668 VOID 02669 ); 02670 02671 ULONGLONG 02672 FASTCALL 02673 RDMSR ( 02674 IN ULONG MsrRegister 02675 ); 02676 02677 VOID 02678 WRMSR ( 02679 IN ULONG MsrRegister, 02680 IN ULONGLONG MsrValue 02681 ); 02682 02683 // 02684 // i386 Vdm specific data 02685 // 02686 extern ULONG KeI386EFlagsAndMaskV86; 02687 extern ULONG KeI386EFlagsOrMaskV86; 02688 extern BOOLEAN KeI386VdmIoplAllowed; 02689 extern ULONG KeI386VirtualIntExtensions; 02690 02691 02692 extern ULONG KeI386CpuType; 02693 extern ULONG KeI386CpuStep; 02694 extern BOOLEAN KeI386NpxPresent; 02695 extern BOOLEAN KeI386FxsrPresent; 02696 02697 02698 // 02699 // i386 Feature bit definitions 02700 // 02701 02702 #define KF_V86_VIS 0x00000001 02703 #define KF_RDTSC 0x00000002 02704 #define KF_CR4 0x00000004 02705 #define KF_CMOV 0x00000008 02706 #define KF_GLOBAL_PAGE 0x00000010 02707 #define KF_LARGE_PAGE 0x00000020 02708 #define KF_MTRR 0x00000040 02709 #define KF_CMPXCHG8B 0x00000080 02710 #define KF_MMX 0x00000100 02711 #define KF_WORKING_PTE 0x00000200 02712 #define KF_PAT 0x00000400 02713 #define KF_FXSR 0x00000800 02714 #define KF_FAST_SYSCALL 0x00001000 02715 #define KF_XMMI 0x00002000 02716 #define KF_3DNOW 0x00004000 02717 #define KF_AMDK6MTRR 0x00008000 02718 02719 // 02720 // Define macro to test if x86 feature is present. 02721 // 02722 02723 extern ULONG KiBootFeatureBits; 02724 02725 #define Isx86FeaturePresent(_f_) ((KiBootFeatureBits & (_f_)) != 0) 02726 02727 #endif // _i386_

Generated on Sat May 15 19:40:18 2004 for test by doxygen 1.3.7