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

ppc.h

Go to the documentation of this file.
00001 /*++ BUILD Version: 0018 // Increment this if a change has global effects 00002 00003 Copyright (c) 1993 IBM Corporation 00004 00005 Module Name: 00006 00007 ppc.h 00008 00009 Abstract: 00010 00011 This module contains the PowerPC hardware specific header file. 00012 00013 Author: 00014 00015 Rick Simpson 9-Jul-1993 00016 00017 Based on mips.h, by David N. Cutler (davec) 31-Mar-1990 00018 00019 Revision History: 00020 00021 --*/ 00022 00023 #ifndef _PPCH_ 00024 #define _PPCH_ 00025 00026 // begin_ntddk begin_wdm begin_nthal begin_ntndis 00027 00028 #if defined(_PPC_) 00029 00030 // 00031 // Define maximum size of flush multple TB request. 00032 // 00033 00034 #define FLUSH_MULTIPLE_MAXIMUM 48 00035 00036 // 00037 // Indicate that the compiler (with MIPS front-end) supports 00038 // the pragma textout construct. 00039 // 00040 00041 #define ALLOC_PRAGMA 1 00042 00043 // 00044 // Define function decoration depending on whether a driver, a file system, 00045 // or a kernel component is being built. 00046 // 00047 00048 // end_wdm 00049 00050 #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) 00051 00052 #define NTKERNELAPI DECLSPEC_IMPORT // wdm 00053 00054 #else 00055 00056 #define NTKERNELAPI 00057 00058 #endif 00059 00060 // 00061 // Define function decoration depending on whether the HAL or other kernel 00062 // component is being build. 00063 // 00064 00065 #if !defined(_NTHAL_) 00066 00067 #define NTHALAPI DECLSPEC_IMPORT // wdm 00068 00069 #else 00070 00071 #define NTHALAPI 00072 00073 #endif 00074 00075 // end_ntndis 00076 // 00077 // Define macro to generate import names. 00078 // 00079 00080 #define IMPORT_NAME(name) __imp_##name 00081 00082 // 00083 // PowerPC specific interlocked operation result values. 00084 // 00085 // These are the values used on MIPS; there appears to be no 00086 // need to change them for PowerPC. 00087 // 00088 00089 #define RESULT_ZERO 0 00090 #define RESULT_NEGATIVE -2 00091 #define RESULT_POSITIVE -1 00092 00093 // 00094 // Interlocked result type is portable, but its values are machine specific. 00095 // Constants for value are in i386.h, mips.h, ppc.h, etc. 00096 // 00097 00098 typedef enum _INTERLOCKED_RESULT { 00099 ResultNegative = RESULT_NEGATIVE, 00100 ResultZero = RESULT_ZERO, 00101 ResultPositive = RESULT_POSITIVE 00102 } INTERLOCKED_RESULT; 00103 00104 00105 // 00106 // Convert portable interlock interfaces to architecure specific interfaces. 00107 // 00108 00109 #define ExInterlockedIncrementLong(Addend, Lock) \ 00110 ExPpcInterlockedIncrementLong(Addend) 00111 00112 #define ExInterlockedDecrementLong(Addend, Lock) \ 00113 ExPpcInterlockedDecrementLong(Addend) 00114 00115 #define ExInterlockedExchangeUlong(Target, Value, Lock) \ 00116 ExPpcInterlockedExchangeUlong(Target, Value) 00117 00118 NTKERNELAPI 00119 INTERLOCKED_RESULT 00120 ExPpcInterlockedIncrementLong ( 00121 IN PLONG Addend 00122 ); 00123 00124 NTKERNELAPI 00125 INTERLOCKED_RESULT 00126 ExPpcInterlockedDecrementLong ( 00127 IN PLONG Addend 00128 ); 00129 00130 NTKERNELAPI 00131 LARGE_INTEGER 00132 ExInterlockedExchangeAddLargeInteger ( 00133 IN PLARGE_INTEGER Addend, 00134 IN LARGE_INTEGER Increment, 00135 IN PKSPIN_LOCK Lock 00136 ); 00137 00138 NTKERNELAPI 00139 ULONG 00140 ExPpcInterlockedExchangeUlong ( 00141 IN PULONG Target, 00142 IN ULONG Value 00143 ); 00144 00145 // begin_wdm 00146 00147 // 00148 // Intrinsic interlocked functions 00149 // 00150 00151 #if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000) && !defined(RC_INVOKED) 00152 00153 #define InterlockedIncrement _InterlockedIncrement 00154 #define InterlockedDecrement _InterlockedDecrement 00155 #define InterlockedExchange _InterlockedExchange 00156 #define InterlockedExchangeAdd _InterlockedExchangeAdd 00157 #define InterlockedCompareExchange _InterlockedCompareExchange 00158 00159 LONG 00160 InterlockedIncrement( 00161 IN OUT PLONG Addend 00162 ); 00163 00164 LONG 00165 InterlockedDecrement( 00166 IN OUT PLONG Addend 00167 ); 00168 00169 LONG 00170 InterlockedExchange( 00171 IN OUT PLONG Target, 00172 IN LONG Increment 00173 ); 00174 00175 LONG 00176 InterlockedExchangeAdd( 00177 IN OUT PLONG Addend, 00178 IN LONG Value 00179 ); 00180 00181 PVOID 00182 InterlockedCompareExchange ( 00183 IN OUT PVOID *Destination, 00184 IN PVOID Exchange, 00185 IN PVOID Comperand 00186 ); 00187 00188 #pragma intrinsic(_InterlockedIncrement) 00189 #pragma intrinsic(_InterlockedDecrement) 00190 #pragma intrinsic(_InterlockedExchange) 00191 #pragma intrinsic(_InterlockedExchangeAdd) 00192 #pragma intrinsic(_InterlockedCompareExchange) 00193 00194 #else 00195 00196 NTKERNELAPI 00197 LONG 00198 InterlockedIncrement( 00199 IN OUT PLONG Addend 00200 ); 00201 00202 NTKERNELAPI 00203 LONG 00204 InterlockedDecrement( 00205 IN OUT PLONG Addend 00206 ); 00207 00208 NTKERNELAPI 00209 LONG 00210 InterlockedExchange( 00211 IN OUT PLONG Target, 00212 IN LONG Increment 00213 ); 00214 00215 NTKERNELAPI 00216 LONG 00217 InterlockedExchangeAdd( 00218 IN OUT PLONG Addend, 00219 IN LONG Value 00220 ); 00221 00222 NTKERNELAPI 00223 PVOID 00224 InterlockedCompareExchange ( 00225 IN OUT PVOID *Destination, 00226 IN PVOID Exchange, 00227 IN PVOID Comperand 00228 ); 00229 00230 #endif 00231 00232 // 00233 // PowerPC Interrupt Definitions. 00234 // 00235 // Define length of interupt object dispatch code in 32-bit words. 00236 // 00237 00238 #define DISPATCH_LENGTH 4 // Length of dispatch code in instructions 00239 00240 // 00241 // Define Interrupt Request Levels. 00242 // 00243 00244 #define PASSIVE_LEVEL 0 // Passive release level 00245 #define LOW_LEVEL 0 // Lowest interrupt level 00246 #define APC_LEVEL 1 // APC interrupt level 00247 #define DISPATCH_LEVEL 2 // Dispatcher level 00248 #define PROFILE_LEVEL 27 // Profiling level 00249 #define IPI_LEVEL 29 // Interprocessor interrupt level 00250 #define POWER_LEVEL 30 // Power failure level 00251 #define FLOAT_LEVEL 31 // Floating interrupt level 00252 #define HIGH_LEVEL 31 // Highest interrupt level 00253 #define SYNCH_LEVEL DISPATCH_LEVEL // Synchronization level 00254 00255 // 00256 // Define profile intervals. 00257 // 00258 // **FINISH** These are the MIPS R4000 values; investigate for PPC 00259 00260 #define DEFAULT_PROFILE_COUNT 0x40000000 // ~= 20 seconds @50mhz 00261 #define DEFAULT_PROFILE_INTERVAL (10 * 500) // 500 microseconds 00262 #define MAXIMUM_PROFILE_INTERVAL (10 * 1000 * 1000) // 1 second 00263 #define MINIMUM_PROFILE_INTERVAL (10 * 40) // 40 microseconds 00264 00265 // end_ntddk end_wdm end_nthal 00266 00267 #define KiSynchIrql SYNCH_LEVEL // enable portable code 00268 #define KiProfileIrql PROFILE_LEVEL // enable portable code 00269 00270 // 00271 // Define machine specific external references. 00272 // 00273 00274 // **FINISH** On MIPS, this is defined in ...\ntos\ke\mips\xxintsup.s 00275 // For PPC, ensure that there is a C-referencable label 00276 // on the list of instructions (the ordinary entry point 00277 // name won't be, because it will start with '.'). 00278 extern ULONG KiInterruptTemplate[]; 00279 00280 // 00281 // Sanitize FPSCR and MSR based on processor mode. 00282 // By analogy with MIPS "Sanitize FSR" and "Sanitize PSR" 00283 // 00284 // General form: #define SANTIZE_<reg>(reg, mode) 00285 // ((mode) == KernelMode ? 00286 // ((0x00000000L) | ((reg) & 0xFFFFFFFF)) : 00287 // ((0x00000000L) | ((reg) & 0xFFFFFFFF))) 00288 // Where 0x00000000L represents bits that are forced on, and 00289 // 0xFFFFFFFF represents bits that are forced off. 00290 // 00291 // We will optimize this expression right here in the macro, because 00292 // the initial PPC compiler cannot be expected to do so itself. 00293 // 00294 // FPSCR -- Floating Point Status and Control Register 00295 // 00296 // We turn off the various exception enable bits so that loading 00297 // the FPSCR cannot cause an exception. 00298 // Force to 0: VE (24), OE (25), UE (26), ZE (27), XE (28) 00299 // Force to 1: -none- 00300 // Let caller specify: All others 00301 00302 // **FINISH** -- Set this macro back to do something; leave as a no-op for now 00303 00304 #define SANITIZE_FPSCR(fpscr, mode) (fpscr) 00305 //#define SANITIZE_FPSCR(fpscr, mode) (fpscr & 0xFFFFFF07L) 00306 00307 // 00308 // MSR -- Machine State Register 00309 // 00310 // If kernel mode, then 00311 // Force to 0: reserved (0..12, 24, 28) 00312 // Force to 1: ILE (15), LE (31) 00313 // Let caller specify: 00314 // POW (13), implementation-dependent (14), 00315 // EE (16), PR (17), FP (18), ME (19), 00316 // FE0 (20), SE (21), BE (22), FE1 (23), 00317 // IP (25), IR (26), DR (27), PM (29), RI (30) 00318 // 00319 // If user mode, then 00320 // Force to 0: POW (13), implementation-dependent (14), IP (25), 00321 // reserved (0..12, 24, 28) 00322 // Force to 1: ILE (15), EE (16), PR (17), FPE (18), ME (19), 00323 // IR (26), DR (27), RI (30), LE (31) 00324 // Let caller specify: 00325 // FE0 (20), SE (21), BE (22), FE1 (23), PM (29) 00326 // 00327 00328 #define SANITIZE_MSR(msr, mode) \ 00329 ((mode) == KernelMode ? \ 00330 ((0x00010001L) | ((msr) & 0x0007FF77L)) : \ 00331 ((0x0001F033L) | ((msr) & 0x0001FF37L))) 00332 00333 // begin_ntddk begin_wdm begin_nthal 00334 // 00335 // Define length of interrupt vector table. 00336 // 00337 00338 #define MAXIMUM_VECTOR 256 00339 00340 // 00341 // Processor Control Region 00342 // 00343 // On PowerPC, this cannot be at a fixed virtual address; 00344 // it must be at a different address on each processor of an MP. 00345 // 00346 00347 #define PCR_MINOR_VERSION 1 00348 #define PCR_MAJOR_VERSION 1 00349 00350 typedef struct _KPCR { 00351 00352 // 00353 // Major and minor version numbers of the PCR. 00354 // 00355 00356 USHORT MinorVersion; 00357 USHORT MajorVersion; 00358 00359 // 00360 // Start of the architecturally defined section of the PCR. This section 00361 // may be directly addressed by vendor/platform specific HAL code and will 00362 // not change from version to version of NT. 00363 // 00364 // Interrupt and error exception vectors. 00365 // 00366 00367 PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR]; 00368 ULONG PcrPage2; 00369 ULONG Kseg0Top; 00370 ULONG Spare7[30]; 00371 00372 // 00373 // First and second level cache parameters. 00374 // 00375 00376 ULONG FirstLevelDcacheSize; 00377 ULONG FirstLevelDcacheFillSize; 00378 ULONG FirstLevelIcacheSize; 00379 ULONG FirstLevelIcacheFillSize; 00380 ULONG SecondLevelDcacheSize; 00381 ULONG SecondLevelDcacheFillSize; 00382 ULONG SecondLevelIcacheSize; 00383 ULONG SecondLevelIcacheFillSize; 00384 00385 // 00386 // Pointer to processor control block. 00387 // 00388 00389 struct _KPRCB *Prcb; 00390 00391 // 00392 // Pointer to the thread environment block. A fast-path system call 00393 // is provided that will return this value to user-mode code. 00394 // 00395 00396 PVOID Teb; 00397 00398 // 00399 // Data cache alignment and fill size used for cache flushing and alignment. 00400 // These fields are set to the larger of the first and second level data 00401 // cache fill sizes. 00402 // 00403 00404 ULONG DcacheAlignment; 00405 ULONG DcacheFillSize; 00406 00407 // 00408 // Instruction cache alignment and fill size used for cache flushing and 00409 // alignment. These fields are set to the larger of the first and second 00410 // level data cache fill sizes. 00411 // 00412 00413 ULONG IcacheAlignment; 00414 ULONG IcacheFillSize; 00415 00416 // 00417 // Processor identification information from PVR. 00418 // 00419 00420 ULONG ProcessorVersion; 00421 ULONG ProcessorRevision; 00422 00423 // 00424 // Profiling data. 00425 // 00426 00427 ULONG ProfileInterval; 00428 ULONG ProfileCount; 00429 00430 // 00431 // Stall execution count and scale factor. 00432 // 00433 00434 ULONG StallExecutionCount; 00435 ULONG StallScaleFactor; 00436 00437 // 00438 // Spare cell. 00439 // 00440 00441 ULONG Spare; 00442 00443 // 00444 // Cache policy, right justified, as read from the processor configuration 00445 // register at startup. 00446 // 00447 00448 union { 00449 ULONG CachePolicy; 00450 struct { 00451 UCHAR IcacheMode; // Dynamic cache mode for PPC 00452 UCHAR DcacheMode; // Dynamic cache mode for PPC 00453 USHORT ModeSpare; 00454 }; 00455 }; 00456 00457 // 00458 // IRQL mapping tables. 00459 // 00460 00461 UCHAR IrqlMask[32]; 00462 UCHAR IrqlTable[9]; 00463 00464 // 00465 // Current IRQL. 00466 // 00467 00468 UCHAR CurrentIrql; 00469 00470 // 00471 // Processor identification 00472 // 00473 CCHAR Number; 00474 KAFFINITY SetMember; 00475 00476 // 00477 // Reserved interrupt vector mask. 00478 // 00479 00480 ULONG ReservedVectors; 00481 00482 // 00483 // Current state parameters. 00484 // 00485 00486 struct _KTHREAD *CurrentThread; 00487 00488 // 00489 // Cache policy, PTE field aligned, as read from the processor configuration 00490 // register at startup. 00491 // 00492 00493 ULONG AlignedCachePolicy; 00494 00495 // 00496 // Flag for determining pending software interrupts 00497 // 00498 union { 00499 ULONG SoftwareInterrupt; // any bit 1 => some s/w interrupt pending 00500 struct { 00501 UCHAR ApcInterrupt; // 0x01 if APC int pending 00502 UCHAR DispatchInterrupt; // 0x01 if dispatch int pending 00503 UCHAR Spare4; 00504 UCHAR Spare5; 00505 }; 00506 }; 00507 00508 // 00509 // Complement of the processor affinity mask. 00510 // 00511 00512 KAFFINITY NotMember; 00513 00514 // 00515 // Space reserved for the system. 00516 // 00517 00518 ULONG SystemReserved[16]; 00519 00520 // 00521 // Space reserved for the HAL 00522 // 00523 00524 ULONG HalReserved[16]; 00525 00526 // 00527 // End of the architecturally defined section of the PCR. This section 00528 // may be directly addressed by vendor/platform specific HAL code and will 00529 // not change from version to version of NT. 00530 // 00531 // end_ntddk end_wdm end_nthal 00532 00533 // 00534 // Start of the operating system release dependent section of the PCR. 00535 // This section may change from release to release and should not be 00536 // addressed by vendor/platform specific HAL code. 00537 // 00538 // Function active flags. 00539 // 00540 00541 ULONG FirstLevelActive; 00542 00543 // 00544 // System service dispatch start and end address used by get/set context. 00545 // 00546 00547 ULONG SystemServiceDispatchStart; 00548 ULONG SystemServiceDispatchEnd; 00549 00550 // 00551 // Interrupt stack. 00552 // 00553 00554 ULONG InterruptStack; 00555 00556 // 00557 // Quantum end flag. 00558 // 00559 00560 ULONG QuantumEnd; 00561 00562 // 00563 // Exception handler values. 00564 // 00565 00566 PVOID InitialStack; 00567 PVOID PanicStack; 00568 ULONG BadVaddr; 00569 PVOID StackLimit; 00570 PVOID SavedStackLimit; 00571 ULONG SavedV0; 00572 ULONG SavedV1; 00573 UCHAR DebugActive; 00574 UCHAR Spare6[3]; 00575 00576 // 00577 // Save area for 6 GPRs on interrupt other than Storage interrupt. 00578 // 00579 ULONG GprSave[6]; 00580 00581 // 00582 // Save area for Instruction Storage and Data Storage interrupts. 00583 // 00584 00585 ULONG SiR0; 00586 ULONG SiR2; 00587 ULONG SiR3; 00588 ULONG SiR4; 00589 ULONG SiR5; 00590 00591 ULONG Spare0; 00592 ULONG Spare8; 00593 00594 // 00595 // Real address of current process's Page Directory Page, 00596 // changed when process (address space) changes, 00597 // for use by Instruction Storage and Data Storage interrupts. 00598 // 00599 00600 ULONG PgDirRa; 00601 00602 // 00603 // On interrupt stack indicator and saved initial stack. 00604 // 00605 00606 ULONG OnInterruptStack; 00607 ULONG SavedInitialStack; 00608 00609 } KPCR, *PKPCR; // ntddk wdm nthal 00610 00611 // 00612 // The PCR address on a particular processor is contained in 00613 // SPRG 0 and 1. 00614 // SPRG 0 -- Real address of PCR (used only by interrupt code) 00615 // SPRG 1 -- Virtual address of PCR (used by kernel generally) 00616 // These SPRGs are not accessable to user-mode code. 00617 00618 00619 // 00620 // Get Pointer to Processor Control Region 00621 // 00622 // KiGetPcr() is a two-instruction routine that just reads SPRG 1 00623 // into reg 3 and returns. Eventually this should be expanded in-line. 00624 00625 KPCR * KiGetPcr(VOID); 00626 00627 // begin_nthal 00628 00629 #define KIPCR2 0xffffe000 // kernel address of second PCR 00630 #define KI_USER_SHARED_DATA KIPCR2 00631 #define SharedUserData ((KUSER_SHARED_DATA * const)KIPCR2) 00632 00633 // begin_ntddk begin_wdm 00634 00635 #define KIPCR 0xffffd000 // kernel address of first PCR 00636 00637 #define PCR ((volatile KPCR * const)KIPCR) 00638 00639 #if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000) 00640 unsigned __sregister_get( unsigned const regnum ); 00641 #define _PPC_SPRG1_ 273 00642 #define PCRsprg1 ((volatile KPCR * volatile)__sregister_get(_PPC_SPRG1_)) 00643 #else 00644 KPCR * __builtin_get_sprg1(VOID); 00645 #define PCRsprg1 ((volatile KPCR * volatile)__builtin_get_sprg1()) 00646 #endif 00647 00648 // 00649 // Macros for enabling and disabling system interrupts. 00650 // 00651 //BUGBUG - work around 603e/ev errata #15 00652 // The instructions __emit'ed in these macros are "cror 0,0,0" instructions 00653 // that force the mtmsr to complete before allowing any subsequent loads to 00654 // issue. The condition register no-op is executed in the system unit on 00655 // the 603. This will not dispatch until the mtmsr completes and will halt 00656 // further dispatch. On a 601 or 604 this instruction executes in the 00657 // branch unit and will run in parallel (i.e., no performance penalty except 00658 // for code bloat). 00659 // 00660 00661 #if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000) 00662 00663 unsigned __sregister_get( unsigned const regnum ); 00664 void __sregister_set( unsigned const regnum, unsigned value ); 00665 #define _PPC_MSR_ (unsigned)(~0x0) 00666 #define _enable() (__sregister_set(_PPC_MSR_, __sregister_get(_PPC_MSR_) | 0x00008000), __emit(0x4C000382)) 00667 #define _disable() (__sregister_set(_PPC_MSR_, __sregister_get(_PPC_MSR_) & 0xffff7fff), __emit(0x4C000382)) 00668 #define __builtin_get_msr() __sregister_get(_PPC_MSR_) 00669 00670 #else 00671 00672 ULONG __builtin_get_msr(VOID); 00673 VOID __builtin_set_msr(ULONG); 00674 #define _enable() (__builtin_set_msr(__builtin_get_msr() | 0x00008000), __builtin_isync()) 00675 #define _disable() (__builtin_set_msr(__builtin_get_msr() & 0xffff7fff), __builtin_isync()) 00676 00677 #endif 00678 00679 // 00680 // Get current IRQL. 00681 // 00682 00683 #define KeGetCurrentIrql() PCR->CurrentIrql 00684 00685 // 00686 // Get address of current processor block. 00687 // 00688 00689 #define KeGetCurrentPrcb() PCR->Prcb 00690 00691 // 00692 // Get address of processor control region. 00693 // 00694 00695 #define KeGetPcr() PCR 00696 00697 // 00698 // Get address of current kernel thread object. 00699 // 00700 00701 #define KeGetCurrentThread() PCR->CurrentThread 00702 00703 // 00704 // Get Processor Version Register 00705 // 00706 00707 #if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000) 00708 unsigned __sregister_get( unsigned const regnum ); 00709 #define _PPC_PVR_ 287 00710 #define KeGetPvr() __sregister_get(_PPC_PVR_) 00711 #else 00712 ULONG __builtin_get_pvr(VOID); 00713 #define KeGetPvr() __builtin_get_pvr() 00714 #endif 00715 00716 // end_wdm 00717 // 00718 // Get current processor number. 00719 // 00720 00721 #define KeGetCurrentProcessorNumber() PCR->Number 00722 00723 // begin_wdm 00724 // 00725 // Get data cache fill size. 00726 // 00727 // **FINISH** See that proper PowerPC parameter is accessed here 00728 00729 #define KeGetDcacheFillSize() PCR->DcacheFillSize 00730 00731 // end_ntddk end_wdm end_nthal 00732 00733 // 00734 // Get previous processor mode. 00735 // 00736 00737 #define KeGetPreviousMode() (KPROCESSOR_MODE)PCR->CurrentThread->PreviousMode 00738 00739 // 00740 // Test if executing a DPC. 00741 // 00742 00743 BOOLEAN 00744 KeIsExecutingDpc ( 00745 VOID 00746 ); 00747 00748 // begin_ntddk begin_wdm 00749 // 00750 // Save & Restore floating point state 00751 // 00752 00753 #define KeSaveFloatingPointState(a) STATUS_SUCCESS 00754 #define KeRestoreFloatingPointState(a) STATUS_SUCCESS 00755 00756 // end_ntddk end_wdm 00757 00758 // begin_nthal 00759 // 00760 // Fill TB random entry 00761 // 00762 00763 NTKERNELAPI 00764 VOID 00765 KeFillEntryTb ( 00766 IN HARDWARE_PTE Pte[2], 00767 IN PVOID Virtual, 00768 IN BOOLEAN Invalid 00769 ); 00770 00771 // 00772 // Data cache, instruction cache, I/O buffer, and write buffer flush routine 00773 // prototypes. 00774 // 00775 00776 NTKERNELAPI 00777 VOID 00778 KeChangeColorPage ( 00779 IN PVOID NewColor, 00780 IN PVOID OldColor, 00781 IN ULONG PageFrame 00782 ); 00783 00784 NTKERNELAPI 00785 VOID 00786 KeSweepDcache ( 00787 IN BOOLEAN AllProcessors 00788 ); 00789 00790 #define KeSweepCurrentDcache() \ 00791 HalSweepDcache(); 00792 00793 NTKERNELAPI 00794 VOID 00795 KeSweepIcache ( 00796 IN BOOLEAN AllProcessors 00797 ); 00798 00799 #define KeSweepCurrentIcache() \ 00800 HalSweepIcache(); \ 00801 HalSweepDcache(); 00802 00803 NTKERNELAPI 00804 VOID 00805 KeSweepIcacheRange ( 00806 IN BOOLEAN AllProcessors, 00807 IN PVOID BaseAddress, 00808 IN ULONG Length 00809 ); 00810 00811 // begin_ntddk begin_wdm begin_ntndis 00812 // 00813 // Cache and write buffer flush functions. 00814 // 00815 00816 NTKERNELAPI 00817 VOID 00818 KeFlushIoBuffers ( 00819 IN PMDL Mdl, 00820 IN BOOLEAN ReadOperation, 00821 IN BOOLEAN DmaOperation 00822 ); 00823 00824 // end_ntddk end_wdm end_ntndis 00825 00826 // 00827 // Clock, profile, and interprocessor interrupt functions. 00828 // 00829 00830 struct _KEXCEPTION_FRAME; 00831 struct _KTRAP_FRAME; 00832 00833 NTKERNELAPI 00834 VOID 00835 KeIpiInterrupt ( 00836 IN struct _KTRAP_FRAME *TrapFrame 00837 ); 00838 00839 NTKERNELAPI 00840 VOID 00841 KeProfileInterrupt ( 00842 IN struct _KTRAP_FRAME *TrapFrame 00843 ); 00844 00845 NTKERNELAPI 00846 VOID 00847 KeProfileInterruptWithSource ( 00848 IN struct _KTRAP_FRAME *TrapFrame, 00849 IN KPROFILE_SOURCE ProfileSource 00850 ); 00851 00852 NTKERNELAPI 00853 VOID 00854 KeUpdateRunTime ( 00855 IN struct _KTRAP_FRAME *TrapFrame 00856 ); 00857 00858 NTKERNELAPI 00859 VOID 00860 KeUpdateSystemTime ( 00861 IN struct _KTRAP_FRAME *TrapFrame, 00862 IN ULONG TimeIncrement 00863 ); 00864 00865 // 00866 // Spin lock function prototypes (empty for uniprocessor). 00867 // Exported for use in MP HALs. 00868 // 00869 00870 #if defined(NT_UP) 00871 00872 #define KiAcquireSpinLock(SpinLock) 00873 00874 #else 00875 00876 NTKERNELAPI 00877 VOID 00878 KiAcquireSpinLock ( 00879 IN PKSPIN_LOCK SpinLock 00880 ); 00881 00882 #endif 00883 00884 #if defined(NT_UP) 00885 00886 #define KiReleaseSpinLock(SpinLock) 00887 00888 #else 00889 00890 NTKERNELAPI 00891 VOID 00892 KiReleaseSpinLock ( 00893 IN PKSPIN_LOCK SpinLock 00894 ); 00895 00896 #endif 00897 // end_nthal 00898 00899 00900 // 00901 // Define executive macros for acquiring and releasing executive spinlocks. 00902 // These macros can ONLY be used by executive components and NOT by drivers. 00903 // Drivers MUST use the kernel interfaces since they must be MP enabled on 00904 // all systems. 00905 // 00906 // On PPC, raise/lower IRQL are in the HAL, but KeRaiseIrqlToDpcLevel (raising to a 00907 // software level) is in the kernel. 00908 // 00909 00910 // begin_ntddk begin_nthal 00911 00912 NTKERNELAPI 00913 KIRQL 00914 KfRaiseIrqlToDpcLevel ( 00915 VOID 00916 ); 00917 00918 #define KeRaiseIrqlToDpcLevel(OldIrql) (*(OldIrql) = KfRaiseIrqlToDpcLevel()) 00919 00920 NTKERNELAPI 00921 KIRQL 00922 KeRaiseIrqlToSynchLevel ( 00923 VOID 00924 ); 00925 00926 // end_ntddk end_nthal 00927 #if defined(NT_UP) && !defined(_NTDDK_) && !defined(_NTIFS_) 00928 #define ExAcquireSpinLock(Lock, OldIrql) KeRaiseIrqlToDpcLevel((OldIrql)) 00929 #define ExReleaseSpinLock(Lock, OldIrql) KeLowerIrql((OldIrql)) 00930 #define ExAcquireSpinLockAtDpcLevel(Lock) 00931 #define ExReleaseSpinLockFromDpcLevel(Lock) 00932 #else 00933 00934 // begin_wdm begin_ntddk 00935 #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql)) 00936 #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql)) 00937 #define ExAcquireSpinLockAtDpcLevel(Lock) KeAcquireSpinLockAtDpcLevel(Lock) 00938 #define ExReleaseSpinLockFromDpcLevel(Lock) KeReleaseSpinLockFromDpcLevel(Lock) 00939 // end_wdm end_ntddk 00940 00941 #endif 00942 00943 // 00944 // The acquire and release fast lock macros disable and enable interrupts 00945 // on UP nondebug systems. On MP or debug systems, the spinlock routines 00946 // are used. 00947 // 00948 // N.B. Extreme caution should be observed when using these routines. 00949 // 00950 00951 #if defined(NT_UP) && !DBG 00952 #define ExAcquireFastLock(Lock, OldIrql) _disable() 00953 #else 00954 #define ExAcquireFastLock(Lock, OldIrql) \ 00955 ExAcquireSpinLock(Lock, OldIrql) 00956 #endif 00957 00958 #if defined(NT_UP) && !DBG 00959 #define ExReleaseFastLock(Lock, OldIrql) _enable() 00960 #else 00961 #define ExReleaseFastLock(Lock, OldIrql) \ 00962 ExReleaseSpinLock(Lock, OldIrql) 00963 #endif 00964 00965 00966 00967 // 00968 // Define query system time macro. 00969 // 00970 00971 #define KiQuerySystemTime(CurrentTime) \ 00972 do { \ 00973 (CurrentTime)->HighPart = SharedUserData->SystemTime.High1Time; \ 00974 (CurrentTime)->LowPart = SharedUserData->SystemTime.LowPart; \ 00975 } while ((CurrentTime)->HighPart != SharedUserData->SystemTime.High2Time) 00976 00977 // 00978 // Define query tick count macro. 00979 // 00980 00981 #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) 00982 00983 // begin_wdm begin_ntddk 00984 00985 #define KeQueryTickCount(CurrentCount) { \ 00986 PKSYSTEM_TIME _TickCount = *((PKSYSTEM_TIME *)(&KeTickCount)); \ 00987 do { \ 00988 (CurrentCount)->HighPart = _TickCount->High1Time; \ 00989 (CurrentCount)->LowPart = _TickCount->LowPart; \ 00990 } while ((CurrentCount)->HighPart != _TickCount->High2Time); \ 00991 } 00992 00993 // end_wdm end_ntddk 00994 00995 #else 00996 00997 // begin_nthal 00998 #define KiQueryTickCount(CurrentCount) \ 00999 do { \ 01000 (CurrentCount)->HighPart = KeTickCount.High1Time; \ 01001 (CurrentCount)->LowPart = KeTickCount.LowPart; \ 01002 } while ((CurrentCount)->HighPart != KeTickCount.High2Time) 01003 01004 NTKERNELAPI 01005 VOID 01006 KeQueryTickCount ( 01007 OUT PLARGE_INTEGER CurrentCount 01008 ); 01009 01010 // end_nthal 01011 #endif 01012 01013 #define KiQueryLowTickCount() KeTickCount.LowPart 01014 01015 // 01016 // Define query interrupt time macro. 01017 // 01018 01019 #define KiQueryInterruptTime(CurrentTime) \ 01020 do { \ 01021 (CurrentTime)->HighPart = SharedUserData->InterruptTime.High1Time; \ 01022 (CurrentTime)->LowPart = SharedUserData->InterruptTime.LowPart; \ 01023 } while ((CurrentTime)->HighPart != SharedUserData->InterruptTime.High2Time) 01024 01025 01026 // 01027 // The following function prototypes must be in the module since they are 01028 // machine dependent. 01029 // 01030 01031 // 01032 // Raise and lower IRQL 01033 // 01034 01035 ULONG 01036 KiEmulateBranch ( 01037 IN struct _KEXCEPTION_FRAME *ExceptionFrame, 01038 IN struct _KTRAP_FRAME *TrapFrame 01039 ); 01040 01041 BOOLEAN 01042 KiEmulateFloating ( 01043 IN OUT PEXCEPTION_RECORD ExceptionRecord, 01044 IN OUT struct _KEXCEPTION_FRAME *ExceptionFrame, 01045 IN OUT struct _KTRAP_FRAME *TrapFrame 01046 ); 01047 01048 BOOLEAN 01049 KiEmulateReference ( 01050 IN OUT PEXCEPTION_RECORD ExceptionRecord, 01051 IN OUT struct _KEXCEPTION_FRAME *ExceptionFrame, 01052 IN OUT struct _KTRAP_FRAME *TrapFrame 01053 ); 01054 01055 ULONG 01056 KiGetRegisterValue ( 01057 IN ULONG Register, 01058 IN struct _KEXCEPTION_FRAME *ExceptionFrame, 01059 IN struct _KTRAP_FRAME *TrapFrame 01060 ); 01061 01062 VOID 01063 KiSetRegisterValue ( 01064 IN ULONG Register, 01065 IN ULONG Value, 01066 OUT struct _KEXCEPTION_FRAME *ExceptionFrame, 01067 OUT struct _KTRAP_FRAME *TrapFrame 01068 ); 01069 01070 VOID 01071 KiRequestSoftwareInterrupt ( 01072 ULONG RequestIrql 01073 ); 01074 01075 01076 01077 01078 // begin_ntddk begin_wdm begin_nthal begin_ntndis 01079 01080 // 01081 // I/O space read and write macros. 01082 // 01083 // **FINISH** Ensure that these are appropriate for PowerPC 01084 01085 #define READ_REGISTER_UCHAR(x) \ 01086 *(volatile UCHAR * const)(x) 01087 01088 #define READ_REGISTER_USHORT(x) \ 01089 *(volatile USHORT * const)(x) 01090 01091 #define READ_REGISTER_ULONG(x) \ 01092 *(volatile ULONG * const)(x) 01093 01094 #define READ_REGISTER_BUFFER_UCHAR(x, y, z) { \ 01095 PUCHAR registerBuffer = x; \ 01096 PUCHAR readBuffer = y; \ 01097 ULONG readCount; \ 01098 for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \ 01099 *readBuffer = *(volatile UCHAR * const)(registerBuffer); \ 01100 } \ 01101 } 01102 01103 #define READ_REGISTER_BUFFER_USHORT(x, y, z) { \ 01104 PUSHORT registerBuffer = x; \ 01105 PUSHORT readBuffer = y; \ 01106 ULONG readCount; \ 01107 for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \ 01108 *readBuffer = *(volatile USHORT * const)(registerBuffer); \ 01109 } \ 01110 } 01111 01112 #define READ_REGISTER_BUFFER_ULONG(x, y, z) { \ 01113 PULONG registerBuffer = x; \ 01114 PULONG readBuffer = y; \ 01115 ULONG readCount; \ 01116 for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \ 01117 *readBuffer = *(volatile ULONG * const)(registerBuffer); \ 01118 } \ 01119 } 01120 01121 #define WRITE_REGISTER_UCHAR(x, y) { \ 01122 *(volatile UCHAR * const)(x) = y; \ 01123 KeFlushWriteBuffer(); \ 01124 } 01125 01126 #define WRITE_REGISTER_USHORT(x, y) { \ 01127 *(volatile USHORT * const)(x) = y; \ 01128 KeFlushWriteBuffer(); \ 01129 } 01130 01131 #define WRITE_REGISTER_ULONG(x, y) { \ 01132 *(volatile ULONG * const)(x) = y; \ 01133 KeFlushWriteBuffer(); \ 01134 } 01135 01136 #define WRITE_REGISTER_BUFFER_UCHAR(x, y, z) { \ 01137 PUCHAR registerBuffer = x; \ 01138 PUCHAR writeBuffer = y; \ 01139 ULONG writeCount; \ 01140 for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \ 01141 *(volatile UCHAR * const)(registerBuffer) = *writeBuffer; \ 01142 } \ 01143 KeFlushWriteBuffer(); \ 01144 } 01145 01146 #define WRITE_REGISTER_BUFFER_USHORT(x, y, z) { \ 01147 PUSHORT registerBuffer = x; \ 01148 PUSHORT writeBuffer = y; \ 01149 ULONG writeCount; \ 01150 for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \ 01151 *(volatile USHORT * const)(registerBuffer) = *writeBuffer; \ 01152 } \ 01153 KeFlushWriteBuffer(); \ 01154 } 01155 01156 #define WRITE_REGISTER_BUFFER_ULONG(x, y, z) { \ 01157 PULONG registerBuffer = x; \ 01158 PULONG writeBuffer = y; \ 01159 ULONG writeCount; \ 01160 for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \ 01161 *(volatile ULONG * const)(registerBuffer) = *writeBuffer; \ 01162 } \ 01163 KeFlushWriteBuffer(); \ 01164 } 01165 01166 01167 #define READ_PORT_UCHAR(x) \ 01168 *(volatile UCHAR * const)(x) 01169 01170 #define READ_PORT_USHORT(x) \ 01171 *(volatile USHORT * const)(x) 01172 01173 #define READ_PORT_ULONG(x) \ 01174 *(volatile ULONG * const)(x) 01175 01176 #define READ_PORT_BUFFER_UCHAR(x, y, z) { \ 01177 PUCHAR readBuffer = y; \ 01178 ULONG readCount; \ 01179 for (readCount = 0; readCount < z; readCount++, readBuffer++) { \ 01180 *readBuffer = *(volatile UCHAR * const)(x); \ 01181 } \ 01182 } 01183 01184 #define READ_PORT_BUFFER_USHORT(x, y, z) { \ 01185 PUSHORT readBuffer = y; \ 01186 ULONG readCount; \ 01187 for (readCount = 0; readCount < z; readCount++, readBuffer++) { \ 01188 *readBuffer = *(volatile USHORT * const)(x); \ 01189 } \ 01190 } 01191 01192 #define READ_PORT_BUFFER_ULONG(x, y, z) { \ 01193 PULONG readBuffer = y; \ 01194 ULONG readCount; \ 01195 for (readCount = 0; readCount < z; readCount++, readBuffer++) { \ 01196 *readBuffer = *(volatile ULONG * const)(x); \ 01197 } \ 01198 } 01199 01200 #define WRITE_PORT_UCHAR(x, y) { \ 01201 *(volatile UCHAR * const)(x) = y; \ 01202 KeFlushWriteBuffer(); \ 01203 } 01204 01205 #define WRITE_PORT_USHORT(x, y) { \ 01206 *(volatile USHORT * const)(x) = y; \ 01207 KeFlushWriteBuffer(); \ 01208 } 01209 01210 #define WRITE_PORT_ULONG(x, y) { \ 01211 *(volatile ULONG * const)(x) = y; \ 01212 KeFlushWriteBuffer(); \ 01213 } 01214 01215 #define WRITE_PORT_BUFFER_UCHAR(x, y, z) { \ 01216 PUCHAR writeBuffer = y; \ 01217 ULONG writeCount; \ 01218 for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \ 01219 *(volatile UCHAR * const)(x) = *writeBuffer; \ 01220 KeFlushWriteBuffer(); \ 01221 } \ 01222 } 01223 01224 #define WRITE_PORT_BUFFER_USHORT(x, y, z) { \ 01225 PUSHORT writeBuffer = y; \ 01226 ULONG writeCount; \ 01227 for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \ 01228 *(volatile USHORT * const)(x) = *writeBuffer; \ 01229 KeFlushWriteBuffer(); \ 01230 } \ 01231 } 01232 01233 #define WRITE_PORT_BUFFER_ULONG(x, y, z) { \ 01234 PULONG writeBuffer = y; \ 01235 ULONG writeCount; \ 01236 for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \ 01237 *(volatile ULONG * const)(x) = *writeBuffer; \ 01238 KeFlushWriteBuffer(); \ 01239 } \ 01240 } 01241 01242 // end_ntddk end_wdm end_nthal end_ntndis 01243 01244 01245 // 01246 // Masks for Dr7 and sanitize macros for various debug registers. 01247 // 01248 #define DR6_LEGAL 0x0000e00f 01249 01250 #define DR7_LEGAL 0xffff0155 01251 01252 #define DR7_ACTIVE 0x00000055 // If any of these bits are set a debug 01253 // register is active providing Dr6 01254 // indicates DR available 01255 #define SANITIZE_DR6(Dr6, mode) ((Dr6 & DR6_LEGAL)); 01256 01257 #define SANITIZE_DR7(Dr7, mode) ((Dr7 & DR7_LEGAL)); 01258 01259 #define SANITIZE_DRADDR(DrReg, mode) ( \ 01260 (mode) == KernelMode ? \ 01261 (DrReg): \ 01262 (((PVOID)DrReg <= MM_HIGHEST_USER_ADDRESS) ? \ 01263 (DrReg): \ 01264 (0) \ 01265 ) \ 01266 ) 01267 01268 // begin_nthal 01269 // 01270 // Trap Frame -- Volatile state 01271 // 01272 // N.B. This frame must be a multiple of 8 bytes in length, as the 01273 // Stack Frame header (see ntppc.h), Trap Frame and Exception Frame 01274 // together must make up a valid call stack frame. 01275 // 01276 01277 // CR fields 0, 1, 5..7 are volatile and appear here 01278 // CR fields 2..4 are non-volatile and appear in the Exception Frame 01279 01280 #define CR_VOLATILE_FIELDS 0xFF000FFFL 01281 01282 typedef struct _KTRAP_FRAME { 01283 01284 PVOID TrapFrame; // previous trap frame address 01285 01286 UCHAR OldIrql; 01287 UCHAR PreviousMode; 01288 UCHAR SavedApcStateIndex; 01289 UCHAR SavedKernelApcDisable; 01290 01291 // Exception Record embedded in the Trap Frame, on 8-byte boundary, 01292 // padded to multiple of 8 bytes 01293 01294 UCHAR ExceptionRecord[(sizeof(EXCEPTION_RECORD) + 7) & (~7)]; 01295 01296 ULONG FILL2; 01297 01298 // General registers 0 thru 12 01299 01300 ULONG Gpr0; 01301 ULONG Gpr1; 01302 ULONG Gpr2; 01303 ULONG Gpr3; 01304 ULONG Gpr4; 01305 ULONG Gpr5; 01306 ULONG Gpr6; 01307 ULONG Gpr7; 01308 ULONG Gpr8; 01309 ULONG Gpr9; 01310 ULONG Gpr10; 01311 ULONG Gpr11; 01312 ULONG Gpr12; 01313 01314 // Floating point registers 0 thru 13 01315 01316 DOUBLE Fpr0; // 8-byte boundary required here 01317 DOUBLE Fpr1; 01318 DOUBLE Fpr2; 01319 DOUBLE Fpr3; 01320 DOUBLE Fpr4; 01321 DOUBLE Fpr5; 01322 DOUBLE Fpr6; 01323 DOUBLE Fpr7; 01324 DOUBLE Fpr8; 01325 DOUBLE Fpr9; 01326 DOUBLE Fpr10; 01327 DOUBLE Fpr11; 01328 DOUBLE Fpr12; 01329 DOUBLE Fpr13; 01330 01331 // Floating Point Status and Control Register 01332 01333 DOUBLE Fpscr; 01334 01335 // Other volatile control registers 01336 01337 ULONG Cr; // Only CR fields 0, 1, 5..7 are volatile, but the 01338 // entire CR is saved here on interrupt 01339 ULONG Xer; 01340 ULONG Msr; 01341 ULONG Iar; 01342 ULONG Lr; 01343 ULONG Ctr; 01344 01345 // Debug Registers 01346 01347 ULONG Dr0; 01348 ULONG Dr1; 01349 ULONG Dr2; 01350 ULONG Dr3; 01351 ULONG Dr4; 01352 ULONG Dr5; 01353 ULONG Dr6; 01354 ULONG Dr7; 01355 01356 } KTRAP_FRAME, *PKTRAP_FRAME; 01357 01358 #define KTRAP_FRAME_LENGTH ((sizeof(KTRAP_FRAME) + 7) & (~7)) 01359 #define KTRAP_FRAME_ALIGN (sizeof(DOUBLE)) 01360 #define KTRAP_FRAME_ROUND (KTRAP_FRAME_ALIGN - 1) 01361 01362 // end_nthal 01363 // 01364 // The frame saved by KiCallUserMode is defined here to allow 01365 // the kernel debugger to trace the entire kernel stack 01366 // when usermode callouts are pending. 01367 // 01368 01369 typedef struct _KCALLOUT_FRAME { 01370 STACK_FRAME_HEADER Frame; 01371 ULONG CbStk; // saved callback stack address 01372 ULONG TrFr; // saved callback trap frame address 01373 ULONG InStk; // saved initial stack address 01374 ULONG TrIar; // saved trap IAR 01375 ULONG TrToc; // saved trap TOC 01376 ULONG R3; // saved R3 (OutputBuffer) 01377 ULONG R4; // saved R4 (OutputLength) 01378 ULONG Lr; // saved LR 01379 ULONG Gpr[18]; // all nonvolatile GPRs 01380 DOUBLE Fpr[18]; // all nonvolatile FPRs 01381 } KCALLOUT_FRAME, *PKCALLOUT_FRAME; 01382 01383 typedef struct _UCALLOUT_FRAME { 01384 STACK_FRAME_HEADER Frame; 01385 PVOID Buffer; 01386 ULONG Length; 01387 ULONG ApiNumber; 01388 ULONG Lr; 01389 ULONG Toc; 01390 ULONG Pad; 01391 } UCALLOUT_FRAME, *PUCALLOUT_FRAME; 01392 01393 01394 // begin_nthal 01395 // 01396 // Exception frame -- NON-VOLATILE state 01397 // 01398 // This structure's layout matches that of the registers as saved 01399 // in a call/return stack frame, where the called program has saved 01400 // all the non-volatile registers. 01401 // 01402 // N.B. This frame must be a multiple of 8 bytes in length, as the 01403 // Stack Frame header (see ntppc.h), Trap Frame and the Exception 01404 // Frame together must make up a valid call stack frame. 01405 // 01406 01407 typedef struct _KEXCEPTION_FRAME { 01408 01409 ULONG Fill1; // padding 01410 01411 ULONG Gpr13; 01412 ULONG Gpr14; 01413 ULONG Gpr15; 01414 ULONG Gpr16; 01415 ULONG Gpr17; 01416 ULONG Gpr18; 01417 ULONG Gpr19; 01418 ULONG Gpr20; 01419 ULONG Gpr21; 01420 ULONG Gpr22; 01421 ULONG Gpr23; 01422 ULONG Gpr24; 01423 ULONG Gpr25; 01424 ULONG Gpr26; 01425 ULONG Gpr27; 01426 ULONG Gpr28; 01427 ULONG Gpr29; 01428 ULONG Gpr30; 01429 ULONG Gpr31; 01430 01431 DOUBLE Fpr14; // 8-byte boundary required here 01432 DOUBLE Fpr15; 01433 DOUBLE Fpr16; 01434 DOUBLE Fpr17; 01435 DOUBLE Fpr18; 01436 DOUBLE Fpr19; 01437 DOUBLE Fpr20; 01438 DOUBLE Fpr21; 01439 DOUBLE Fpr22; 01440 DOUBLE Fpr23; 01441 DOUBLE Fpr24; 01442 DOUBLE Fpr25; 01443 DOUBLE Fpr26; 01444 DOUBLE Fpr27; 01445 DOUBLE Fpr28; 01446 DOUBLE Fpr29; 01447 DOUBLE Fpr30; 01448 DOUBLE Fpr31; 01449 01450 } KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; 01451 01452 // end_nthal 01453 // 01454 // Special version of exception frame for use by SwapContext and 01455 // KiInitializeContextThread. 01456 // 01457 01458 typedef struct _KSWAP_FRAME { 01459 KEXCEPTION_FRAME ExceptionFrame; 01460 ULONG ConditionRegister; 01461 ULONG SwapReturn; 01462 } KSWAP_FRAME, *PKSWAP_FRAME; 01463 01464 01465 // begin_ntddk begin_wdm 01466 // 01467 // Non-volatile floating point state 01468 // 01469 01470 typedef struct _KFLOATING_SAVE { 01471 ULONG Reserved; 01472 } KFLOATING_SAVE, *PKFLOATING_SAVE; 01473 01474 // end_ntddk end_wdm 01475 // 01476 // Format of stack frame during exceptions. 01477 // 01478 01479 #define STK_SLACK_SPACE 232 01480 01481 typedef struct _KEXCEPTION_STACK_FRAME { 01482 STACK_FRAME_HEADER Header; 01483 ULONG AdditionalParameters[8]; 01484 KTRAP_FRAME TrapFrame; 01485 KEXCEPTION_FRAME ExceptionFrame; 01486 PVOID Lr; 01487 PVOID Cr; 01488 UCHAR SlackSpace[STK_SLACK_SPACE]; 01489 } KEXCEPTION_STACK_FRAME, *PKEXCEPTION_STACK_FRAME; 01490 01491 // begin_nthal 01492 // begin_windbgkd 01493 01494 #ifdef _PPC_ 01495 // 01496 // Special Registers for PowerPC 01497 // 01498 01499 typedef struct _KSPECIAL_REGISTERS { 01500 ULONG KernelDr0; 01501 ULONG KernelDr1; 01502 ULONG KernelDr2; 01503 ULONG KernelDr3; 01504 ULONG KernelDr4; 01505 ULONG KernelDr5; 01506 ULONG KernelDr6; 01507 ULONG KernelDr7; 01508 ULONG Sprg0; 01509 ULONG Sprg1; 01510 ULONG Sr0; 01511 ULONG Sr1; 01512 ULONG Sr2; 01513 ULONG Sr3; 01514 ULONG Sr4; 01515 ULONG Sr5; 01516 ULONG Sr6; 01517 ULONG Sr7; 01518 ULONG Sr8; 01519 ULONG Sr9; 01520 ULONG Sr10; 01521 ULONG Sr11; 01522 ULONG Sr12; 01523 ULONG Sr13; 01524 ULONG Sr14; 01525 ULONG Sr15; 01526 ULONG DBAT0L; 01527 ULONG DBAT0U; 01528 ULONG DBAT1L; 01529 ULONG DBAT1U; 01530 ULONG DBAT2L; 01531 ULONG DBAT2U; 01532 ULONG DBAT3L; 01533 ULONG DBAT3U; 01534 ULONG IBAT0L; 01535 ULONG IBAT0U; 01536 ULONG IBAT1L; 01537 ULONG IBAT1U; 01538 ULONG IBAT2L; 01539 ULONG IBAT2U; 01540 ULONG IBAT3L; 01541 ULONG IBAT3U; 01542 ULONG Sdr1; 01543 ULONG Reserved[9]; 01544 } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; 01545 01546 // 01547 // Processor State structure. 01548 // 01549 01550 typedef struct _KPROCESSOR_STATE { 01551 struct _CONTEXT ContextFrame; 01552 struct _KSPECIAL_REGISTERS SpecialRegisters; 01553 } KPROCESSOR_STATE, *PKPROCESSOR_STATE; 01554 01555 #endif // _PPC_ 01556 // end_windbgkd 01557 01558 // 01559 // Processor Control Block (PRCB) 01560 // 01561 01562 #define PRCB_MINOR_VERSION 1 01563 #define PRCB_MAJOR_VERSION 1 01564 #define PRCB_BUILD_DEBUG 0x0001 01565 #define PRCB_BUILD_UNIPROCESSOR 0x0002 01566 01567 struct _RESTART_BLOCK; 01568 01569 typedef struct _KPRCB { 01570 01571 // 01572 // Major and minor version numbers of the PCR. 01573 // 01574 01575 USHORT MinorVersion; 01576 USHORT MajorVersion; 01577 01578 // 01579 // Start of the architecturally defined section of the PRCB. This section 01580 // may be directly addressed by vendor/platform specific HAL code and will 01581 // not change from version to version of NT. 01582 // 01583 01584 struct _KTHREAD *CurrentThread; 01585 struct _KTHREAD *RESTRICTED_POINTER NextThread; 01586 struct _KTHREAD *IdleThread; 01587 CCHAR Number; 01588 CCHAR Reserved; 01589 USHORT BuildType; 01590 KAFFINITY SetMember; 01591 struct _RESTART_BLOCK *RestartBlock; 01592 ULONG PcrPage; 01593 ULONG PcrPage2; 01594 01595 // 01596 // Space reserved for the system. 01597 // 01598 01599 ULONG SystemReserved[15]; 01600 01601 // 01602 // Space reserved for the HAL. 01603 // 01604 01605 ULONG HalReserved[16]; 01606 01607 // End of the architecturally defined section of the PRCB. 01608 // end_nthal 01609 // 01610 01611 ULONG DpcTime; 01612 ULONG InterruptTime; 01613 ULONG KernelTime; 01614 ULONG UserTime; 01615 ULONG AdjustDpcThreshold; 01616 ULONG InterruptCount; 01617 ULONG ApcBypassCount; 01618 ULONG DpcBypassCount; 01619 ULONG Spare6[5]; 01620 01621 // 01622 // MP information. 01623 // 01624 01625 PVOID Spare1; 01626 PVOID Spare2; 01627 volatile ULONG IpiFrozen; 01628 struct _KPROCESSOR_STATE ProcessorState; 01629 01630 // 01631 // Per-processor data for various hot code which resides in the 01632 // kernel image. Each processor is given its own copy of the data 01633 // to lessen the cache impact of sharing the data between multiple 01634 // processors. 01635 // 01636 01637 // 01638 // Spares (formerly fsrtl filelock free lists) 01639 // 01640 01641 PVOID SpareHotData[2]; 01642 01643 // 01644 // Cache manager performance counters. 01645 // 01646 01647 ULONG CcFastReadNoWait; 01648 ULONG CcFastReadWait; 01649 ULONG CcFastReadNotPossible; 01650 ULONG CcCopyReadNoWait; 01651 ULONG CcCopyReadWait; 01652 ULONG CcCopyReadNoWaitMiss; 01653 01654 // 01655 // Kernel performance counters. 01656 // 01657 01658 ULONG KeAlignmentFixupCount; 01659 ULONG KeContextSwitches; 01660 ULONG KeDcacheFlushCount; 01661 ULONG KeExceptionDispatchCount; 01662 ULONG KeFirstLevelTbFills; 01663 ULONG KeFloatingEmulationCount; 01664 ULONG KeIcacheFlushCount; 01665 ULONG KeSecondLevelTbFills; 01666 ULONG KeSystemCalls; 01667 01668 ULONG PagedPoolLookasideHits; 01669 01670 // 01671 // Reserved for future counters. 01672 // 01673 01674 ULONG ReservedCounter[14]; 01675 01676 // 01677 // Reserved pad. 01678 // 01679 01680 union { 01681 ULONG ReservedPad[16 * 8]; 01682 PVOID PagedFreeEntry[POOL_SMALL_LISTS]; 01683 }; 01684 01685 // 01686 // MP interprocessor request packet and summary. 01687 // 01688 // N.B. This is carefully aligned to be on a cache line boundary. 01689 // 01690 01691 volatile PVOID CurrentPacket[3]; 01692 volatile KAFFINITY TargetSet; 01693 volatile PKIPI_WORKER WorkerRoutine; 01694 ULONG CachePad1[3]; 01695 01696 // 01697 // N.B. These two longwords must be on a quadword boundary and adjacent. 01698 // 01699 01700 volatile ULONG RequestSummary; 01701 volatile struct _KPRCB *SignalDone; 01702 ULONG CachePad2[6]; 01703 01704 // 01705 // DPC interrupt requested. 01706 // 01707 01708 ULONG DpcInterruptRequested; 01709 ULONG CachePad3[7]; 01710 01711 // 01712 // DPC batching parameters. 01713 // 01714 01715 ULONG MaximumDpcQueueDepth; 01716 ULONG MinimumDpcRate; 01717 01718 // 01719 // Spare counters. 01720 // 01721 01722 ULONG Spare4[2]; 01723 01724 // 01725 // I/O system per processor single entry lookaside lists. 01726 // 01727 01728 PVOID SmallIrpFreeEntry; 01729 PVOID LargeIrpFreeEntry; 01730 PVOID MdlFreeEntry; 01731 01732 // 01733 // Object manager per processor single entry lookaside lists. 01734 // 01735 01736 PVOID CreateInfoFreeEntry; 01737 PVOID NameBufferFreeEntry; 01738 01739 // 01740 // Cache manager per processor single entry lookaside lists. 01741 // 01742 01743 PVOID SharedCacheMapEntry; 01744 01745 // 01746 // Spares. 01747 // 01748 01749 ULONG Spare5[2]; 01750 01751 // 01752 // Address of MP interprocessor operation counters. 01753 // 01754 01755 PKIPI_COUNTS IpiCounts; 01756 LARGE_INTEGER StartCount; 01757 01758 // 01759 // DPC list head, spinlock, and count. 01760 // 01761 01762 KSPIN_LOCK DpcLock; 01763 LIST_ENTRY DpcListHead; 01764 ULONG DpcQueueDepth; 01765 ULONG DpcCount; 01766 ULONG DpcLastCount; 01767 ULONG DpcRequestRate; 01768 ULONG DpcRoutineActive; 01769 BOOLEAN SkipTick; 01770 ULONG CachePad4[5]; 01771 01772 // 01773 // Processors power state 01774 // 01775 PROCESSOR_POWER_STATE PowerState; 01776 01777 01778 } KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB; // nthal 01779 01780 // begin_ntddk begin_wdm begin_nthal begin_ntndis 01781 // 01782 // PowerPC page size = 4 KB 01783 // 01784 01785 #define PAGE_SIZE (ULONG)0x1000 01786 01787 // 01788 // Define the number of trailing zeroes in a page aligned virtual address. 01789 // This is used as the shift count when shifting virtual addresses to 01790 // virtual page numbers. 01791 // 01792 01793 #define PAGE_SHIFT 12L 01794 01795 // end_ntddk end_wdm end_ntndis 01796 01797 // 01798 // Define the number of bits to shift to right justify the Page Directory Index 01799 // field of a PTE. 01800 // 01801 01802 #define PDI_SHIFT 22 01803 01804 // 01805 // Define the number of bits to shift to right justify the Page Table Index 01806 // field of a PTE. 01807 // 01808 01809 #define PTI_SHIFT 12 01810 01811 // begin_ntddk 01812 // 01813 // The highest user address reserves 64K bytes for a guard page. This 01814 // the probing of address from kernel mode to only have to check the 01815 // starting address for structures of 64k bytes or less. 01816 // 01817 01818 #define MM_HIGHEST_USER_ADDRESS (PVOID)0x7FFEFFFF // highest user address 01819 #define MM_SYSTEM_RANGE_START (PVOID)KSEG0_BASE // start of system space 01820 #define MM_USER_PROBE_ADDRESS 0x7FFF0000 // starting address of guard page 01821 01822 // 01823 // The following definitions are required for the debugger data block. 01824 // 01825 01826 extern PVOID MmHighestUserAddress; 01827 extern PVOID MmSystemRangeStart; 01828 extern ULONG MmUserProbeAddress; 01829 01830 // 01831 // The lowest user address reserves the low 64k. 01832 // 01833 01834 #define MM_LOWEST_USER_ADDRESS (PVOID)0x00010000 01835 01836 // begin_wdm 01837 01838 #define MmGetProcedureAddress(Address) *((PVOID *)(Address)) 01839 #define MmLockPagableCodeSection(Address) MmLockPagableDataSection(*((PVOID *)(Address))) 01840 01841 // end_ntddk end_wdm 01842 // 01843 // Define the page table and the page directory base for 01844 // memory management. 01845 // 01846 01847 #define PDE_BASE (ULONG)0xC0300000 01848 #define PTE_BASE (ULONG)0xC0000000 01849 01850 // begin_ntddk begin_wdm 01851 // 01852 // The lowest address for system space. 01853 // 01854 01855 #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0x80000000 01856 #define SYSTEM_BASE 0x80000000 // start of system space (no typecast) 01857 01858 // begin_ntndis 01859 #endif // defined(_PPC_) 01860 // end_ntddk end_wdm end_nthal end_ntndis 01861 // Special comment moved for hal.h since mips.h defines UNCACHED_POLICY 01862 // in unconditional code which is placed in the hal header file. 01863 01864 // 01865 // Define uncache policies. 01866 // 01867 // **FINISH** Check that these values are even needed for PPC. 01868 // 01869 01870 #define UNCACHED_POLICY 2 // uncached 01871 01872 // 01873 // Registers visible only to the operating system 01874 // 01875 01876 // 01877 // Define Data Storage Interrupt Status Register (DSISR) 01878 // 01879 01880 typedef struct _DSISR { 01881 ULONG UpdateReg : 5; // RA field for update-form instrs 01882 ULONG DataReg : 5; // RA, RS, FRA, or FRT field of instr 01883 ULONG Index : 7; // Index into table to distinguish instrs 01884 ULONG Fill2 : 1; 01885 ULONG XO : 2; // Extended op-code for DS-form instrs 01886 ULONG Fill1 : 12; 01887 } DSISR, *PDSISR; 01888 01889 DSISR KiGetDsisr (); // Function to read the DSISR 01890 void KiSetDsisr (DSISR Value); // Function to write the DSISR 01891 01892 // 01893 // PowerPC function definitions 01894 // 01895 01896 //++ 01897 // 01898 // BOOLEAN 01899 // KiIsThreadNumericStateSaved( 01900 // IN PKTHREAD Address 01901 // ) 01902 // 01903 // This call is used on a not running thread to see if its numeric 01904 // state has been saved in its context information. 01905 // 01906 // **FINISH** PowerPC is eventually to use lazy FP state-save, 01907 // but for now we'll always save the FP state. 01908 // 01909 //-- 01910 01911 #define KiIsThreadNumericStateSaved(a) TRUE 01912 01913 //++ 01914 // 01915 // VOID 01916 // KiRundownThread( 01917 // IN PKTHREAD Address 01918 // ) 01919 // 01920 //-- 01921 01922 #define KiRundownThread(a) 01923 01924 // 01925 // Define macro to test if x86 feature is present. 01926 // 01927 // N.B. All x86 features test TRUE on PPC systems. 01928 // 01929 01930 #define Isx86FeaturePresent(_f_) TRUE 01931 01932 // 01933 // Symbolic values for exception entry 01934 // 01935 #define ppc_machine_check 1 01936 #define ppc_data_storage 2 01937 #define ppc_instruction_storage 3 01938 #define ppc_external 4 01939 #define ppc_alignment 5 01940 #define ppc_program 6 01941 #define ppc_fp_unavailable 7 01942 #define ppc_decrementer 8 01943 #define ppc_direct_store_error 9 01944 #define ppc_syscall 10 01945 #define ppc_trace 11 01946 #define ppc_fp_assist 12 01947 #define ppc_run_mode 13 01948 01949 #endif // _PPCH_

Generated on Sat May 15 19:41:25 2004 for test by doxygen 1.3.7