Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3282 lines
73 KiB

  1. /*++ BUILD Version: 0014 // Increment this if a change has global effects
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. i386.h
  5. Abstract:
  6. This module contains the i386 hardware specific header file.
  7. Author:
  8. David N. Cutler (davec) 2-Aug-1989
  9. Revision History:
  10. 25-Jan-1990 shielint
  11. Added definitions for 8259 ports and commands and
  12. macros for 8259 irq# and system irql conversion.
  13. --*/
  14. #ifndef _i386_
  15. #define _i386_
  16. // begin_ntddk begin_wdm begin_nthal begin_ntndis begin_ntosp
  17. #if defined(_X86_)
  18. //
  19. // Types to use to contain PFNs and their counts.
  20. //
  21. typedef ULONG PFN_COUNT;
  22. typedef LONG SPFN_NUMBER, *PSPFN_NUMBER;
  23. typedef ULONG PFN_NUMBER, *PPFN_NUMBER;
  24. //
  25. // Define maximum size of flush multiple TB request.
  26. //
  27. #define FLUSH_MULTIPLE_MAXIMUM 32
  28. //
  29. // Indicate that the i386 compiler supports the pragma textout construct.
  30. //
  31. #define ALLOC_PRAGMA 1
  32. //
  33. // Indicate that the i386 compiler supports the DATA_SEG("INIT") and
  34. // DATA_SEG("PAGE") pragmas
  35. //
  36. #define ALLOC_DATA_PRAGMA 1
  37. // end_ntddk end_nthal end_ntndis end_wdm end_ntosp
  38. // NOTE - KiPcr is only useful for PCR references where we know we
  39. // won't get context switched between the call to it and the
  40. // variable reference, OR, were we don't care, (ie TEB pointer)
  41. // NOTE - bryanwi 11 june 90 - we must not macro out things we export
  42. // Things like KeFlushIcache and KeFlushDcache cannot be macroed
  43. // out because external code (like drivers) will want to import
  44. // them by name. Therefore, the defines below that turn them into
  45. // nothing are inappropriate. But this isn't going to hurt us right
  46. // now.
  47. //
  48. // Length on interrupt object dispatch code in longwords.
  49. // (shielint) Reserve 9*4 space for ABIOS stack mapping. If NO
  50. // ABIOS support the size of DISPATCH_LENGTH should be 74.
  51. //
  52. // begin_nthal
  53. #define NORMAL_DISPATCH_LENGTH 106 // ntddk wdm
  54. #define DISPATCH_LENGTH NORMAL_DISPATCH_LENGTH // ntddk wdm
  55. //
  56. // Define constants to access the bits in CR0.
  57. //
  58. #define CR0_PG 0x80000000 // paging
  59. #define CR0_ET 0x00000010 // extension type (80387)
  60. #define CR0_TS 0x00000008 // task switched
  61. #define CR0_EM 0x00000004 // emulate math coprocessor
  62. #define CR0_MP 0x00000002 // math present
  63. #define CR0_PE 0x00000001 // protection enable
  64. //
  65. // More CR0 bits; these only apply to the 80486.
  66. //
  67. #define CR0_CD 0x40000000 // cache disable
  68. #define CR0_NW 0x20000000 // not write-through
  69. #define CR0_AM 0x00040000 // alignment mask
  70. #define CR0_WP 0x00010000 // write protect
  71. #define CR0_NE 0x00000020 // numeric error
  72. //
  73. // CR4 bits; These only apply to Pentium
  74. //
  75. #define CR4_VME 0x00000001 // V86 mode extensions
  76. #define CR4_PVI 0x00000002 // Protected mode virtual interrupts
  77. #define CR4_TSD 0x00000004 // Time stamp disable
  78. #define CR4_DE 0x00000008 // Debugging Extensions
  79. #define CR4_PSE 0x00000010 // Page size extensions
  80. #define CR4_PAE 0x00000020 // Physical address extensions
  81. #define CR4_MCE 0x00000040 // Machine check enable
  82. #define CR4_PGE 0x00000080 // Page global enable
  83. #define CR4_FXSR 0x00000200 // FXSR used by OS
  84. #define CR4_XMMEXCPT 0x00000400 // XMMI used by OS
  85. // end_nthal
  86. //
  87. // Define constants to access ThNpxState
  88. //
  89. #define NPX_STATE_NOT_LOADED (CR0_TS | CR0_MP)
  90. #define NPX_STATE_LOADED 0
  91. //
  92. // External references to the labels defined in int.asm
  93. //
  94. extern ULONG KiInterruptTemplate[NORMAL_DISPATCH_LENGTH];
  95. extern PULONG KiInterruptTemplateObject;
  96. extern PULONG KiInterruptTemplateDispatch;
  97. extern PULONG KiInterruptTemplate2ndDispatch;
  98. // begin_ntddk begin_wdm begin_nthal begin_ntosp
  99. //
  100. // Interrupt Request Level definitions
  101. //
  102. #define PASSIVE_LEVEL 0 // Passive release level
  103. #define LOW_LEVEL 0 // Lowest interrupt level
  104. #define APC_LEVEL 1 // APC interrupt level
  105. #define DISPATCH_LEVEL 2 // Dispatcher level
  106. #define PROFILE_LEVEL 27 // timer used for profiling.
  107. #define CLOCK1_LEVEL 28 // Interval clock 1 level - Not used on x86
  108. #define CLOCK2_LEVEL 28 // Interval clock 2 level
  109. #define IPI_LEVEL 29 // Interprocessor interrupt level
  110. #define POWER_LEVEL 30 // Power failure level
  111. #define HIGH_LEVEL 31 // Highest interrupt level
  112. // end_ntddk end_wdm end_ntosp
  113. #if defined(NT_UP)
  114. // synchronization level - UP system
  115. #define SYNCH_LEVEL DISPATCH_LEVEL
  116. #else
  117. // synchronization level - MP system
  118. #define SYNCH_LEVEL (IPI_LEVEL-2) // ntddk wdm ntosp
  119. #endif
  120. #define KiSynchIrql SYNCH_LEVEL // enable portable code
  121. //
  122. // Machine type definitions
  123. //
  124. #define MACHINE_TYPE_ISA 0
  125. #define MACHINE_TYPE_EISA 1
  126. #define MACHINE_TYPE_MCA 2
  127. // end_nthal
  128. //
  129. // The previous values are or'ed into KeI386MachineType.
  130. //
  131. extern ULONG KeI386MachineType;
  132. // begin_nthal
  133. //
  134. // Define constants used in selector tests.
  135. //
  136. // RPL_MASK is the real value for extracting RPL values. IT IS THE WRONG
  137. // CONSTANT TO USE FOR MODE TESTING.
  138. //
  139. // MODE_MASK is the value for deciding the current mode.
  140. // WARNING: MODE_MASK assumes that all code runs at either ring-0
  141. // or ring-3. Ring-1 or Ring-2 support will require changing
  142. // this value and all of the code that refers to it.
  143. #define MODE_MASK 1 // ntosp
  144. #define RPL_MASK 3
  145. //
  146. // SEGMENT_MASK is used to throw away trash part of segment. Part always
  147. // pushes or pops 32 bits to/from stack, but if it's a segment value,
  148. // high order 16 bits are trash.
  149. //
  150. #define SEGMENT_MASK 0xffff
  151. //
  152. // Startup count value for KeStallExecution. This value is used
  153. // until KiInitializeStallExecution can compute the real one.
  154. // Pick a value long enough for very fast processors.
  155. //
  156. #define INITIAL_STALL_COUNT 100
  157. // end_nthal
  158. //
  159. // begin_nthal
  160. //
  161. // Macro to extract the high word of a long offset
  162. //
  163. #define HIGHWORD(l) \
  164. ((USHORT)(((ULONG)(l)>>16) & 0xffff))
  165. //
  166. // Macro to extract the low word of a long offset
  167. //
  168. #define LOWWORD(l) \
  169. ((USHORT)((ULONG)l & 0x0000ffff))
  170. //
  171. // Macro to combine two USHORT offsets into a long offset
  172. //
  173. #if !defined(MAKEULONG)
  174. #define MAKEULONG(x, y) \
  175. (((((ULONG)(x))<<16) & 0xffff0000) | \
  176. ((ULONG)(y) & 0xffff))
  177. #endif
  178. // end_nthal
  179. //
  180. // Request a software interrupt.
  181. //
  182. #define KiRequestSoftwareInterrupt(RequestIrql) \
  183. HalRequestSoftwareInterrupt( RequestIrql )
  184. // begin_ntddk begin_wdm begin_nthal begin_ntndis begin_ntosp
  185. //
  186. // I/O space read and write macros.
  187. //
  188. // These have to be actual functions on the 386, because we need
  189. // to use assembler, but cannot return a value if we inline it.
  190. //
  191. // The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space.
  192. // (Use x86 move instructions, with LOCK prefix to force correct behavior
  193. // w.r.t. caches and write buffers.)
  194. //
  195. // The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space.
  196. // (Use x86 in/out instructions.)
  197. //
  198. NTKERNELAPI
  199. UCHAR
  200. NTAPI
  201. READ_REGISTER_UCHAR(
  202. PUCHAR Register
  203. );
  204. NTKERNELAPI
  205. USHORT
  206. NTAPI
  207. READ_REGISTER_USHORT(
  208. PUSHORT Register
  209. );
  210. NTKERNELAPI
  211. ULONG
  212. NTAPI
  213. READ_REGISTER_ULONG(
  214. PULONG Register
  215. );
  216. NTKERNELAPI
  217. VOID
  218. NTAPI
  219. READ_REGISTER_BUFFER_UCHAR(
  220. PUCHAR Register,
  221. PUCHAR Buffer,
  222. ULONG Count
  223. );
  224. NTKERNELAPI
  225. VOID
  226. NTAPI
  227. READ_REGISTER_BUFFER_USHORT(
  228. PUSHORT Register,
  229. PUSHORT Buffer,
  230. ULONG Count
  231. );
  232. NTKERNELAPI
  233. VOID
  234. NTAPI
  235. READ_REGISTER_BUFFER_ULONG(
  236. PULONG Register,
  237. PULONG Buffer,
  238. ULONG Count
  239. );
  240. NTKERNELAPI
  241. VOID
  242. NTAPI
  243. WRITE_REGISTER_UCHAR(
  244. PUCHAR Register,
  245. UCHAR Value
  246. );
  247. NTKERNELAPI
  248. VOID
  249. NTAPI
  250. WRITE_REGISTER_USHORT(
  251. PUSHORT Register,
  252. USHORT Value
  253. );
  254. NTKERNELAPI
  255. VOID
  256. NTAPI
  257. WRITE_REGISTER_ULONG(
  258. PULONG Register,
  259. ULONG Value
  260. );
  261. NTKERNELAPI
  262. VOID
  263. NTAPI
  264. WRITE_REGISTER_BUFFER_UCHAR(
  265. PUCHAR Register,
  266. PUCHAR Buffer,
  267. ULONG Count
  268. );
  269. NTKERNELAPI
  270. VOID
  271. NTAPI
  272. WRITE_REGISTER_BUFFER_USHORT(
  273. PUSHORT Register,
  274. PUSHORT Buffer,
  275. ULONG Count
  276. );
  277. NTKERNELAPI
  278. VOID
  279. NTAPI
  280. WRITE_REGISTER_BUFFER_ULONG(
  281. PULONG Register,
  282. PULONG Buffer,
  283. ULONG Count
  284. );
  285. NTHALAPI
  286. UCHAR
  287. NTAPI
  288. READ_PORT_UCHAR(
  289. PUCHAR Port
  290. );
  291. NTHALAPI
  292. USHORT
  293. NTAPI
  294. READ_PORT_USHORT(
  295. PUSHORT Port
  296. );
  297. NTHALAPI
  298. ULONG
  299. NTAPI
  300. READ_PORT_ULONG(
  301. PULONG Port
  302. );
  303. NTHALAPI
  304. VOID
  305. NTAPI
  306. READ_PORT_BUFFER_UCHAR(
  307. PUCHAR Port,
  308. PUCHAR Buffer,
  309. ULONG Count
  310. );
  311. NTHALAPI
  312. VOID
  313. NTAPI
  314. READ_PORT_BUFFER_USHORT(
  315. PUSHORT Port,
  316. PUSHORT Buffer,
  317. ULONG Count
  318. );
  319. NTHALAPI
  320. VOID
  321. NTAPI
  322. READ_PORT_BUFFER_ULONG(
  323. PULONG Port,
  324. PULONG Buffer,
  325. ULONG Count
  326. );
  327. NTHALAPI
  328. VOID
  329. NTAPI
  330. WRITE_PORT_UCHAR(
  331. PUCHAR Port,
  332. UCHAR Value
  333. );
  334. NTHALAPI
  335. VOID
  336. NTAPI
  337. WRITE_PORT_USHORT(
  338. PUSHORT Port,
  339. USHORT Value
  340. );
  341. NTHALAPI
  342. VOID
  343. NTAPI
  344. WRITE_PORT_ULONG(
  345. PULONG Port,
  346. ULONG Value
  347. );
  348. NTHALAPI
  349. VOID
  350. NTAPI
  351. WRITE_PORT_BUFFER_UCHAR(
  352. PUCHAR Port,
  353. PUCHAR Buffer,
  354. ULONG Count
  355. );
  356. NTHALAPI
  357. VOID
  358. NTAPI
  359. WRITE_PORT_BUFFER_USHORT(
  360. PUSHORT Port,
  361. PUSHORT Buffer,
  362. ULONG Count
  363. );
  364. NTHALAPI
  365. VOID
  366. NTAPI
  367. WRITE_PORT_BUFFER_ULONG(
  368. PULONG Port,
  369. PULONG Buffer,
  370. ULONG Count
  371. );
  372. // end_ntndis
  373. //
  374. // Get data cache fill size.
  375. //
  376. #if PRAGMA_DEPRECATED_DDK
  377. #pragma deprecated(KeGetDcacheFillSize) // Use GetDmaAlignment
  378. #endif
  379. #define KeGetDcacheFillSize() 1L
  380. // end_ntddk end_wdm end_nthal end_ntosp
  381. //
  382. // Fill TB entry.
  383. //
  384. #define KeFillEntryTb(Virtual) \
  385. KiFlushSingleTb (Virtual);
  386. #if !defined(MIDL_PASS) && defined(_M_IX86) && !defined(_CROSS_PLATFORM_)
  387. FORCEINLINE
  388. VOID
  389. KiFlushSingleTb (
  390. IN PVOID Virtual
  391. )
  392. {
  393. __asm {
  394. mov eax, Virtual
  395. invlpg [eax]
  396. }
  397. }
  398. FORCEINLINE
  399. VOID
  400. KiFlushProcessTb (
  401. VOID
  402. )
  403. {
  404. __asm {
  405. mov eax, cr3
  406. mov cr3, eax
  407. }
  408. }
  409. #endif
  410. NTKERNELAPI // nthal
  411. VOID // nthal
  412. KeFlushCurrentTb ( // nthal
  413. VOID // nthal
  414. ); // nthal
  415. // nthal
  416. //
  417. // Data cache, instruction cache, I/O buffer, and write buffer flush routine
  418. // prototypes.
  419. //
  420. // 386 and 486 have transparent caches, so these are noops.
  421. #define KeSweepDcache(AllProcessors)
  422. #define KeSweepCurrentDcache()
  423. #define KeSweepIcache(AllProcessors)
  424. #define KeSweepCurrentIcache()
  425. #define KeSweepIcacheRange(AllProcessors, BaseAddress, Length)
  426. // begin_ntddk begin_wdm begin_nthal begin_ntndis begin_ntosp
  427. #define KeFlushIoBuffers(Mdl, ReadOperation, DmaOperation)
  428. // end_ntddk end_wdm end_ntndis end_ntosp
  429. #define KeYieldProcessor() __asm { rep nop }
  430. // end_nthal
  431. //
  432. // Define executive macros for acquiring and releasing executive spinlocks.
  433. // These macros can ONLY be used by executive components and NOT by drivers.
  434. // Drivers MUST use the kernel interfaces since they must be MP enabled on
  435. // all systems.
  436. //
  437. // KeRaiseIrql is one instruction longer than KeAcquireSpinLock on x86 UP.
  438. // KeLowerIrql and KeReleaseSpinLock are the same.
  439. //
  440. #if defined(NT_UP) && !DBG && !defined(_NTDDK_) && !defined(_NTIFS_)
  441. #if !defined(_NTDRIVER_)
  442. #define ExAcquireSpinLock(Lock, OldIrql) (*OldIrql) = KeRaiseIrqlToDpcLevel();
  443. #define ExReleaseSpinLock(Lock, OldIrql) KeLowerIrql((OldIrql))
  444. #else
  445. #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql))
  446. #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql))
  447. #endif
  448. #define ExAcquireSpinLockAtDpcLevel(Lock)
  449. #define ExReleaseSpinLockFromDpcLevel(Lock)
  450. #else
  451. // begin_wdm begin_ntddk begin_ntosp
  452. #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql))
  453. #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql))
  454. #define ExAcquireSpinLockAtDpcLevel(Lock) KeAcquireSpinLockAtDpcLevel(Lock)
  455. #define ExReleaseSpinLockFromDpcLevel(Lock) KeReleaseSpinLockFromDpcLevel(Lock)
  456. // end_wdm end_ntddk end_ntosp
  457. #endif
  458. //
  459. // The acquire and release fast lock macros disable and enable interrupts
  460. // on UP nondebug systems. On MP or debug systems, the spinlock routines
  461. // are used.
  462. //
  463. // N.B. Extreme caution should be observed when using these routines.
  464. //
  465. #if defined(_M_IX86) && !defined(USER_MODE_CODE)
  466. #if _MSC_VER >= 1200
  467. #pragma warning(push)
  468. #endif
  469. #pragma warning(disable:4164)
  470. #pragma intrinsic(_disable)
  471. #pragma intrinsic(_enable)
  472. #if _MSC_VER >= 1200
  473. #pragma warning(pop)
  474. #else
  475. #pragma warning(default:4164)
  476. #endif
  477. #endif
  478. #if defined(NT_UP) && !DBG && !defined(USER_MODE_CODE)
  479. #define ExAcquireFastLock(Lock, OldIrql) _disable()
  480. #else
  481. #define ExAcquireFastLock(Lock, OldIrql) \
  482. ExAcquireSpinLock(Lock, OldIrql)
  483. #endif
  484. #if defined(NT_UP) && !DBG && !defined(USER_MODE_CODE)
  485. #define ExReleaseFastLock(Lock, OldIrql) _enable()
  486. #else
  487. #define ExReleaseFastLock(Lock, OldIrql) \
  488. ExReleaseSpinLock(Lock, OldIrql)
  489. #endif
  490. //
  491. // The following function prototypes must be in this module so that the
  492. // above macros can call them directly.
  493. //
  494. // begin_nthal
  495. VOID
  496. FASTCALL
  497. KiAcquireSpinLock (
  498. IN PKSPIN_LOCK SpinLock
  499. );
  500. VOID
  501. FASTCALL
  502. KiReleaseSpinLock (
  503. IN PKSPIN_LOCK SpinLock
  504. );
  505. // end_nthal
  506. //
  507. // Define query tick count macro.
  508. //
  509. // begin_ntddk begin_nthal begin_ntosp
  510. #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_)
  511. // begin_wdm
  512. #define KeQueryTickCount(CurrentCount ) { \
  513. volatile PKSYSTEM_TIME _TickCount = *((PKSYSTEM_TIME *)(&KeTickCount)); \
  514. while (TRUE) { \
  515. (CurrentCount)->HighPart = _TickCount->High1Time; \
  516. (CurrentCount)->LowPart = _TickCount->LowPart; \
  517. if ((CurrentCount)->HighPart == _TickCount->High2Time) break; \
  518. _asm { rep nop } \
  519. } \
  520. }
  521. // end_wdm
  522. #else
  523. // end_ntddk end_nthal end_ntosp
  524. //
  525. // Define query tick count macro.
  526. //
  527. #define KiQueryTickCount(CurrentCount) \
  528. while (TRUE) { \
  529. (CurrentCount)->HighPart = KeTickCount.High1Time; \
  530. (CurrentCount)->LowPart = KeTickCount.LowPart; \
  531. if ((CurrentCount)->HighPart == KeTickCount.High2Time) break; \
  532. _asm { rep nop } \
  533. }
  534. //
  535. // Define query interrupt time macro.
  536. //
  537. #define KiQueryInterruptTime(CurrentTime) \
  538. while (TRUE) { \
  539. (CurrentTime)->HighPart = SharedUserData->InterruptTime.High1Time; \
  540. (CurrentTime)->LowPart = SharedUserData->InterruptTime.LowPart; \
  541. if ((CurrentTime)->HighPart == SharedUserData->InterruptTime.High2Time) break; \
  542. _asm { rep nop } \
  543. }
  544. // begin_ntddk begin_nthal begin_ntosp
  545. VOID
  546. NTAPI
  547. KeQueryTickCount (
  548. OUT PLARGE_INTEGER CurrentCount
  549. );
  550. #endif // defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_)
  551. // end_ntddk end_nthal end_ntosp
  552. // begin_nthal begin_ntosp
  553. //
  554. // 386 hardware structures
  555. //
  556. //
  557. // A Page Table Entry on an Intel 386/486 has the following definition.
  558. //
  559. // **** NOTE A PRIVATE COPY OF THIS EXISTS IN THE MM\I386 DIRECTORY! ****
  560. // **** ANY CHANGES NEED TO BE MADE TO BOTH HEADER FILES. ****
  561. //
  562. typedef struct _HARDWARE_PTE_X86 {
  563. ULONG Valid : 1;
  564. ULONG Write : 1;
  565. ULONG Owner : 1;
  566. ULONG WriteThrough : 1;
  567. ULONG CacheDisable : 1;
  568. ULONG Accessed : 1;
  569. ULONG Dirty : 1;
  570. ULONG LargePage : 1;
  571. ULONG Global : 1;
  572. ULONG CopyOnWrite : 1; // software field
  573. ULONG Prototype : 1; // software field
  574. ULONG reserved : 1; // software field
  575. ULONG PageFrameNumber : 20;
  576. } HARDWARE_PTE_X86, *PHARDWARE_PTE_X86;
  577. typedef struct _HARDWARE_PTE_X86PAE {
  578. union {
  579. struct {
  580. ULONGLONG Valid : 1;
  581. ULONGLONG Write : 1;
  582. ULONGLONG Owner : 1;
  583. ULONGLONG WriteThrough : 1;
  584. ULONGLONG CacheDisable : 1;
  585. ULONGLONG Accessed : 1;
  586. ULONGLONG Dirty : 1;
  587. ULONGLONG LargePage : 1;
  588. ULONGLONG Global : 1;
  589. ULONGLONG CopyOnWrite : 1; // software field
  590. ULONGLONG Prototype : 1; // software field
  591. ULONGLONG reserved0 : 1; // software field
  592. ULONGLONG PageFrameNumber : 26;
  593. ULONGLONG reserved1 : 26; // software field
  594. };
  595. struct {
  596. ULONG LowPart;
  597. ULONG HighPart;
  598. };
  599. };
  600. } HARDWARE_PTE_X86PAE, *PHARDWARE_PTE_X86PAE;
  601. //
  602. // Special check to work around mspdb limitation
  603. //
  604. #if defined (_NTSYM_HARDWARE_PTE_SYMBOL_)
  605. #if !defined (_X86PAE_)
  606. typedef struct _HARDWARE_PTE {
  607. ULONG Valid : 1;
  608. ULONG Write : 1;
  609. ULONG Owner : 1;
  610. ULONG WriteThrough : 1;
  611. ULONG CacheDisable : 1;
  612. ULONG Accessed : 1;
  613. ULONG Dirty : 1;
  614. ULONG LargePage : 1;
  615. ULONG Global : 1;
  616. ULONG CopyOnWrite : 1; // software field
  617. ULONG Prototype : 1; // software field
  618. ULONG reserved : 1; // software field
  619. ULONG PageFrameNumber : 20;
  620. } HARDWARE_PTE, *PHARDWARE_PTE;
  621. #else
  622. typedef struct _HARDWARE_PTE {
  623. union {
  624. struct {
  625. ULONGLONG Valid : 1;
  626. ULONGLONG Write : 1;
  627. ULONGLONG Owner : 1;
  628. ULONGLONG WriteThrough : 1;
  629. ULONGLONG CacheDisable : 1;
  630. ULONGLONG Accessed : 1;
  631. ULONGLONG Dirty : 1;
  632. ULONGLONG LargePage : 1;
  633. ULONGLONG Global : 1;
  634. ULONGLONG CopyOnWrite : 1; // software field
  635. ULONGLONG Prototype : 1; // software field
  636. ULONGLONG reserved0 : 1; // software field
  637. ULONGLONG PageFrameNumber : 26;
  638. ULONGLONG reserved1 : 26; // software field
  639. };
  640. struct {
  641. ULONG LowPart;
  642. ULONG HighPart;
  643. };
  644. };
  645. } HARDWARE_PTE, *PHARDWARE_PTE;
  646. #endif
  647. #else
  648. #if !defined (_X86PAE_)
  649. typedef HARDWARE_PTE_X86 HARDWARE_PTE;
  650. typedef PHARDWARE_PTE_X86 PHARDWARE_PTE;
  651. #else
  652. typedef HARDWARE_PTE_X86PAE HARDWARE_PTE;
  653. typedef PHARDWARE_PTE_X86PAE PHARDWARE_PTE;
  654. #endif
  655. #endif
  656. //
  657. // GDT Entry
  658. //
  659. typedef struct _KGDTENTRY {
  660. USHORT LimitLow;
  661. USHORT BaseLow;
  662. union {
  663. struct {
  664. UCHAR BaseMid;
  665. UCHAR Flags1; // Declare as bytes to avoid alignment
  666. UCHAR Flags2; // Problems.
  667. UCHAR BaseHi;
  668. } Bytes;
  669. struct {
  670. ULONG BaseMid : 8;
  671. ULONG Type : 5;
  672. ULONG Dpl : 2;
  673. ULONG Pres : 1;
  674. ULONG LimitHi : 4;
  675. ULONG Sys : 1;
  676. ULONG Reserved_0 : 1;
  677. ULONG Default_Big : 1;
  678. ULONG Granularity : 1;
  679. ULONG BaseHi : 8;
  680. } Bits;
  681. } HighWord;
  682. } KGDTENTRY, *PKGDTENTRY;
  683. #define TYPE_CODE 0x10 // 11010 = Code, Readable, NOT Conforming, Accessed
  684. #define TYPE_DATA 0x12 // 10010 = Data, ReadWrite, NOT Expanddown, Accessed
  685. #define TYPE_TSS 0x01 // 01001 = NonBusy TSS
  686. #define TYPE_LDT 0x02 // 00010 = LDT
  687. #define DPL_USER 3
  688. #define DPL_SYSTEM 0
  689. #define GRAN_BYTE 0
  690. #define GRAN_PAGE 1
  691. #define SELECTOR_TABLE_INDEX 0x04
  692. #define IDT_NMI_VECTOR 2
  693. #define IDT_DFH_VECTOR 8
  694. #define NMI_TSS_DESC_OFFSET 0x58
  695. #define DF_TSS_DESC_OFFSET 0x50
  696. //
  697. // Entry of Interrupt Descriptor Table (IDTENTRY)
  698. //
  699. typedef struct _KIDTENTRY {
  700. USHORT Offset;
  701. USHORT Selector;
  702. USHORT Access;
  703. USHORT ExtendedOffset;
  704. } KIDTENTRY;
  705. typedef KIDTENTRY *PKIDTENTRY;
  706. //
  707. // TSS (Task switch segment) NT only uses to control stack switches.
  708. //
  709. // The only fields we actually care about are Esp0, Ss0, the IoMapBase
  710. // and the IoAccessMaps themselves.
  711. //
  712. //
  713. // N.B. Size of TSS must be <= 0xDFFF
  714. //
  715. //
  716. // The interrupt direction bitmap is used on Pentium to allow
  717. // the processor to emulate V86 mode software interrupts for us.
  718. // There is one for each IOPM. It is located by subtracting
  719. // 32 from the IOPM base in the Tss.
  720. //
  721. #define INT_DIRECTION_MAP_SIZE 32
  722. typedef UCHAR KINT_DIRECTION_MAP[INT_DIRECTION_MAP_SIZE];
  723. #define IOPM_COUNT 1 // Number of i/o access maps that
  724. // exist (in addition to
  725. // IO_ACCESS_MAP_NONE)
  726. #define IO_ACCESS_MAP_NONE 0
  727. #define IOPM_SIZE 8192 // Size of map callers can set.
  728. #define PIOPM_SIZE 8196 // Size of structure we must allocate
  729. // to hold it.
  730. typedef UCHAR KIO_ACCESS_MAP[IOPM_SIZE];
  731. typedef KIO_ACCESS_MAP *PKIO_ACCESS_MAP;
  732. typedef struct _KiIoAccessMap {
  733. KINT_DIRECTION_MAP DirectionMap;
  734. UCHAR IoMap[PIOPM_SIZE];
  735. } KIIO_ACCESS_MAP;
  736. typedef struct _KTSS {
  737. USHORT Backlink;
  738. USHORT Reserved0;
  739. ULONG Esp0;
  740. USHORT Ss0;
  741. USHORT Reserved1;
  742. ULONG NotUsed1[4];
  743. ULONG CR3;
  744. ULONG Eip;
  745. ULONG EFlags;
  746. ULONG Eax;
  747. ULONG Ecx;
  748. ULONG Edx;
  749. ULONG Ebx;
  750. ULONG Esp;
  751. ULONG Ebp;
  752. ULONG Esi;
  753. ULONG Edi;
  754. USHORT Es;
  755. USHORT Reserved2;
  756. USHORT Cs;
  757. USHORT Reserved3;
  758. USHORT Ss;
  759. USHORT Reserved4;
  760. USHORT Ds;
  761. USHORT Reserved5;
  762. USHORT Fs;
  763. USHORT Reserved6;
  764. USHORT Gs;
  765. USHORT Reserved7;
  766. USHORT LDT;
  767. USHORT Reserved8;
  768. USHORT Flags;
  769. USHORT IoMapBase;
  770. KIIO_ACCESS_MAP IoMaps[IOPM_COUNT];
  771. //
  772. // This is the Software interrupt direction bitmap associated with
  773. // IO_ACCESS_MAP_NONE
  774. //
  775. KINT_DIRECTION_MAP IntDirectionMap;
  776. } KTSS, *PKTSS;
  777. #define KiComputeIopmOffset(MapNumber) \
  778. (MapNumber == IO_ACCESS_MAP_NONE) ? \
  779. (USHORT)(sizeof(KTSS)) : \
  780. (USHORT)(FIELD_OFFSET(KTSS, IoMaps[MapNumber-1].IoMap))
  781. // begin_windbgkd
  782. //
  783. // Special Registers for i386
  784. //
  785. #ifdef _X86_
  786. typedef struct _DESCRIPTOR {
  787. USHORT Pad;
  788. USHORT Limit;
  789. ULONG Base;
  790. } KDESCRIPTOR, *PKDESCRIPTOR;
  791. typedef struct _KSPECIAL_REGISTERS {
  792. ULONG Cr0;
  793. ULONG Cr2;
  794. ULONG Cr3;
  795. ULONG Cr4;
  796. ULONG KernelDr0;
  797. ULONG KernelDr1;
  798. ULONG KernelDr2;
  799. ULONG KernelDr3;
  800. ULONG KernelDr6;
  801. ULONG KernelDr7;
  802. KDESCRIPTOR Gdtr;
  803. KDESCRIPTOR Idtr;
  804. USHORT Tr;
  805. USHORT Ldtr;
  806. ULONG Reserved[6];
  807. } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
  808. //
  809. // Processor State frame: Before a processor freezes itself, it
  810. // dumps the processor state to the processor state frame for
  811. // debugger to examine.
  812. //
  813. typedef struct _KPROCESSOR_STATE {
  814. struct _CONTEXT ContextFrame;
  815. struct _KSPECIAL_REGISTERS SpecialRegisters;
  816. } KPROCESSOR_STATE, *PKPROCESSOR_STATE;
  817. #endif // _X86_
  818. // end_windbgkd
  819. //
  820. // DPC data structure definition.
  821. //
  822. typedef struct _KDPC_DATA {
  823. LIST_ENTRY DpcListHead;
  824. KSPIN_LOCK DpcLock;
  825. volatile ULONG DpcQueueDepth;
  826. ULONG DpcCount;
  827. } KDPC_DATA, *PKDPC_DATA;
  828. //
  829. // Processor Control Block (PRCB)
  830. //
  831. #define PRCB_MAJOR_VERSION 1
  832. #define PRCB_MINOR_VERSION 1
  833. #define PRCB_BUILD_DEBUG 0x0001
  834. #define PRCB_BUILD_UNIPROCESSOR 0x0002
  835. typedef struct _KPRCB {
  836. //
  837. // Start of the architecturally defined section of the PRCB. This section
  838. // may be directly addressed by vendor/platform specific HAL code and will
  839. // not change from version to version of NT.
  840. //
  841. USHORT MinorVersion;
  842. USHORT MajorVersion;
  843. struct _KTHREAD *CurrentThread;
  844. struct _KTHREAD *NextThread;
  845. struct _KTHREAD *IdleThread;
  846. CCHAR Number;
  847. CCHAR Reserved;
  848. USHORT BuildType;
  849. KAFFINITY SetMember;
  850. CCHAR CpuType;
  851. CCHAR CpuID;
  852. USHORT CpuStep;
  853. struct _KPROCESSOR_STATE ProcessorState;
  854. ULONG KernelReserved[16]; // For use by the kernel
  855. ULONG HalReserved[16]; // For use by Hal
  856. //
  857. // Per processor lock queue entries.
  858. //
  859. // N.B. The following padding is such that the first lock entry falls in the
  860. // last eight bytes of a cache line. This makes the dispatcher lock and
  861. // the context swap lock lie in separate cache lines.
  862. //
  863. UCHAR PrcbPad0[28 + 64];
  864. KSPIN_LOCK_QUEUE LockQueue[16];
  865. UCHAR PrcbPad1[8];
  866. // End of the architecturally defined section of the PRCB.
  867. // end_nthal end_ntosp
  868. //
  869. // Micellaneous counters - 64-byte aligned.
  870. //
  871. struct _KTHREAD *NpxThread;
  872. ULONG InterruptCount;
  873. ULONG KernelTime;
  874. ULONG UserTime;
  875. ULONG DpcTime;
  876. ULONG DebugDpcTime;
  877. ULONG InterruptTime;
  878. ULONG AdjustDpcThreshold;
  879. ULONG PageColor;
  880. BOOLEAN SkipTick;
  881. KIRQL DebuggerSavedIRQL;
  882. UCHAR Spare1[6];
  883. struct _KNODE *ParentNode;
  884. KAFFINITY MultiThreadProcessorSet;
  885. struct _KPRCB * MultiThreadSetMaster;
  886. ULONG ThreadStartCount[2];
  887. //
  888. // Performance counters - 64-byte aligned.
  889. //
  890. // Cache manager performance counters.
  891. //
  892. ULONG CcFastReadNoWait;
  893. ULONG CcFastReadWait;
  894. ULONG CcFastReadNotPossible;
  895. ULONG CcCopyReadNoWait;
  896. ULONG CcCopyReadWait;
  897. ULONG CcCopyReadNoWaitMiss;
  898. //
  899. // Kernel performance counters.
  900. //
  901. ULONG KeAlignmentFixupCount;
  902. ULONG SpareCounter0;
  903. ULONG KeDcacheFlushCount;
  904. ULONG KeExceptionDispatchCount;
  905. ULONG KeFirstLevelTbFills;
  906. ULONG KeFloatingEmulationCount;
  907. ULONG KeIcacheFlushCount;
  908. ULONG KeSecondLevelTbFills;
  909. ULONG KeSystemCalls;
  910. ULONG SpareCounter1;
  911. //
  912. // Nonpaged per processor lookaside lists - 64-byte aligned.
  913. //
  914. PP_LOOKASIDE_LIST PPLookasideList[16];
  915. //
  916. // Nonpaged per processor small pool lookaside lists - 64-byte aligned.
  917. //
  918. PP_LOOKASIDE_LIST PPNPagedLookasideList[POOL_SMALL_LISTS];
  919. //
  920. // Paged per processor small pool lookaside lists - 64-byte aligned.
  921. //
  922. PP_LOOKASIDE_LIST PPPagedLookasideList[POOL_SMALL_LISTS];
  923. //
  924. // MP interprocessor request packet barrier - 64-byte aligned.
  925. //
  926. volatile KAFFINITY PacketBarrier;
  927. volatile ULONG ReverseStall;
  928. PVOID IpiFrame;
  929. UCHAR PrcbPad2[52];
  930. //
  931. // MP interprocessor request packet and summary - 64-byte aligned.
  932. //
  933. volatile PVOID CurrentPacket[3];
  934. volatile KAFFINITY TargetSet;
  935. volatile PKIPI_WORKER WorkerRoutine;
  936. volatile ULONG IpiFrozen;
  937. UCHAR PrcbPad3[40];
  938. //
  939. // MP interprocessor request summary and packet address - 64-byte aligned.
  940. //
  941. volatile ULONG RequestSummary;
  942. volatile struct _KPRCB *SignalDone;
  943. UCHAR PrcbPad4[56];
  944. //
  945. // DPC listhead, counts, and batching parameters - 64-byte aligned.
  946. //
  947. KDPC_DATA DpcData[2];
  948. PVOID DpcStack;
  949. ULONG MaximumDpcQueueDepth;
  950. ULONG DpcRequestRate;
  951. ULONG MinimumDpcRate;
  952. volatile BOOLEAN DpcInterruptRequested;
  953. volatile BOOLEAN DpcThreadRequested;
  954. //
  955. // N.B. the following two fields must be on a word boundary.
  956. //
  957. volatile BOOLEAN DpcRoutineActive;
  958. volatile BOOLEAN DpcThreadActive;
  959. KSPIN_LOCK PrcbLock;
  960. ULONG DpcLastCount;
  961. volatile ULONG TimerHand;
  962. volatile ULONG TimerRequest;
  963. PVOID DpcThread;
  964. KEVENT DpcEvent;
  965. BOOLEAN ThreadDpcEnable;
  966. volatile BOOLEAN QuantumEnd;
  967. UCHAR PrcbPad50;
  968. volatile BOOLEAN IdleSchedule;
  969. LONG DpcSetEventRequest;
  970. UCHAR PrcbPad5[22];
  971. //
  972. // Generic call DPC - 64-byte aligned.
  973. //
  974. KDPC CallDpc;
  975. ULONG PrcbPad7[8];
  976. //
  977. // Per-processor ready summary and ready queues - 64-byte aligned.
  978. //
  979. // N.B. Ready summary is in the first cache line as the queue for priority
  980. // zero is never used.
  981. //
  982. LIST_ENTRY WaitListHead;
  983. ULONG ReadySummary;
  984. ULONG SelectNextLast;
  985. LIST_ENTRY DispatcherReadyListHead[MAXIMUM_PRIORITY];
  986. SINGLE_LIST_ENTRY DeferredReadyListHead;
  987. ULONG PrcbPad72[11];
  988. //
  989. // Per processor chained interrupt list - 64-byte aligned.
  990. //
  991. PVOID ChainedInterruptList;
  992. //
  993. // I/O IRP float.
  994. //
  995. LONG LookasideIrpFloat;
  996. //
  997. // Spare fields.
  998. //
  999. ULONG SpareFields0[4];
  1000. //
  1001. // Processor information.
  1002. //
  1003. UCHAR VendorString[13];
  1004. UCHAR InitialApicId;
  1005. UCHAR LogicalProcessorsPerPhysicalProcessor;
  1006. ULONG MHz;
  1007. ULONG FeatureBits;
  1008. LARGE_INTEGER UpdateSignature;
  1009. //
  1010. // ISR timing data.
  1011. //
  1012. volatile ULONGLONG IsrTime;
  1013. //
  1014. // Npx save area - 16-byte aligned.
  1015. //
  1016. FX_SAVE_AREA NpxSaveArea;
  1017. //
  1018. // Processors power state
  1019. //
  1020. PROCESSOR_POWER_STATE PowerState;
  1021. // begin_nthal begin_ntosp
  1022. } KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB;
  1023. // end_nthal end_ntosp
  1024. //
  1025. // The offset of the PRCB in the PCR is 32 mod 64.
  1026. //
  1027. // The offset of the following structure must be 0 mod 64 except for the
  1028. // lock queue array which straddles two cache lines.
  1029. //
  1030. C_ASSERT(((FIELD_OFFSET(KPRCB, LockQueue) + sizeof(KSPIN_LOCK_QUEUE) + 32) & (64 - 1)) == 0);
  1031. C_ASSERT(((FIELD_OFFSET(KPRCB, NpxThread) + 32) & (64 - 1)) == 0);
  1032. C_ASSERT(((FIELD_OFFSET(KPRCB, CcFastReadNoWait) + 32) & (64 - 1)) == 0);
  1033. C_ASSERT(((FIELD_OFFSET(KPRCB, PPLookasideList) + 32) & (64 - 1)) == 0);
  1034. C_ASSERT(((FIELD_OFFSET(KPRCB, PPNPagedLookasideList) + 32) & (64 - 1)) == 0);
  1035. C_ASSERT(((FIELD_OFFSET(KPRCB, PPPagedLookasideList) + 32) & (64 - 1)) == 0);
  1036. C_ASSERT(((FIELD_OFFSET(KPRCB, PacketBarrier) + 32) & (64 - 1)) == 0);
  1037. C_ASSERT(((FIELD_OFFSET(KPRCB, CurrentPacket) + 32) & (64 - 1)) == 0);
  1038. C_ASSERT(((FIELD_OFFSET(KPRCB, DpcData) + 32) & (64 - 1)) == 0);
  1039. C_ASSERT(((FIELD_OFFSET(KPRCB, DpcRoutineActive)) & (1)) == 0);
  1040. C_ASSERT(((FIELD_OFFSET(KPRCB, CallDpc) + 32) & (64 - 1)) == 0);
  1041. C_ASSERT(((FIELD_OFFSET(KPRCB, WaitListHead) + 32) & (64 - 1)) == 0);
  1042. C_ASSERT(((FIELD_OFFSET(KPRCB, ChainedInterruptList) + 32) & (64 - 1)) == 0);
  1043. C_ASSERT(((FIELD_OFFSET(KPRCB, NpxSaveArea) + 32) & (16 - 1)) == 0);
  1044. // begin_nthal begin_ntddk begin_ntosp
  1045. //
  1046. // Processor Control Region Structure Definition
  1047. //
  1048. #define PCR_MINOR_VERSION 1
  1049. #define PCR_MAJOR_VERSION 1
  1050. typedef struct _KPCR {
  1051. //
  1052. // Start of the architecturally defined section of the PCR. This section
  1053. // may be directly addressed by vendor/platform specific HAL code and will
  1054. // not change from version to version of NT.
  1055. //
  1056. // Certain fields in the TIB are not used in kernel mode. These include the
  1057. // stack limit, subsystem TIB, fiber data, arbitrary user pointer, and the
  1058. // self address of then PCR itself (another field has been added for that
  1059. // purpose). Therefore, these fields are overlaid with other data to get
  1060. // better cache locality.
  1061. //
  1062. union {
  1063. NT_TIB NtTib;
  1064. struct {
  1065. struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList;
  1066. PVOID Used_StackBase;
  1067. PVOID PerfGlobalGroupMask;
  1068. PVOID TssCopy;
  1069. ULONG ContextSwitches;
  1070. KAFFINITY SetMemberCopy;
  1071. PVOID Used_Self;
  1072. };
  1073. };
  1074. struct _KPCR *SelfPcr; // flat address of this PCR
  1075. struct _KPRCB *Prcb; // pointer to Prcb
  1076. KIRQL Irql; // do not use 3 bytes after this as
  1077. // HALs assume they are zero.
  1078. ULONG IRR;
  1079. ULONG IrrActive;
  1080. ULONG IDR;
  1081. PVOID KdVersionBlock;
  1082. struct _KIDTENTRY *IDT;
  1083. struct _KGDTENTRY *GDT;
  1084. struct _KTSS *TSS;
  1085. USHORT MajorVersion;
  1086. USHORT MinorVersion;
  1087. KAFFINITY SetMember;
  1088. ULONG StallScaleFactor;
  1089. UCHAR SpareUnused;
  1090. UCHAR Number;
  1091. // end_ntddk end_ntosp
  1092. UCHAR Spare0;
  1093. UCHAR SecondLevelCacheAssociativity;
  1094. ULONG VdmAlert;
  1095. ULONG KernelReserved[14]; // For use by the kernel
  1096. ULONG SecondLevelCacheSize;
  1097. ULONG HalReserved[16]; // For use by Hal
  1098. // End of the architecturally defined section of the PCR.
  1099. // end_nthal
  1100. ULONG InterruptMode;
  1101. UCHAR Spare1;
  1102. ULONG KernelReserved2[17];
  1103. struct _KPRCB PrcbData;
  1104. // begin_nthal begin_ntddk begin_ntosp
  1105. } KPCR, *PKPCR;
  1106. // end_nthal end_ntddk end_ntosp
  1107. C_ASSERT(FIELD_OFFSET(KPCR, NtTib.ExceptionList) == FIELD_OFFSET(KPCR, Used_ExceptionList));
  1108. C_ASSERT(FIELD_OFFSET(KPCR, NtTib.StackBase) == FIELD_OFFSET(KPCR, Used_StackBase));
  1109. C_ASSERT(FIELD_OFFSET(KPCR, NtTib.StackLimit) == FIELD_OFFSET(KPCR, PerfGlobalGroupMask));
  1110. C_ASSERT(FIELD_OFFSET(KPCR, NtTib.SubSystemTib) == FIELD_OFFSET(KPCR, TssCopy));
  1111. C_ASSERT(FIELD_OFFSET(KPCR, NtTib.FiberData) == FIELD_OFFSET(KPCR, ContextSwitches));
  1112. C_ASSERT(FIELD_OFFSET(KPCR, NtTib.ArbitraryUserPointer) == FIELD_OFFSET(KPCR, SetMemberCopy));
  1113. C_ASSERT(FIELD_OFFSET(KPCR, NtTib.Self) == FIELD_OFFSET(KPCR, Used_Self));
  1114. C_ASSERT((FIELD_OFFSET(KPCR, PrcbData) & (64 - 1)) == 32);
  1115. FORCEINLINE
  1116. ULONG
  1117. KeGetContextSwitches (
  1118. PKPRCB Prcb
  1119. )
  1120. {
  1121. PKPCR Pcr;
  1122. Pcr = CONTAINING_RECORD(Prcb, KPCR, PrcbData);
  1123. return Pcr->ContextSwitches;
  1124. }
  1125. // begin_nthal begin_ntosp
  1126. //
  1127. // bits defined in Eflags
  1128. //
  1129. #define EFLAGS_CF_MASK 0x00000001L
  1130. #define EFLAGS_PF_MASK 0x00000004L
  1131. #define EFLAGS_AF_MASK 0x00000010L
  1132. #define EFLAGS_ZF_MASK 0x00000040L
  1133. #define EFLAGS_SF_MASK 0x00000080L
  1134. #define EFLAGS_TF 0x00000100L
  1135. #define EFLAGS_INTERRUPT_MASK 0x00000200L
  1136. #define EFLAGS_DF_MASK 0x00000400L
  1137. #define EFLAGS_OF_MASK 0x00000800L
  1138. #define EFLAGS_IOPL_MASK 0x00003000L
  1139. #define EFLAGS_NT 0x00004000L
  1140. #define EFLAGS_RF 0x00010000L
  1141. #define EFLAGS_V86_MASK 0x00020000L
  1142. #define EFLAGS_ALIGN_CHECK 0x00040000L
  1143. #define EFLAGS_VIF 0x00080000L
  1144. #define EFLAGS_VIP 0x00100000L
  1145. #define EFLAGS_ID_MASK 0x00200000L
  1146. #define EFLAGS_USER_SANITIZE 0x003f4dd7L
  1147. // end_nthal
  1148. //
  1149. // Sanitize segCS and eFlags based on a processor mode.
  1150. //
  1151. // If kernel mode,
  1152. // force CPL == 0
  1153. //
  1154. // If user mode,
  1155. // force CPL == 3
  1156. //
  1157. #define SANITIZE_SEG(segCS, mode) (\
  1158. ((mode) == KernelMode ? \
  1159. ((0x00000000L) | ((segCS) & 0xfffc)) : \
  1160. ((0x00000003L) | ((segCS) & 0xffff))))
  1161. //
  1162. // If kernel mode, then
  1163. // let caller specify Carry, Parity, AuxCarry, Zero, Sign, Trap,
  1164. // Direction, Overflow, Interrupt, AlignCheck.
  1165. //
  1166. // If user mode, then
  1167. // let caller specify Carry, Parity, AuxCarry, Zero, Sign, Trap,
  1168. // Direction, Overflow, AlignCheck.
  1169. // force Interrupts on.
  1170. //
  1171. #define SANITIZE_FLAGS(eFlags, mode) (\
  1172. ((mode) == KernelMode ? \
  1173. ((0x00000000L) | ((eFlags) & 0x003f0fd7)) : \
  1174. ((EFLAGS_INTERRUPT_MASK) | ((eFlags) & EFLAGS_USER_SANITIZE))))
  1175. //
  1176. // Masks for Dr7 and sanitize macros for various Dr registers.
  1177. //
  1178. #define DR6_LEGAL 0x0000e00f
  1179. #define DR7_LEGAL 0xffff0155 // R/W, LEN for Dr0-Dr4,
  1180. // Local enable for Dr0-Dr4,
  1181. // Le for "perfect" trapping
  1182. #define DR7_ACTIVE 0x00000055 // If any of these bits are set, a Dr is active
  1183. #define SANITIZE_DR6(Dr6, mode) ((Dr6 & DR6_LEGAL));
  1184. #define SANITIZE_DR7(Dr7, mode) ((Dr7 & DR7_LEGAL));
  1185. #define SANITIZE_DRADDR(DrReg, mode) ( \
  1186. (mode) == KernelMode ? \
  1187. (DrReg) : \
  1188. (((PVOID)DrReg <= MM_HIGHEST_USER_ADDRESS) ? \
  1189. (DrReg) : \
  1190. (0) \
  1191. ) \
  1192. )
  1193. //
  1194. // Define macro to clear reserved bits from MXCSR so that we don't
  1195. // GP fault when doing an FRSTOR
  1196. //
  1197. extern ULONG KiMXCsrMask;
  1198. #define SANITIZE_MXCSR(_mxcsr_) ((_mxcsr_) & KiMXCsrMask)
  1199. //
  1200. // Nonvolatile context pointers
  1201. //
  1202. // bryanwi 21 feb 90 - This is bogus. The 386 doesn't have
  1203. // enough nonvolatile context to make this
  1204. // structure worthwhile. Can't declare a
  1205. // field to be void, so declare a Junk structure
  1206. // instead.
  1207. typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
  1208. ULONG Junk;
  1209. } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
  1210. // begin_nthal
  1211. //
  1212. // Trap frame
  1213. //
  1214. // NOTE - We deal only with 32bit registers, so the assembler equivalents
  1215. // are always the extended forms.
  1216. //
  1217. // NOTE - Unless you want to run like slow molasses everywhere in the
  1218. // the system, this structure must be of DWORD length, DWORD
  1219. // aligned, and its elements must all be DWORD aligned.
  1220. //
  1221. // NOTE WELL -
  1222. //
  1223. // The i386 does not build stack frames in a consistent format, the
  1224. // frames vary depending on whether or not a privilege transition
  1225. // was involved.
  1226. //
  1227. // In order to make NtContinue work for both user mode and kernel
  1228. // mode callers, we must force a canonical stack.
  1229. //
  1230. // If we're called from kernel mode, this structure is 8 bytes longer
  1231. // than the actual frame!
  1232. //
  1233. // WARNING:
  1234. //
  1235. // KTRAP_FRAME_LENGTH needs to be 16byte integral (at present.)
  1236. //
  1237. typedef struct _KTRAP_FRAME {
  1238. //
  1239. // Following 4 values are only used and defined for DBG systems,
  1240. // but are always allocated to make switching from DBG to non-DBG
  1241. // and back quicker. They are not DEVL because they have a non-0
  1242. // performance impact.
  1243. //
  1244. ULONG DbgEbp; // Copy of User EBP set up so KB will work.
  1245. ULONG DbgEip; // EIP of caller to system call, again, for KB.
  1246. ULONG DbgArgMark; // Marker to show no args here.
  1247. ULONG DbgArgPointer; // Pointer to the actual args
  1248. //
  1249. // Temporary values used when frames are edited.
  1250. //
  1251. //
  1252. // NOTE: Any code that want's ESP must materialize it, since it
  1253. // is not stored in the frame for kernel mode callers.
  1254. //
  1255. // And code that sets ESP in a KERNEL mode frame, must put
  1256. // the new value in TempEsp, make sure that TempSegCs holds
  1257. // the real SegCs value, and put a special marker value into SegCs.
  1258. //
  1259. ULONG TempSegCs;
  1260. ULONG TempEsp;
  1261. //
  1262. // Debug registers.
  1263. //
  1264. ULONG Dr0;
  1265. ULONG Dr1;
  1266. ULONG Dr2;
  1267. ULONG Dr3;
  1268. ULONG Dr6;
  1269. ULONG Dr7;
  1270. //
  1271. // Segment registers
  1272. //
  1273. ULONG SegGs;
  1274. ULONG SegEs;
  1275. ULONG SegDs;
  1276. //
  1277. // Volatile registers
  1278. //
  1279. ULONG Edx;
  1280. ULONG Ecx;
  1281. ULONG Eax;
  1282. //
  1283. // Nesting state, not part of context record
  1284. //
  1285. ULONG PreviousPreviousMode;
  1286. PEXCEPTION_REGISTRATION_RECORD ExceptionList;
  1287. // Trash if caller was user mode.
  1288. // Saved exception list if caller
  1289. // was kernel mode or we're in
  1290. // an interrupt.
  1291. //
  1292. // FS is TIB/PCR pointer, is here to make save sequence easy
  1293. //
  1294. ULONG SegFs;
  1295. //
  1296. // Non-volatile registers
  1297. //
  1298. ULONG Edi;
  1299. ULONG Esi;
  1300. ULONG Ebx;
  1301. ULONG Ebp;
  1302. //
  1303. // Control registers
  1304. //
  1305. ULONG ErrCode;
  1306. ULONG Eip;
  1307. ULONG SegCs;
  1308. ULONG EFlags;
  1309. ULONG HardwareEsp; // WARNING - segSS:esp are only here for stacks
  1310. ULONG HardwareSegSs; // that involve a ring transition.
  1311. ULONG V86Es; // these will be present for all transitions from
  1312. ULONG V86Ds; // V86 mode
  1313. ULONG V86Fs;
  1314. ULONG V86Gs;
  1315. } KTRAP_FRAME;
  1316. typedef KTRAP_FRAME *PKTRAP_FRAME;
  1317. typedef KTRAP_FRAME *PKEXCEPTION_FRAME;
  1318. #define KTRAP_FRAME_LENGTH (sizeof(KTRAP_FRAME))
  1319. #define KTRAP_FRAME_ALIGN (sizeof(ULONG))
  1320. #define KTRAP_FRAME_ROUND (KTRAP_FRAME_ALIGN-1)
  1321. //
  1322. // Bits forced to 0 in SegCs if Esp has been edited.
  1323. //
  1324. #define FRAME_EDITED 0xfff8
  1325. // end_nthal
  1326. //
  1327. // The frame saved by KiCallUserMode is defined here to allow
  1328. // the kernel debugger to trace the entire kernel stack
  1329. // when usermode callouts are pending.
  1330. //
  1331. typedef struct _KCALLOUT_FRAME {
  1332. ULONG InStk; // saved initial stack address
  1333. ULONG TrFr; // saved callback trap frame
  1334. ULONG CbStk; // saved callback stack address
  1335. ULONG Edi; // saved nonvolatile registers
  1336. ULONG Esi; //
  1337. ULONG Ebx; //
  1338. ULONG Ebp; //
  1339. ULONG Ret; // saved return address
  1340. ULONG OutBf; // address to store output buffer
  1341. ULONG OutLn; // address to store output length
  1342. } KCALLOUT_FRAME;
  1343. typedef KCALLOUT_FRAME *PKCALLOUT_FRAME;
  1344. //
  1345. // Switch Frame
  1346. //
  1347. // 386 doesn't have an "exception frame", and doesn't normally make
  1348. // any use of nonvolatile context register structures.
  1349. //
  1350. // However, swapcontext in ctxswap.c and KeInitializeThread in
  1351. // thredini.c need to share common stack structure used at thread
  1352. // startup and switch time.
  1353. //
  1354. // This is that structure.
  1355. //
  1356. typedef struct _KSWITCHFRAME {
  1357. ULONG ExceptionList;
  1358. ULONG ApcBypassDisable;
  1359. ULONG RetAddr;
  1360. } KSWITCHFRAME, *PKSWITCHFRAME;
  1361. //
  1362. // Various 387 defines
  1363. //
  1364. #define I386_80387_NP_VECTOR 0x07 // trap 7 when hardware not present
  1365. // begin_ntddk begin_wdm
  1366. //
  1367. // The non-volatile 387 state
  1368. //
  1369. typedef struct _KFLOATING_SAVE {
  1370. ULONG ControlWord;
  1371. ULONG StatusWord;
  1372. ULONG ErrorOffset;
  1373. ULONG ErrorSelector;
  1374. ULONG DataOffset; // Not used in wdm
  1375. ULONG DataSelector;
  1376. ULONG Cr0NpxState;
  1377. ULONG Spare1; // Not used in wdm
  1378. } KFLOATING_SAVE, *PKFLOATING_SAVE;
  1379. // end_ntddk end_wdm end_ntosp
  1380. //
  1381. // i386 Profile values
  1382. //
  1383. #define DEFAULT_PROFILE_INTERVAL 39063
  1384. //
  1385. // The minimum acceptable profiling interval is set to 1221 which is the
  1386. // fast RTC clock rate we can get. If this
  1387. // value is too small, the system will run very slowly.
  1388. //
  1389. #define MINIMUM_PROFILE_INTERVAL 1221
  1390. // begin_ntddk begin_wdm begin_nthal begin_ntndis begin_ntosp
  1391. //
  1392. // i386 Specific portions of mm component
  1393. //
  1394. //
  1395. // Define the page size for the Intel 386 as 4096 (0x1000).
  1396. //
  1397. #define PAGE_SIZE 0x1000
  1398. //
  1399. // Define the number of trailing zeroes in a page aligned virtual address.
  1400. // This is used as the shift count when shifting virtual addresses to
  1401. // virtual page numbers.
  1402. //
  1403. #define PAGE_SHIFT 12L
  1404. // end_ntndis end_wdm
  1405. //
  1406. // Define the number of bits to shift to right justify the Page Directory Index
  1407. // field of a PTE.
  1408. //
  1409. #define PDI_SHIFT_X86 22
  1410. #define PDI_SHIFT_X86PAE 21
  1411. #if !defined (_X86PAE_)
  1412. #define PDI_SHIFT PDI_SHIFT_X86
  1413. #else
  1414. #define PDI_SHIFT PDI_SHIFT_X86PAE
  1415. #define PPI_SHIFT 30
  1416. #endif
  1417. //
  1418. // Define the number of bits to shift to right justify the Page Table Index
  1419. // field of a PTE.
  1420. //
  1421. #define PTI_SHIFT 12
  1422. //
  1423. // Define the highest user address and user probe address.
  1424. //
  1425. // end_ntddk end_nthal end_ntosp
  1426. #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_)
  1427. // begin_ntddk begin_nthal begin_ntosp
  1428. extern PVOID *MmHighestUserAddress;
  1429. extern PVOID *MmSystemRangeStart;
  1430. extern ULONG *MmUserProbeAddress;
  1431. #define MM_HIGHEST_USER_ADDRESS *MmHighestUserAddress
  1432. #define MM_SYSTEM_RANGE_START *MmSystemRangeStart
  1433. #define MM_USER_PROBE_ADDRESS *MmUserProbeAddress
  1434. // end_ntddk end_nthal end_ntosp
  1435. #else
  1436. extern PVOID MmHighestUserAddress;
  1437. extern PVOID MmSystemRangeStart;
  1438. extern ULONG MmUserProbeAddress;
  1439. #define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress
  1440. #define MM_SYSTEM_RANGE_START MmSystemRangeStart
  1441. #define MM_USER_PROBE_ADDRESS MmUserProbeAddress
  1442. #endif
  1443. // begin_ntddk begin_nthal begin_ntosp
  1444. //
  1445. // The lowest user address reserves the low 64k.
  1446. //
  1447. #define MM_LOWEST_USER_ADDRESS (PVOID)0x10000
  1448. //
  1449. // The lowest address for system space.
  1450. //
  1451. #if !defined (_X86PAE_)
  1452. #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000
  1453. #else
  1454. #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000
  1455. #endif
  1456. // begin_wdm
  1457. #define MmGetProcedureAddress(Address) (Address)
  1458. #define MmLockPagableCodeSection(Address) MmLockPagableDataSection(Address)
  1459. // end_ntddk end_wdm
  1460. //
  1461. // Define the number of bits to shift to right justify the Page Directory Index
  1462. // field of a PTE.
  1463. //
  1464. #define PDI_SHIFT_X86 22
  1465. #define PDI_SHIFT_X86PAE 21
  1466. #if !defined (_X86PAE_)
  1467. #define PDI_SHIFT PDI_SHIFT_X86
  1468. #else
  1469. #define PDI_SHIFT PDI_SHIFT_X86PAE
  1470. #define PPI_SHIFT 30
  1471. #endif
  1472. //
  1473. // Define the number of bits to shift to right justify the Page Table Index
  1474. // field of a PTE.
  1475. //
  1476. #define PTI_SHIFT 12
  1477. //
  1478. // Define page directory and page base addresses.
  1479. //
  1480. #define PDE_BASE_X86 0xc0300000
  1481. #define PDE_BASE_X86PAE 0xc0600000
  1482. #define PTE_TOP_X86 0xC03FFFFF
  1483. #define PDE_TOP_X86 0xC0300FFF
  1484. #define PTE_TOP_X86PAE 0xC07FFFFF
  1485. #define PDE_TOP_X86PAE 0xC0603FFF
  1486. #if !defined (_X86PAE_)
  1487. #define PDE_BASE PDE_BASE_X86
  1488. #define PTE_TOP PTE_TOP_X86
  1489. #define PDE_TOP PDE_TOP_X86
  1490. #else
  1491. #define PDE_BASE PDE_BASE_X86PAE
  1492. #define PTE_TOP PTE_TOP_X86PAE
  1493. #define PDE_TOP PDE_TOP_X86PAE
  1494. #endif
  1495. #define PTE_BASE 0xc0000000
  1496. // end_nthal end_ntosp
  1497. //
  1498. // Define virtual base and alternate virtual base of kernel.
  1499. //
  1500. #define KSEG0_BASE 0x80000000
  1501. #define ALTERNATE_BASE (0xe1000000 - 16 * 1024 * 1024)
  1502. //
  1503. // Define macro to initialize directory table base.
  1504. //
  1505. #define INITIALIZE_DIRECTORY_TABLE_BASE(dirbase,pfn) \
  1506. *((PULONG)(dirbase)) = ((pfn) << PAGE_SHIFT)
  1507. // begin_nthal
  1508. //
  1509. // Location of primary PCR (used only for UP kernel & hal code)
  1510. //
  1511. // addressed from 0xffdf0000 - 0xffdfffff are reserved for the system
  1512. // (ie, not for use by the hal)
  1513. #define KI_BEGIN_KERNEL_RESERVED 0xffdf0000
  1514. #define KIP0PCRADDRESS 0xffdff000 // ntddk wdm ntosp
  1515. // begin_ntddk begin_ntosp
  1516. #define KI_USER_SHARED_DATA 0xffdf0000
  1517. #define SharedUserData ((KUSER_SHARED_DATA * const) KI_USER_SHARED_DATA)
  1518. //
  1519. // Result type definition for i386. (Machine specific enumerate type
  1520. // which is return type for portable exinterlockedincrement/decrement
  1521. // procedures.) In general, you should use the enumerated type defined
  1522. // in ex.h instead of directly referencing these constants.
  1523. //
  1524. // Flags loaded into AH by LAHF instruction
  1525. #define EFLAG_SIGN 0x8000
  1526. #define EFLAG_ZERO 0x4000
  1527. #define EFLAG_SELECT (EFLAG_SIGN | EFLAG_ZERO)
  1528. #define RESULT_NEGATIVE ((EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT)
  1529. #define RESULT_ZERO ((~EFLAG_SIGN & EFLAG_ZERO) & EFLAG_SELECT)
  1530. #define RESULT_POSITIVE ((~EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT)
  1531. //
  1532. // Convert various portable ExInterlock APIs into their architectural
  1533. // equivalents.
  1534. //
  1535. #if PRAGMA_DEPRECATED_DDK
  1536. #pragma deprecated(ExInterlockedIncrementLong) // Use InterlockedIncrement
  1537. #pragma deprecated(ExInterlockedDecrementLong) // Use InterlockedDecrement
  1538. #pragma deprecated(ExInterlockedExchangeUlong) // Use InterlockedExchange
  1539. #endif
  1540. #define ExInterlockedIncrementLong(Addend,Lock) \
  1541. Exfi386InterlockedIncrementLong(Addend)
  1542. #define ExInterlockedDecrementLong(Addend,Lock) \
  1543. Exfi386InterlockedDecrementLong(Addend)
  1544. #define ExInterlockedExchangeUlong(Target,Value,Lock) \
  1545. Exfi386InterlockedExchangeUlong(Target,Value)
  1546. // begin_wdm
  1547. #define ExInterlockedAddUlong ExfInterlockedAddUlong
  1548. #define ExInterlockedInsertHeadList ExfInterlockedInsertHeadList
  1549. #define ExInterlockedInsertTailList ExfInterlockedInsertTailList
  1550. #define ExInterlockedRemoveHeadList ExfInterlockedRemoveHeadList
  1551. #define ExInterlockedPopEntryList ExfInterlockedPopEntryList
  1552. #define ExInterlockedPushEntryList ExfInterlockedPushEntryList
  1553. // end_wdm
  1554. //
  1555. // Prototypes for architectural specific versions of Exi386 Api
  1556. //
  1557. //
  1558. // Interlocked result type is portable, but its values are machine specific.
  1559. // Constants for value are in i386.h, mips.h, etc.
  1560. //
  1561. typedef enum _INTERLOCKED_RESULT {
  1562. ResultNegative = RESULT_NEGATIVE,
  1563. ResultZero = RESULT_ZERO,
  1564. ResultPositive = RESULT_POSITIVE
  1565. } INTERLOCKED_RESULT;
  1566. NTKERNELAPI
  1567. INTERLOCKED_RESULT
  1568. FASTCALL
  1569. Exfi386InterlockedIncrementLong (
  1570. IN PLONG Addend
  1571. );
  1572. NTKERNELAPI
  1573. INTERLOCKED_RESULT
  1574. FASTCALL
  1575. Exfi386InterlockedDecrementLong (
  1576. IN PLONG Addend
  1577. );
  1578. NTKERNELAPI
  1579. ULONG
  1580. FASTCALL
  1581. Exfi386InterlockedExchangeUlong (
  1582. IN PULONG Target,
  1583. IN ULONG Value
  1584. );
  1585. // end_ntddk end_nthal end_ntosp
  1586. //
  1587. // UP/MP versions of interlocked intrinsics
  1588. //
  1589. // N.B. FASTCALL does NOT work with inline functions.
  1590. //
  1591. #if !defined(_WINBASE_) && !defined(NONTOSPINTERLOCK) // ntosp ntddk nthal
  1592. #if defined(_M_IX86)
  1593. #if _MSC_VER >= 1200
  1594. #pragma warning(push)
  1595. #endif
  1596. #pragma warning(disable:4035) // re-enable below
  1597. // begin_ntddk begin_nthal begin_ntosp
  1598. #if !defined(MIDL_PASS) // wdm
  1599. #if defined(NO_INTERLOCKED_INTRINSICS) || defined(_CROSS_PLATFORM_)
  1600. // begin_wdm
  1601. NTKERNELAPI
  1602. LONG
  1603. FASTCALL
  1604. InterlockedIncrement(
  1605. IN LONG volatile *Addend
  1606. );
  1607. NTKERNELAPI
  1608. LONG
  1609. FASTCALL
  1610. InterlockedDecrement(
  1611. IN LONG volatile *Addend
  1612. );
  1613. NTKERNELAPI
  1614. LONG
  1615. FASTCALL
  1616. InterlockedExchange(
  1617. IN OUT LONG volatile *Target,
  1618. IN LONG Value
  1619. );
  1620. #define InterlockedExchangePointer(Target, Value) \
  1621. (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value))
  1622. LONG
  1623. FASTCALL
  1624. InterlockedExchangeAdd(
  1625. IN OUT LONG volatile *Addend,
  1626. IN LONG Increment
  1627. );
  1628. NTKERNELAPI
  1629. LONG
  1630. FASTCALL
  1631. InterlockedCompareExchange(
  1632. IN OUT LONG volatile *Destination,
  1633. IN LONG ExChange,
  1634. IN LONG Comperand
  1635. );
  1636. #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \
  1637. (PVOID)InterlockedCompareExchange((PLONG)Destination, (LONG)ExChange, (LONG)Comperand)
  1638. #define InterlockedCompareExchange64(Destination, ExChange, Comperand) \
  1639. ExfInterlockedCompareExchange64(Destination, &(ExChange), &(Comperand))
  1640. NTKERNELAPI
  1641. LONGLONG
  1642. FASTCALL
  1643. ExfInterlockedCompareExchange64(
  1644. IN OUT LONGLONG volatile *Destination,
  1645. IN PLONGLONG ExChange,
  1646. IN PLONGLONG Comperand
  1647. );
  1648. // end_wdm
  1649. #else // NO_INTERLOCKED_INTRINSICS || _CROSS_PLATFORM_
  1650. #define InterlockedExchangePointer(Target, Value) \
  1651. (PVOID)InterlockedExchange((PLONG)Target, (LONG)Value)
  1652. // end_ntddk end_nthal end_ntosp
  1653. #if defined(NT_UP) && !defined (_NTDDK_) && !defined(_NTIFS_)
  1654. #if (_MSC_FULL_VER > 13009037)
  1655. LONG
  1656. __cdecl
  1657. _InterlockedIncrement(
  1658. IN LONG volatile *Addend
  1659. );
  1660. #pragma intrinsic (_InterlockedIncrement)
  1661. #define InterlockedIncrement _InterlockedIncrement
  1662. #else
  1663. #define InterlockedIncrement(Addend) (InterlockedExchangeAdd (Addend, 1)+1)
  1664. #endif
  1665. #if (_MSC_FULL_VER > 13009037)
  1666. LONG
  1667. __cdecl
  1668. _InterlockedDecrement(
  1669. IN LONG volatile *Addend
  1670. );
  1671. #pragma intrinsic (_InterlockedDecrement)
  1672. #define InterlockedDecrement _InterlockedDecrement
  1673. #else
  1674. #define InterlockedDecrement(Addend) (InterlockedExchangeAdd (Addend, -1)-1)
  1675. #endif
  1676. //FORCEINLINE
  1677. //LONG
  1678. //FASTCALL
  1679. //InterlockedIncrement(
  1680. // IN PLONG Addend
  1681. // )
  1682. //{
  1683. // __asm {
  1684. // mov eax, 1
  1685. // mov ecx, Addend
  1686. // xadd [ecx], eax
  1687. // inc eax
  1688. // }
  1689. //}
  1690. //FORCEINLINE
  1691. //LONG
  1692. //FASTCALL
  1693. //InterlockedDecrement(
  1694. // IN PLONG Addend
  1695. // )
  1696. //{
  1697. // __asm {
  1698. // mov eax, -1
  1699. // mov ecx, Addend
  1700. // xadd [ecx], eax
  1701. // dec eax
  1702. // }
  1703. //}
  1704. #if (_MSC_FULL_VER > 13009037)
  1705. LONG
  1706. __cdecl
  1707. _InterlockedExchange(
  1708. IN OUT LONG volatile *Target,
  1709. IN LONG Value
  1710. );
  1711. #pragma intrinsic (_InterlockedExchange)
  1712. #define InterlockedExchange _InterlockedExchange
  1713. #else
  1714. FORCEINLINE
  1715. LONG
  1716. FASTCALL
  1717. InterlockedExchange(
  1718. IN OUT LONG volatile *Target,
  1719. IN LONG Value
  1720. )
  1721. {
  1722. __asm {
  1723. mov eax, Value
  1724. mov ecx, Target
  1725. xchg [ecx], eax
  1726. }
  1727. }
  1728. #endif
  1729. #if (_MSC_FULL_VER > 13009037)
  1730. LONG
  1731. __cdecl
  1732. _InterlockedExchangeAdd(
  1733. IN OUT LONG volatile *Addend,
  1734. IN LONG Increment
  1735. );
  1736. #pragma intrinsic (_InterlockedExchangeAdd)
  1737. #define InterlockedExchangeAdd _InterlockedExchangeAdd
  1738. #else
  1739. FORCEINLINE
  1740. LONG
  1741. FASTCALL
  1742. InterlockedExchangeAdd(
  1743. IN OUT LONG volatile *Addend,
  1744. IN LONG Increment
  1745. )
  1746. {
  1747. __asm {
  1748. mov eax, Increment
  1749. mov ecx, Addend
  1750. xadd [ecx], eax
  1751. }
  1752. }
  1753. #endif
  1754. #if (_MSC_FULL_VER > 13009037)
  1755. LONG
  1756. __cdecl
  1757. _InterlockedCompareExchange (
  1758. IN OUT LONG volatile *Destination,
  1759. IN LONG ExChange,
  1760. IN LONG Comperand
  1761. );
  1762. #pragma intrinsic (_InterlockedCompareExchange)
  1763. #define InterlockedCompareExchange (LONG)_InterlockedCompareExchange
  1764. #else
  1765. FORCEINLINE
  1766. LONG
  1767. FASTCALL
  1768. InterlockedCompareExchange(
  1769. IN OUT LONG volatile *Destination,
  1770. IN LONG Exchange,
  1771. IN LONG Comperand
  1772. )
  1773. {
  1774. __asm {
  1775. mov eax, Comperand
  1776. mov ecx, Destination
  1777. mov edx, Exchange
  1778. cmpxchg [ecx], edx
  1779. }
  1780. }
  1781. #endif
  1782. #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \
  1783. (PVOID)InterlockedCompareExchange((PLONG)Destination, (LONG)ExChange, (LONG)Comperand)
  1784. #define InterlockedCompareExchange64(Destination, ExChange, Comperand) \
  1785. ExfInterlockedCompareExchange64(Destination, &(ExChange), &(Comperand))
  1786. LONGLONG
  1787. FASTCALL
  1788. ExfInterlockedCompareExchange64(
  1789. IN OUT LONGLONG volatile *Destination,
  1790. IN PLONGLONG ExChange,
  1791. IN PLONGLONG Comperand
  1792. );
  1793. #else // NT_UP
  1794. // begin_ntosp begin_ntddk begin_nthal
  1795. #if (_MSC_FULL_VER > 13009037)
  1796. LONG
  1797. __cdecl
  1798. _InterlockedExchange(
  1799. IN OUT LONG volatile *Target,
  1800. IN LONG Value
  1801. );
  1802. #pragma intrinsic (_InterlockedExchange)
  1803. #define InterlockedExchange _InterlockedExchange
  1804. #else
  1805. FORCEINLINE
  1806. LONG
  1807. FASTCALL
  1808. InterlockedExchange(
  1809. IN OUT LONG volatile *Target,
  1810. IN LONG Value
  1811. )
  1812. {
  1813. __asm {
  1814. mov eax, Value
  1815. mov ecx, Target
  1816. xchg [ecx], eax
  1817. }
  1818. }
  1819. #endif
  1820. #if (_MSC_FULL_VER > 13009037)
  1821. LONG
  1822. __cdecl
  1823. _InterlockedIncrement(
  1824. IN LONG volatile *Addend
  1825. );
  1826. #pragma intrinsic (_InterlockedIncrement)
  1827. #define InterlockedIncrement _InterlockedIncrement
  1828. #else
  1829. #define InterlockedIncrement(Addend) (InterlockedExchangeAdd (Addend, 1)+1)
  1830. #endif
  1831. #if (_MSC_FULL_VER > 13009037)
  1832. LONG
  1833. __cdecl
  1834. _InterlockedDecrement(
  1835. IN LONG volatile *Addend
  1836. );
  1837. #pragma intrinsic (_InterlockedDecrement)
  1838. #define InterlockedDecrement _InterlockedDecrement
  1839. #else
  1840. #define InterlockedDecrement(Addend) (InterlockedExchangeAdd (Addend, -1)-1)
  1841. #endif
  1842. #if (_MSC_FULL_VER > 13009037)
  1843. LONG
  1844. __cdecl
  1845. _InterlockedExchangeAdd(
  1846. IN OUT LONG volatile *Addend,
  1847. IN LONG Increment
  1848. );
  1849. #pragma intrinsic (_InterlockedExchangeAdd)
  1850. #define InterlockedExchangeAdd _InterlockedExchangeAdd
  1851. #else
  1852. // begin_wdm
  1853. FORCEINLINE
  1854. LONG
  1855. FASTCALL
  1856. InterlockedExchangeAdd(
  1857. IN OUT LONG volatile *Addend,
  1858. IN LONG Increment
  1859. )
  1860. {
  1861. __asm {
  1862. mov eax, Increment
  1863. mov ecx, Addend
  1864. lock xadd [ecx], eax
  1865. }
  1866. }
  1867. // end_wdm
  1868. #endif
  1869. #if (_MSC_FULL_VER > 13009037)
  1870. LONG
  1871. __cdecl
  1872. _InterlockedCompareExchange (
  1873. IN OUT LONG volatile *Destination,
  1874. IN LONG ExChange,
  1875. IN LONG Comperand
  1876. );
  1877. #pragma intrinsic (_InterlockedCompareExchange)
  1878. #define InterlockedCompareExchange (LONG)_InterlockedCompareExchange
  1879. #else
  1880. FORCEINLINE
  1881. LONG
  1882. FASTCALL
  1883. InterlockedCompareExchange(
  1884. IN OUT LONG volatile *Destination,
  1885. IN LONG Exchange,
  1886. IN LONG Comperand
  1887. )
  1888. {
  1889. __asm {
  1890. mov eax, Comperand
  1891. mov ecx, Destination
  1892. mov edx, Exchange
  1893. lock cmpxchg [ecx], edx
  1894. }
  1895. }
  1896. #endif
  1897. #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \
  1898. (PVOID)InterlockedCompareExchange((PLONG)Destination, (LONG)ExChange, (LONG)Comperand)
  1899. #define InterlockedCompareExchange64(Destination, ExChange, Comperand) \
  1900. ExfInterlockedCompareExchange64(Destination, &(ExChange), &(Comperand))
  1901. NTKERNELAPI
  1902. LONGLONG
  1903. FASTCALL
  1904. ExfInterlockedCompareExchange64(
  1905. IN OUT LONGLONG volatile *Destination,
  1906. IN PLONGLONG ExChange,
  1907. IN PLONGLONG Comperand
  1908. );
  1909. // end_ntosp end_ntddk end_nthal
  1910. #endif // NT_UP
  1911. // begin_ntddk begin_nthal begin_ntosp
  1912. #endif // INTERLOCKED_INTRINSICS || _CROSS_PLATFORM_
  1913. // begin_wdm
  1914. #endif // MIDL_PASS
  1915. #define InterlockedIncrementAcquire InterlockedIncrement
  1916. #define InterlockedIncrementRelease InterlockedIncrement
  1917. #define InterlockedDecrementAcquire InterlockedDecrement
  1918. #define InterlockedDecrementRelease InterlockedDecrement
  1919. #define InterlockedExchangeAcquire64 InterlockedExchange64
  1920. #define InterlockedCompareExchangeAcquire InterlockedCompareExchange
  1921. #define InterlockedCompareExchangeRelease InterlockedCompareExchange
  1922. #define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64
  1923. #define InterlockedCompareExchangeRelease64 InterlockedCompareExchange64
  1924. // end_ntosp end_ntddk end_nthal end_wdm
  1925. #if _MSC_VER >= 1200
  1926. #pragma warning(pop)
  1927. #else
  1928. #pragma warning(default:4035)
  1929. #endif
  1930. #endif // _M_IX86 && !CROSS_PLATFORM
  1931. // begin_ntddk begin_nthal begin_ntosp
  1932. #endif // __WINBASE__ && !NONTOSPINTERLOCK
  1933. // end_ntosp end_ntddk end_nthal
  1934. // begin_nthal begin_ntddk
  1935. //
  1936. // Turn these instrinsics off until the compiler can handle them
  1937. //
  1938. #if (_MSC_FULL_VER > 13009037)
  1939. LONG
  1940. _InterlockedOr (
  1941. IN OUT LONG volatile *Target,
  1942. IN LONG Set
  1943. );
  1944. #pragma intrinsic (_InterlockedOr)
  1945. #define InterlockedOr _InterlockedOr
  1946. LONG
  1947. _InterlockedAnd (
  1948. IN OUT LONG volatile *Target,
  1949. IN LONG Set
  1950. );
  1951. #pragma intrinsic (_InterlockedAnd)
  1952. #define InterlockedAnd _InterlockedAnd
  1953. LONG
  1954. _InterlockedXor (
  1955. IN OUT LONG volatile *Target,
  1956. IN LONG Set
  1957. );
  1958. #pragma intrinsic (_InterlockedXor)
  1959. #define InterlockedXor _InterlockedXor
  1960. #else // compiler version
  1961. FORCEINLINE
  1962. LONG
  1963. InterlockedAnd (
  1964. IN OUT LONG volatile *Target,
  1965. LONG Set
  1966. )
  1967. {
  1968. LONG i;
  1969. LONG j;
  1970. j = *Target;
  1971. do {
  1972. i = j;
  1973. j = InterlockedCompareExchange(Target,
  1974. i & Set,
  1975. i);
  1976. } while (i != j);
  1977. return j;
  1978. }
  1979. FORCEINLINE
  1980. LONG
  1981. InterlockedOr (
  1982. IN OUT LONG volatile *Target,
  1983. IN LONG Set
  1984. )
  1985. {
  1986. LONG i;
  1987. LONG j;
  1988. j = *Target;
  1989. do {
  1990. i = j;
  1991. j = InterlockedCompareExchange(Target,
  1992. i | Set,
  1993. i);
  1994. } while (i != j);
  1995. return j;
  1996. }
  1997. #endif // compiler version
  1998. // end_nthal end_ntddk
  1999. //
  2000. // Structure for Ldt information in x86 processes
  2001. //
  2002. typedef struct _LDTINFORMATION {
  2003. ULONG Size;
  2004. ULONG AllocatedSize;
  2005. PLDT_ENTRY Ldt;
  2006. } LDTINFORMATION, *PLDTINFORMATION;
  2007. //
  2008. // SetProcessInformation Structure for ProcessSetIoHandlers info class
  2009. //
  2010. // begin_ntosp
  2011. typedef struct _PROCESS_IO_PORT_HANDLER_INFORMATION {
  2012. BOOLEAN Install; // true if handlers to be installed
  2013. ULONG NumEntries;
  2014. ULONG Context;
  2015. PEMULATOR_ACCESS_ENTRY EmulatorAccessEntries;
  2016. } PROCESS_IO_PORT_HANDLER_INFORMATION, *PPROCESS_IO_PORT_HANDLER_INFORMATION;
  2017. //
  2018. // Vdm Objects and Io handling structure
  2019. //
  2020. typedef struct _VDM_IO_HANDLER_FUNCTIONS {
  2021. PDRIVER_IO_PORT_ULONG UlongIo;
  2022. PDRIVER_IO_PORT_ULONG_STRING UlongStringIo;
  2023. PDRIVER_IO_PORT_USHORT UshortIo[2];
  2024. PDRIVER_IO_PORT_USHORT_STRING UshortStringIo[2];
  2025. PDRIVER_IO_PORT_UCHAR UcharIo[4];
  2026. PDRIVER_IO_PORT_UCHAR_STRING UcharStringIo[4];
  2027. } VDM_IO_HANDLER_FUNCTIONS, *PVDM_IO_HANDLER_FUNCTIONS;
  2028. typedef struct _VDM_IO_HANDLER {
  2029. struct _VDM_IO_HANDLER *Next;
  2030. ULONG PortNumber;
  2031. VDM_IO_HANDLER_FUNCTIONS IoFunctions[2];
  2032. } VDM_IO_HANDLER, *PVDM_IO_HANDLER;
  2033. // begin_nthal begin_ntddk begin_wdm
  2034. #if !defined(MIDL_PASS) && defined(_M_IX86)
  2035. //
  2036. // i386 function definitions
  2037. //
  2038. // end_wdm
  2039. #if _MSC_VER >= 1200
  2040. #pragma warning(push)
  2041. #endif
  2042. #pragma warning(disable:4035) // re-enable below
  2043. // end_ntddk end_ntosp
  2044. #if NT_UP
  2045. #define _PCR ds:[KIP0PCRADDRESS]
  2046. #else
  2047. #define _PCR fs:[0] // ntddk ntosp
  2048. #endif
  2049. //
  2050. // Get address of current processor block.
  2051. //
  2052. // WARNING: This inline macro can only be used by the kernel or hal
  2053. //
  2054. #define KiPcr() KeGetPcr()
  2055. FORCEINLINE
  2056. PKPCR
  2057. NTAPI
  2058. KeGetPcr(VOID)
  2059. {
  2060. #if NT_UP
  2061. return (PKPCR)KIP0PCRADDRESS;
  2062. #else
  2063. #if (_MSC_FULL_VER >= 13012035)
  2064. return (PKPCR) (ULONG_PTR) __readfsdword (FIELD_OFFSET (KPCR, SelfPcr));
  2065. #else
  2066. __asm { mov eax, _PCR KPCR.SelfPcr }
  2067. #endif
  2068. #endif
  2069. }
  2070. // begin_ntosp
  2071. //
  2072. // Get address of current processor block.
  2073. //
  2074. // WARNING: This inline macro can only be used by the kernel or hal
  2075. //
  2076. FORCEINLINE
  2077. PKPRCB
  2078. NTAPI
  2079. KeGetCurrentPrcb (VOID)
  2080. {
  2081. #if (_MSC_FULL_VER >= 13012035)
  2082. return (PKPRCB) (ULONG_PTR) __readfsdword (FIELD_OFFSET (KPCR, Prcb));
  2083. #else
  2084. __asm { mov eax, _PCR KPCR.Prcb }
  2085. #endif
  2086. }
  2087. // begin_ntddk begin_wdm
  2088. //
  2089. // Get current IRQL.
  2090. //
  2091. // On x86 this function resides in the HAL
  2092. //
  2093. // end_ntddk end_wdm
  2094. #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) || !defined(_APIC_TPR_)
  2095. // begin_ntddk begin_wdm
  2096. NTHALAPI
  2097. KIRQL
  2098. NTAPI
  2099. KeGetCurrentIrql();
  2100. // end_ntddk end_wdm
  2101. #endif
  2102. // begin_ntddk begin_wdm
  2103. // end_wdm
  2104. //
  2105. // Get the current processor number
  2106. //
  2107. FORCEINLINE
  2108. ULONG
  2109. NTAPI
  2110. KeGetCurrentProcessorNumber(VOID)
  2111. {
  2112. #if (_MSC_FULL_VER >= 13012035)
  2113. return (ULONG) __readfsbyte (FIELD_OFFSET (KPCR, Number));
  2114. #else
  2115. __asm { movzx eax, _PCR KPCR.Number }
  2116. #endif
  2117. }
  2118. // end_nthal end_ntddk end_ntosp
  2119. //
  2120. // Get address of current kernel thread object.
  2121. //
  2122. // WARNING: This inline macro can not be used for device drivers or HALs
  2123. // they must call the kernel function KeGetCurrentThread.
  2124. // WARNING: This inline macro is always MP enabled because filesystems
  2125. // utilize it
  2126. //
  2127. //
  2128. FORCEINLINE
  2129. struct _KTHREAD *
  2130. NTAPI KeGetCurrentThread (VOID)
  2131. {
  2132. #if (_MSC_FULL_VER >= 13012035)
  2133. return (struct _KTHREAD *) (ULONG_PTR) __readfsdword (FIELD_OFFSET (KPCR, PrcbData.CurrentThread));
  2134. #else
  2135. __asm { mov eax, fs:[0] KPCR.PrcbData.CurrentThread }
  2136. #endif
  2137. }
  2138. //
  2139. // If processor executing DPC?
  2140. // WARNING: This inline macro is always MP enabled because filesystems
  2141. // utilize it
  2142. //
  2143. FORCEINLINE
  2144. ULONG
  2145. NTAPI
  2146. KeIsExecutingDpc(VOID)
  2147. {
  2148. #if (_MSC_FULL_VER >= 13012035)
  2149. return (ULONG) __readfsbyte (FIELD_OFFSET (KPCR, PrcbData.DpcRoutineActive));
  2150. #else
  2151. __asm { movzx eax, word ptr fs:[0] KPCR.PrcbData.DpcRoutineActive }
  2152. #endif
  2153. }
  2154. // begin_nthal begin_ntddk begin_ntosp
  2155. #if _MSC_VER >= 1200
  2156. #pragma warning(pop)
  2157. #else
  2158. #pragma warning(default:4035)
  2159. #endif
  2160. // begin_wdm
  2161. #endif // !defined(MIDL_PASS) && defined(_M_IX86)
  2162. // end_nthal end_ntddk end_wdm end_ntosp
  2163. // begin_ntddk begin_nthal begin_ntndis begin_wdm begin_ntosp
  2164. //++
  2165. //
  2166. // VOID
  2167. // KeMemoryBarrier (
  2168. // VOID
  2169. // )
  2170. //
  2171. // VOID
  2172. // KeMemoryBarrierWithoutFence (
  2173. // VOID
  2174. // )
  2175. //
  2176. //
  2177. // Routine Description:
  2178. //
  2179. // These functions order memory accesses as seen by other processors.
  2180. //
  2181. // Arguments:
  2182. //
  2183. // None.
  2184. //
  2185. // Return Value:
  2186. //
  2187. // None.
  2188. //
  2189. //--
  2190. #ifdef __cplusplus
  2191. extern "C" {
  2192. #endif
  2193. VOID
  2194. _ReadWriteBarrier(
  2195. VOID
  2196. );
  2197. #ifdef __cplusplus
  2198. }
  2199. #endif
  2200. #pragma intrinsic (_ReadWriteBarrier)
  2201. FORCEINLINE
  2202. VOID
  2203. KeMemoryBarrier (
  2204. VOID
  2205. )
  2206. {
  2207. LONG Barrier;
  2208. __asm {
  2209. xchg Barrier, eax
  2210. }
  2211. }
  2212. #define KeMemoryBarrierWithoutFence() _ReadWriteBarrier()
  2213. // end_ntddk end_nthal end_ntndis end_wdm end_ntosp
  2214. //
  2215. // For the UP kernel don't generate the locked reference
  2216. //
  2217. #if defined (NT_UP)
  2218. #define KeMemoryBarrier() _ReadWriteBarrier()
  2219. #endif
  2220. // begin_nthal
  2221. //
  2222. // Macro to set address of a trap/interrupt handler to IDT
  2223. //
  2224. #define KiSetHandlerAddressToIDT(Vector, HandlerAddress) {\
  2225. UCHAR IDTEntry = HalVectorToIDTEntry(Vector); \
  2226. ULONG Ha = (ULONG)HandlerAddress; \
  2227. KeGetPcr()->IDT[IDTEntry].ExtendedOffset = HIGHWORD(Ha); \
  2228. KeGetPcr()->IDT[IDTEntry].Offset = LOWWORD(Ha); \
  2229. }
  2230. //
  2231. // Macro to return address of a trap/interrupt handler in IDT
  2232. //
  2233. #define KiReturnHandlerAddressFromIDT(Vector) \
  2234. MAKEULONG(KiPcr()->IDT[HalVectorToIDTEntry(Vector)].ExtendedOffset, KiPcr()->IDT[HalVectorToIDTEntry(Vector)].Offset)
  2235. // end_nthal
  2236. //++
  2237. //
  2238. // BOOLEAN
  2239. // KiIsThreadNumericStateSaved(
  2240. // IN PKTHREAD Address
  2241. // )
  2242. //
  2243. //--
  2244. #define KiIsThreadNumericStateSaved(a) \
  2245. (a->NpxState != NPX_STATE_LOADED)
  2246. //++
  2247. //
  2248. // VOID
  2249. // KiRundownThread(
  2250. // IN PKTHREAD Address
  2251. // )
  2252. //
  2253. //--
  2254. #if defined(NT_UP)
  2255. //
  2256. // On UP x86 systems, FP state is lazy saved and loaded. If this
  2257. // thread owns the current FP context, clear the ownership field
  2258. // so we will not try to save to this thread after it has been
  2259. // terminated.
  2260. //
  2261. #define KiRundownThread(a) \
  2262. if (KeGetCurrentPrcb()->NpxThread == (a)) { \
  2263. KeGetCurrentPrcb()->NpxThread = NULL; \
  2264. __asm { fninit } \
  2265. }
  2266. #else
  2267. #define KiRundownThread(a)
  2268. #endif
  2269. //
  2270. // functions specific to 386 structure
  2271. //
  2272. VOID
  2273. NTAPI
  2274. KiSetIRR (
  2275. IN ULONG SWInterruptMask
  2276. );
  2277. //
  2278. // Procedures to support frame manipulation
  2279. //
  2280. ULONG
  2281. NTAPI
  2282. KiEspFromTrapFrame(
  2283. IN PKTRAP_FRAME TrapFrame
  2284. );
  2285. VOID
  2286. NTAPI
  2287. KiEspToTrapFrame(
  2288. IN PKTRAP_FRAME TrapFrame,
  2289. IN ULONG Esp
  2290. );
  2291. ULONG
  2292. NTAPI
  2293. KiSegSsFromTrapFrame(
  2294. IN PKTRAP_FRAME TrapFrame
  2295. );
  2296. VOID
  2297. NTAPI
  2298. KiSegSsToTrapFrame(
  2299. IN PKTRAP_FRAME TrapFrame,
  2300. IN ULONG SegSs
  2301. );
  2302. //
  2303. // Define prototypes for i386 specific clock and profile interrupt routines.
  2304. //
  2305. VOID
  2306. NTAPI
  2307. KiUpdateRunTime (
  2308. VOID
  2309. );
  2310. VOID
  2311. NTAPI
  2312. KiUpdateSystemTime (
  2313. VOID
  2314. );
  2315. // begin_ntddk begin_wdm begin_ntosp
  2316. NTKERNELAPI
  2317. NTSTATUS
  2318. NTAPI
  2319. KeSaveFloatingPointState (
  2320. OUT PKFLOATING_SAVE FloatSave
  2321. );
  2322. NTKERNELAPI
  2323. NTSTATUS
  2324. NTAPI
  2325. KeRestoreFloatingPointState (
  2326. IN PKFLOATING_SAVE FloatSave
  2327. );
  2328. // end_ntddk end_wdm
  2329. // begin_nthal
  2330. NTKERNELAPI
  2331. VOID
  2332. NTAPI
  2333. KeProfileInterruptWithSource (
  2334. IN struct _KTRAP_FRAME *TrapFrame,
  2335. IN KPROFILE_SOURCE ProfileSource
  2336. );
  2337. // end_ntosp
  2338. VOID
  2339. NTAPI
  2340. KeProfileInterrupt (
  2341. IN KIRQL OldIrql,
  2342. IN KTRAP_FRAME TrapFrame
  2343. );
  2344. VOID
  2345. NTAPI
  2346. KeUpdateRuntime (
  2347. IN KIRQL OldIrql,
  2348. IN KTRAP_FRAME TrapFrame
  2349. );
  2350. VOID
  2351. NTAPI
  2352. KeUpdateSystemTime (
  2353. IN KIRQL OldIrql,
  2354. IN KTRAP_FRAME TrapFrame
  2355. );
  2356. // begin_ntddk begin_wdm begin_ntndis begin_ntosp
  2357. #endif // defined(_X86_)
  2358. // end_nthal end_ntddk end_wdm end_ntndis end_ntosp
  2359. // begin_nthal begin_ntddk
  2360. // Use the following for kernel mode runtime checks of X86 system architecture
  2361. #ifdef _X86_
  2362. #ifdef IsNEC_98
  2363. #undef IsNEC_98
  2364. #endif
  2365. #ifdef IsNotNEC_98
  2366. #undef IsNotNEC_98
  2367. #endif
  2368. #ifdef SetNEC_98
  2369. #undef SetNEC_98
  2370. #endif
  2371. #ifdef SetNotNEC_98
  2372. #undef SetNotNEC_98
  2373. #endif
  2374. #define IsNEC_98 (SharedUserData->AlternativeArchitecture == NEC98x86)
  2375. #define IsNotNEC_98 (SharedUserData->AlternativeArchitecture != NEC98x86)
  2376. #define SetNEC_98 SharedUserData->AlternativeArchitecture = NEC98x86
  2377. #define SetNotNEC_98 SharedUserData->AlternativeArchitecture = StandardDesign
  2378. #endif
  2379. // end_nthal end_ntddk
  2380. //
  2381. // i386 arch. specific kernel functions.
  2382. //
  2383. // begin_ntosp
  2384. #ifdef _X86_
  2385. VOID
  2386. NTAPI
  2387. Ke386SetLdtProcess (
  2388. struct _KPROCESS *Process,
  2389. PLDT_ENTRY Ldt,
  2390. ULONG Limit
  2391. );
  2392. VOID
  2393. NTAPI
  2394. Ke386SetDescriptorProcess (
  2395. struct _KPROCESS *Process,
  2396. ULONG Offset,
  2397. LDT_ENTRY LdtEntry
  2398. );
  2399. VOID
  2400. NTAPI
  2401. Ke386GetGdtEntryThread (
  2402. struct _KTHREAD *Thread,
  2403. ULONG Offset,
  2404. PKGDTENTRY Descriptor
  2405. );
  2406. BOOLEAN
  2407. NTAPI
  2408. Ke386SetIoAccessMap (
  2409. ULONG MapNumber,
  2410. PKIO_ACCESS_MAP IoAccessMap
  2411. );
  2412. BOOLEAN
  2413. NTAPI
  2414. Ke386QueryIoAccessMap (
  2415. ULONG MapNumber,
  2416. PKIO_ACCESS_MAP IoAccessMap
  2417. );
  2418. BOOLEAN
  2419. NTAPI
  2420. Ke386IoSetAccessProcess (
  2421. struct _KPROCESS *Process,
  2422. ULONG MapNumber
  2423. );
  2424. VOID
  2425. NTAPI
  2426. Ke386SetIOPL(
  2427. VOID
  2428. );
  2429. NTSTATUS
  2430. NTAPI
  2431. Ke386CallBios (
  2432. IN ULONG BiosCommand,
  2433. IN OUT PCONTEXT BiosArguments
  2434. );
  2435. VOID
  2436. NTAPI
  2437. KiEditIopmDpc (
  2438. IN struct _KDPC *Dpc,
  2439. IN PVOID DeferredContext,
  2440. IN PVOID SystemArgument1,
  2441. IN PVOID SystemArgument2
  2442. );
  2443. BOOLEAN
  2444. NTAPI
  2445. Ki386GetSelectorParameters(
  2446. IN USHORT Selector,
  2447. OUT PULONG Flags,
  2448. OUT PULONG Base,
  2449. OUT PULONG Limit
  2450. );
  2451. ULONG
  2452. Ki386DispatchOpcodeV86 (
  2453. IN PKTRAP_FRAME TrapFrame
  2454. );
  2455. ULONG
  2456. Ki386DispatchOpcode (
  2457. IN PKTRAP_FRAME TrapFrame
  2458. );
  2459. NTSTATUS
  2460. NTAPI
  2461. Ke386SetVdmInterruptHandler (
  2462. IN struct _KPROCESS *Process,
  2463. IN ULONG Interrupt,
  2464. IN USHORT Selector,
  2465. IN ULONG Offset,
  2466. IN BOOLEAN Gate32
  2467. );
  2468. #endif //_X86_
  2469. // end_ntosp
  2470. //
  2471. // i386 ABIOS specific routines.
  2472. //
  2473. NTSTATUS
  2474. NTAPI
  2475. KeI386GetLid(
  2476. IN USHORT DeviceId,
  2477. IN USHORT RelativeLid,
  2478. IN BOOLEAN SharedLid,
  2479. IN struct _DRIVER_OBJECT *DeviceObject,
  2480. OUT PUSHORT LogicalId
  2481. );
  2482. NTSTATUS
  2483. NTAPI
  2484. KeI386ReleaseLid(
  2485. IN USHORT LogicalId,
  2486. IN struct _DRIVER_OBJECT *DeviceObject
  2487. );
  2488. NTSTATUS
  2489. NTAPI
  2490. KeI386AbiosCall(
  2491. IN USHORT LogicalId,
  2492. IN struct _DRIVER_OBJECT *DriverObject,
  2493. IN PUCHAR RequestBlock,
  2494. IN USHORT EntryPoint
  2495. );
  2496. //
  2497. // i386 misc routines
  2498. //
  2499. NTSTATUS
  2500. NTAPI
  2501. KeI386AllocateGdtSelectors(
  2502. OUT PUSHORT SelectorArray,
  2503. IN USHORT NumberOfSelectors
  2504. );
  2505. VOID
  2506. NTAPI
  2507. KeI386Call16BitFunction (
  2508. IN OUT PCONTEXT Regs
  2509. );
  2510. USHORT
  2511. NTAPI
  2512. KeI386Call16BitCStyleFunction (
  2513. IN ULONG EntryOffset,
  2514. IN ULONG EntrySelector,
  2515. IN PUCHAR Parameters,
  2516. IN ULONG Size
  2517. );
  2518. NTSTATUS
  2519. NTAPI
  2520. KeI386FlatToGdtSelector(
  2521. IN ULONG SelectorBase,
  2522. IN USHORT Length,
  2523. IN USHORT Selector
  2524. );
  2525. NTSTATUS
  2526. NTAPI
  2527. KeI386ReleaseGdtSelectors(
  2528. OUT PUSHORT SelectorArray,
  2529. IN USHORT NumberOfSelectors
  2530. );
  2531. NTSTATUS
  2532. NTAPI
  2533. KeI386SetGdtSelector (
  2534. ULONG Selector,
  2535. PKGDTENTRY GdtValue
  2536. );
  2537. VOID
  2538. NTAPI
  2539. KeOptimizeProcessorControlState (
  2540. VOID
  2541. );
  2542. //
  2543. // Vdm specific functions.
  2544. //
  2545. BOOLEAN
  2546. NTAPI
  2547. KeVdmInsertQueueApc (
  2548. IN PKAPC Apc,
  2549. IN struct _KTHREAD *Thread,
  2550. IN KPROCESSOR_MODE ApcMode,
  2551. IN PKKERNEL_ROUTINE KernelRoutine,
  2552. IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
  2553. IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL,
  2554. IN PVOID NormalContext OPTIONAL,
  2555. IN KPRIORITY Increment
  2556. );
  2557. FORCEINLINE
  2558. VOID
  2559. NTAPI
  2560. KeVdmClearApcThreadAddress (
  2561. IN PKAPC Apc
  2562. )
  2563. {
  2564. if (Apc->Inserted == FALSE) {
  2565. Apc->Thread = NULL;
  2566. }
  2567. }
  2568. VOID
  2569. NTAPI
  2570. KeI386VdmInitialize (
  2571. VOID
  2572. );
  2573. //
  2574. // x86 functions for special instructions
  2575. //
  2576. VOID
  2577. NTAPI
  2578. CPUID (
  2579. ULONG InEax,
  2580. PULONG OutEax,
  2581. PULONG OutEbx,
  2582. PULONG OutEcx,
  2583. PULONG OutEdx
  2584. );
  2585. LONGLONG
  2586. NTAPI
  2587. RDTSC (
  2588. VOID
  2589. );
  2590. ULONGLONG
  2591. FASTCALL
  2592. RDMSR (
  2593. IN ULONG MsrRegister
  2594. );
  2595. VOID
  2596. NTAPI
  2597. WRMSR (
  2598. IN ULONG MsrRegister,
  2599. IN ULONGLONG MsrValue
  2600. );
  2601. //
  2602. // i386 Vdm specific data
  2603. //
  2604. extern ULONG KeI386EFlagsAndMaskV86;
  2605. extern ULONG KeI386EFlagsOrMaskV86;
  2606. extern ULONG KeI386VirtualIntExtensions;
  2607. extern ULONG KeI386CpuType;
  2608. extern ULONG KeI386CpuStep;
  2609. extern BOOLEAN KeI386NpxPresent;
  2610. extern BOOLEAN KeI386FxsrPresent;
  2611. //
  2612. // i386 Feature bit definitions
  2613. //
  2614. #define KF_V86_VIS 0x00000001
  2615. #define KF_RDTSC 0x00000002
  2616. #define KF_CR4 0x00000004
  2617. #define KF_CMOV 0x00000008
  2618. #define KF_GLOBAL_PAGE 0x00000010
  2619. #define KF_LARGE_PAGE 0x00000020
  2620. #define KF_MTRR 0x00000040
  2621. #define KF_CMPXCHG8B 0x00000080
  2622. #define KF_MMX 0x00000100
  2623. #define KF_WORKING_PTE 0x00000200
  2624. #define KF_PAT 0x00000400
  2625. #define KF_FXSR 0x00000800
  2626. #define KF_FAST_SYSCALL 0x00001000
  2627. #define KF_XMMI 0x00002000
  2628. #define KF_3DNOW 0x00004000
  2629. #define KF_AMDK6MTRR 0x00008000
  2630. #define KF_XMMI64 0x00010000
  2631. #define KF_DTS 0x00020000
  2632. //
  2633. // Define macro to test if x86 feature is present.
  2634. //
  2635. extern ULONG KiBootFeatureBits;
  2636. #define Isx86FeaturePresent(_f_) ((KiBootFeatureBits & (_f_)) != 0)
  2637. #endif // _i386_