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.

2256 lines
46 KiB

  1. /*++ BUILD Version: 0001 // Increment this if a change has global effects
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. halp.h
  5. Abstract:
  6. This header file defines the private Hardware Architecture Layer (HAL)
  7. interfaces, defines and structures.
  8. Author:
  9. John Vert (jvert) 11-Feb-92
  10. Revision History:
  11. --*/
  12. #ifndef _HALP_H_
  13. #define _HALP_H_
  14. #include "nthal.h"
  15. #include "halnls.h"
  16. //
  17. //Pickup the pnp guid definitions.
  18. //
  19. #include "wdmguid.h"
  20. #if defined(NEC_98)
  21. #include "nec98.h"
  22. #else
  23. #if MCA
  24. #include "mca.h"
  25. #else
  26. #include "eisa.h"
  27. #endif
  28. #endif // NEC_98
  29. #ifndef _HALI_
  30. #include "hali.h"
  31. #endif
  32. #ifdef RtlMoveMemory
  33. #undef RtlMoveMemory
  34. // #undef RtlCopyMemory
  35. // #undef RtlFillMemory
  36. // #undef RtlZeroMemory
  37. //#define RtlCopyMemory(Destination,Source,Length) RtlMoveMemory((Destination),(Source),(Length))
  38. #if defined(_WIN64)
  39. __inline
  40. VOID
  41. RtlMoveMemory (
  42. PVOID Destination,
  43. CONST VOID *Source,
  44. SIZE_T Length
  45. )
  46. {
  47. memmove(Destination,Source,Length);
  48. }
  49. #else
  50. VOID
  51. RtlMoveMemory (
  52. PVOID Destination,
  53. CONST VOID *Source,
  54. SIZE_T Length
  55. );
  56. #endif
  57. // VOID
  58. // RtlFillMemory (
  59. // PVOID Destination,
  60. // ULONG Length,
  61. // UCHAR Fill
  62. // );
  63. //
  64. // VOID
  65. // RtlZeroMemory (
  66. // PVOID Destination,
  67. // ULONG Length
  68. // );
  69. //
  70. #endif
  71. #if defined(_AMD64_)
  72. //
  73. // A temporary macro used to indicate that a particular piece of code
  74. // has never been executed on AMD64 before, and should be examined
  75. // carefully for correct operation.
  76. //
  77. #define AMD64_COVERAGE_TRAP() DbgBreakPoint()
  78. //
  79. // The following prototypes are not available from the standard HAL headers
  80. // due to the fact that NO_LEGACY_DRIVERS is defined while compiling the
  81. // HAL... however, they are used internally.
  82. //
  83. NTSTATUS
  84. HalAssignSlotResources (
  85. IN PUNICODE_STRING RegistryPath,
  86. IN PUNICODE_STRING DriverClassName OPTIONAL,
  87. IN PDRIVER_OBJECT DriverObject,
  88. IN PDEVICE_OBJECT DeviceObject,
  89. IN INTERFACE_TYPE BusType,
  90. IN ULONG BusNumber,
  91. IN ULONG SlotNumber,
  92. IN OUT PCM_RESOURCE_LIST *AllocatedResources
  93. );
  94. ULONG
  95. HalGetInterruptVector(
  96. IN INTERFACE_TYPE InterfaceType,
  97. IN ULONG BusNumber,
  98. IN ULONG BusInterruptLevel,
  99. IN ULONG BusInterruptVector,
  100. OUT PKIRQL Irql,
  101. OUT PKAFFINITY Affinity
  102. );
  103. ULONG
  104. HalGetBusData(
  105. IN BUS_DATA_TYPE BusDataType,
  106. IN ULONG BusNumber,
  107. IN ULONG SlotNumber,
  108. IN PVOID Buffer,
  109. IN ULONG Length
  110. );
  111. ULONG
  112. HalSetBusData(
  113. IN BUS_DATA_TYPE BusDataType,
  114. IN ULONG BusNumber,
  115. IN ULONG SlotNumber,
  116. IN PVOID Buffer,
  117. IN ULONG Length
  118. );
  119. //
  120. // We are sharing code that was written for the x86. There are some
  121. // macros with identical meanings but different names in AMD64. Following
  122. // are some definitions to abstract those differences.
  123. //
  124. //
  125. // CLOCK2_LEVEL on x86 is CLOCK_LEVEL on AMD64.
  126. //
  127. #define CLOCK2_LEVEL CLOCK_LEVEL
  128. //
  129. // X86 EFLAGS_INTERRUPT_MASK == AMD64 EFLAGS_IF_MASK
  130. //
  131. #define EFLAGS_INTERRUPT_MASK EFLAGS_IF_MASK
  132. //
  133. // The PCR's pointer to the current prcb is named Prcb, while on AMD64
  134. // it is named CurrentPrcb.
  135. //
  136. // The CurrentPrcb() macro is used to abstract this difference.
  137. //
  138. #define CurrentPrcb(x) (x)->CurrentPrcb
  139. //
  140. // The x86 KiReturnHandlerAddressFromIDT() is the equivalent of the AMD64's
  141. // KeGetIdtHandlerAddress()
  142. //
  143. #define KiReturnHandlerAddressFromIDT(v) (ULONG_PTR)KeGetIdtHandlerAddress(v)
  144. //
  145. // More macro and structure name differences
  146. //
  147. #define RDMSR(m) ReadMSR(m)
  148. #define WRMSR(m,d) WriteMSR(m,d)
  149. #define KGDTENTRY KGDTENTRY64
  150. #define PKGDTENTRY PKGDTENTRY64
  151. #define PIOPM_SIZE (sizeof(KIO_ACCESS_MAP) + sizeof(ULONG))
  152. //
  153. // The AMD64 in long mode uses 8-byte PTE entries, which have the same format
  154. // as Pentium PAE page tables.
  155. //
  156. #if !defined(_HALPAE_)
  157. #define _HALPAE_ 1
  158. #endif
  159. #define HARDWARE_PTE_X86PAE HARDWARE_PTE
  160. #define HARDWARE_PTE_X86 HARDWARE_PTE
  161. #define PHARDWARE_PTE_X86PAE PHARDWARE_PTE
  162. #define PHARDWARE_PTE_X86 PHARDWARE_PTE
  163. #define PDE_BASE_X86PAE PDE_BASE
  164. #define PDE_BASE_X86 PDE_BASE
  165. #define PDI_SHIFT_X86PAE PDI_SHIFT
  166. #define PDI_SHIFT_X86 PDI_SHIFT
  167. //
  168. // Fence instruction.
  169. //
  170. __forceinline
  171. VOID
  172. HalpProcessorFence (
  173. VOID
  174. )
  175. {
  176. CPU_INFO cpuInfo;
  177. KiCpuId (0,&cpuInfo);
  178. }
  179. #define HalpGetProcessorFlags() __getcallerseflags()
  180. //
  181. // While _enable() and _disable() are intrinsics in both the AMD64 and X86
  182. // compilers, they are disabled on X86. HalpDisableInterruptsNoFlags and
  183. // HalpEnableInterrupts are macros used to abstract this difference.
  184. //
  185. #define HalpDisableInterruptsNoFlags _disable
  186. #define HalpEnableInterrupts _enable
  187. //
  188. // There is no intrinsic for the hlt instruction on AMD64. HalpHalt()
  189. // is a function call on AMD64, and inline asm on X86.
  190. //
  191. VOID
  192. HalpHalt (
  193. VOID
  194. );
  195. //
  196. // On x86, the variables HalpClockSetMSRate, HalpClockMcaQueueDpc and
  197. // HalpClockWork are defined in an .asm module such that HalpClockWork
  198. // is defined as a DWORD that overlapps HalpClockSetMSRate and
  199. // HalpClockMcaQueueDpc.
  200. //
  201. // This is not directly representable in C, so instead HALP_CLOCKWORK_UNION
  202. // is defined and the above variable names are instead redefined to reference
  203. // elements of this union.
  204. //
  205. #define HalpClockSetMSRate HalpClockWorkUnion.ClockSetMSRate
  206. #define HalpClockMcaQueueDpc HalpClockWorkUnion.ClockMcaQueueDpc
  207. #define HalpClockWork HalpClockWorkUnion.ClockWork
  208. typedef union {
  209. struct {
  210. UCHAR ClockMcaQueueDpc;
  211. UCHAR ClockSetMSRate;
  212. UCHAR bReserved1;
  213. UCHAR bReserved2;
  214. };
  215. ULONG ClockWork;
  216. } HALP_CLOCKWORK_UNION;
  217. extern HALP_CLOCKWORK_UNION HalpClockWorkUnion;
  218. #else
  219. //
  220. // Following are X86 definitions that are used to help abstract differences
  221. // between X86 and AMD64 platforms.
  222. //
  223. #define AMD64_COVERAGE_TRAP()
  224. //
  225. // We are sharing code that was written for the x86. There are some
  226. // macros with identical meanings but different names in AMD64. Following
  227. // are some definitions to abstract those differences.
  228. //
  229. //
  230. // The following _KPCR fields have different names but identical purposes.
  231. //
  232. #define IdtBase IDT
  233. #define GdtBase GDT
  234. #define TssBase TSS
  235. //
  236. // The PCR's pointer to the current prcb is named Prcb, while on AMD64
  237. // it is named CurrentPrcb.
  238. //
  239. // The CurrentPrcb() macro is used to abstract this difference.
  240. //
  241. #define CurrentPrcb(x) (x)->Prcb
  242. //
  243. // On X86, HalpGetProcessorFlags() can be implemented inline.
  244. //
  245. __forceinline
  246. ULONG
  247. HalpGetProcessorFlags (
  248. VOID
  249. )
  250. /*++
  251. Routine Description:
  252. This procedure retrieves the contents of the EFLAGS register.
  253. Arguments:
  254. None.
  255. Return Value:
  256. The 32-bit contents of the EFLAGS register.
  257. --*/
  258. {
  259. ULONG flags;
  260. _asm {
  261. pushfd
  262. pop eax
  263. mov flags, eax
  264. }
  265. return flags;
  266. }
  267. //
  268. // While _enable() and _disable() are intrinsics in both the AMD64 and X86
  269. // compilers, they are disabled in the HAL on X86.
  270. //
  271. // HalpDisableInterruptsNoFlags and HalpEnableInterrupts are macros used
  272. // to abstract this difference.
  273. //
  274. #define HalpDisableInterruptsNoFlags() _asm cli
  275. #define HalpEnableInterrupts() _asm sti
  276. //
  277. // There is no intrinsic for the hlt instruction on AMD64. HalpHalt()
  278. // is a function call on AMD64, and inline asm on X86.
  279. //
  280. #define HalpHalt() _asm hlt
  281. //
  282. // Fence instruction
  283. //
  284. __forceinline
  285. VOID
  286. HalpProcessorFence (
  287. VOID
  288. )
  289. {
  290. _asm {
  291. xor eax, eax
  292. cpuid
  293. }
  294. }
  295. #endif
  296. #define PROCESSOR_FENCE HalpProcessorFence()
  297. __forceinline
  298. ULONG
  299. HalpDisableInterrupts(
  300. VOID
  301. )
  302. /*++
  303. Routine Description:
  304. This function saves the state of the processor flag register, clears the
  305. state of the interrupt flag (disables interrupts), and returns the
  306. previous contents of the processor flag register.
  307. Arguments:
  308. None.
  309. Return Value:
  310. The previous contents of the processor flag register.
  311. --*/
  312. {
  313. ULONG flags;
  314. flags = HalpGetProcessorFlags();
  315. HalpDisableInterruptsNoFlags();
  316. return flags;
  317. }
  318. __forceinline
  319. VOID
  320. HalpRestoreInterrupts(
  321. IN ULONG Flags
  322. )
  323. /*++
  324. Routine Description:
  325. This procedure restores the state of the interrupt flag based on a
  326. value returned by a previous call to HalpDisableInterrupts.
  327. Arguments:
  328. Flags - Supplies the value returned by a previous call to
  329. HalpDisableInterrupts
  330. Return Value:
  331. None.
  332. --*/
  333. {
  334. if ((Flags & EFLAGS_INTERRUPT_MASK) != 0) {
  335. HalpEnableInterrupts();
  336. }
  337. }
  338. #if defined(_WIN64)
  339. //
  340. // For AMD64 (and, ideally, all subsequent WIN64 platforms), interrupt
  341. // service routines are C callable.
  342. //
  343. typedef PKSERVICE_ROUTINE PHAL_INTERRUPT_SERVICE_ROUTINE;
  344. #define HAL_INTERRUPT_SERVICE_PROTOTYPE(RoutineName) \
  345. BOOLEAN \
  346. RoutineName ( \
  347. IN PKINTERRUPT Interrupt, \
  348. IN PVOID ServiceContext \
  349. )
  350. #define PROCESSOR_CURRENT ((UCHAR)-1)
  351. VOID
  352. HalpSetHandlerAddressToIDTIrql (
  353. IN ULONG Vector,
  354. IN PHAL_INTERRUPT_SERVICE_ROUTINE ServiceRoutine,
  355. IN PVOID Context,
  356. IN KIRQL Irql
  357. );
  358. #define KiSetHandlerAddressToIDT Dont_Use_KiSetHandlerAddressToIdt
  359. //
  360. // On AMD64, the HAL does not connect directly to the IDT, rather the
  361. // kernel handles the interrupt and calls a C-callable interrupt routine.
  362. //
  363. // Therefore, HalpSetHandlerAddressToIDT() must supply a context and an
  364. // IRQL in addition to the vector number and interrupt routine.
  365. //
  366. // On X86, the context and IRQL are ignored, as the vector is inserted
  367. // directly into the IDT, such that the service routine is responsible for
  368. // raising IRQL.
  369. //
  370. #define KiSetHandlerAddressToIDTIrql(v,a,c,i) \
  371. HalpSetHandlerAddressToIDTIrql (v,a,c,i);
  372. #else
  373. //
  374. // On X86, the last two parameters of KiSetHandlerAddressToIDTIrql()
  375. // (Context and Irql) are ignored. The interrupt handlers themselves
  376. // are responsible for raising IRQL.
  377. //
  378. #define KiSetHandlerAddressToIDTIrql(v,a,c,i) KiSetHandlerAddressToIDT(v,a)
  379. //
  380. // For X86, interrupt service routines must be written in assembler because
  381. // they are referenced directly in the IDT and trasferred to directly by
  382. // the processor with a convention that is not C callable.
  383. //
  384. // For purposes of C code that references ISRs, then, the prototype is
  385. // very simple.
  386. //
  387. typedef
  388. VOID
  389. (*PHAL_INTERRUPT_SERVICE_ROUTINE)(
  390. VOID
  391. );
  392. #define HAL_INTERRUPT_SERVICE_PROTOTYPE(RoutineName) \
  393. VOID \
  394. RoutineName ( \
  395. VOID \
  396. )
  397. #endif
  398. typedef
  399. VOID
  400. (*HALP_MOVE_MEMORY_ROUTINE)(
  401. PVOID Destination,
  402. CONST VOID *Source,
  403. SIZE_T Length
  404. );
  405. VOID
  406. HalpMovntiCopyBuffer(
  407. PVOID Destination,
  408. CONST VOID *Source,
  409. ULONG Length
  410. );
  411. VOID
  412. HalpSetInternalVector (
  413. IN ULONG InternalVector,
  414. IN PHAL_INTERRUPT_SERVICE_ROUTINE HalInterruptSerivceRoutine,
  415. IN PVOID Context,
  416. IN KIRQL Irql
  417. );
  418. extern HALP_MOVE_MEMORY_ROUTINE HalpMoveMemory;
  419. #if MCA
  420. #include "ixmca.h"
  421. #else
  422. #include "ixisa.h"
  423. #endif
  424. #include "ix8259.inc"
  425. #if DBG
  426. extern ULONG HalDebug;
  427. #define HalPrint(x) \
  428. if (HalDebug) { \
  429. DbgPrint("HAL: "); \
  430. DbgPrint x; \
  431. DbgPrint("\n"); \
  432. }
  433. #else
  434. #define HalPrint(x)
  435. #endif
  436. //
  437. // Define map register translation entry structure.
  438. //
  439. typedef struct _TRANSLATION_ENTRY {
  440. PVOID VirtualAddress;
  441. ULONG PhysicalAddress;
  442. ULONG Index;
  443. } TRANSLATION_ENTRY, *PTRANSLATION_ENTRY;
  444. //
  445. // Some devices require a phyicially contiguous data buffers for DMA transfers.
  446. // Map registers are used give the appearance that all data buffers are
  447. // contiguous. In order to pool all of the map registers a master
  448. // adapter object is used. This object is allocated and saved internal to this
  449. // file. It contains a bit map for allocation of the registers and a queue
  450. // for requests which are waiting for more map registers. This object is
  451. // allocated during the first request to allocate an adapter which requires
  452. // map registers.
  453. //
  454. // In this system, the map registers are translation entries which point to
  455. // map buffers. Map buffers are physically contiguous and have physical memory
  456. // addresses less than 0x01000000. All of the map registers are allocated
  457. // initialially; however, the map buffers are allocated base in the number of
  458. // adapters which are allocated.
  459. //
  460. // If the master adapter is NULL in the adapter object then device does not
  461. // require any map registers.
  462. //
  463. extern POBJECT_TYPE *IoAdapterObjectType;
  464. extern BOOLEAN LessThan16Mb;
  465. extern BOOLEAN HalpEisaDma;
  466. VOID
  467. HalpGrowMapBufferWorker(
  468. IN PVOID Context
  469. );
  470. //
  471. // Work item to grow map buffers
  472. //
  473. typedef struct _BUFFER_GROW_WORK_ITEM {
  474. WORK_QUEUE_ITEM WorkItem;
  475. PADAPTER_OBJECT AdapterObject;
  476. ULONG MapRegisterCount;
  477. } BUFFER_GROW_WORK_ITEM, *PBUFFER_GROW_WORK_ITEM;
  478. //
  479. // Map buffer prameters. These are initialized in HalInitSystem
  480. //
  481. //
  482. // PAE note:
  483. //
  484. // Previously, there was only one class of adapter that we had to double-buffer
  485. // for: adapters with only 24 address lines that could access memory up to
  486. // 16MB.
  487. //
  488. // The HAL tracked these map buffers with a single, global master adapter.
  489. // Associated with this master adapter were three global variables:
  490. //
  491. // - MasterAdapterObject
  492. // - HalpMapBufferSize
  493. // - HalpMapBufferPhysicalAddress
  494. //
  495. // With PAE, we have another class of adapters that require double-buffering:
  496. // specifically, adapters with only 32 address lines that can access memory
  497. // up to 4G.
  498. //
  499. // This meant the introduction of another master adapter along with an
  500. // associated set of variables. For PAE-capable hals, this data has been
  501. // reorganized into a MASTER_ADAPTER_OBJECT (see ixisa.h).
  502. //
  503. // So now we have two global MASTER_ADAPTER_OBJECT structures:
  504. //
  505. // MasterAdapter24
  506. // MasterAdapter32
  507. //
  508. // The following macros are used in code that is included in PAE-capable
  509. // hals. It is important to note that in a non-PAE-capable HAL (i.e. one
  510. // that does not have _HALPAE_ defined), the macros must resolve to the
  511. // values that they replaced.
  512. //
  513. #if defined(_HALPAE_)
  514. PADAPTER_OBJECT
  515. HalpAllocateAdapterEx(
  516. IN ULONG MapRegistersPerChannel,
  517. IN PVOID AdapterBaseVa,
  518. IN PVOID ChannelNumber,
  519. IN BOOLEAN Dma32Bit
  520. );
  521. extern MASTER_ADAPTER_OBJECT MasterAdapter24;
  522. extern MASTER_ADAPTER_OBJECT MasterAdapter32;
  523. #define HalpMasterAdapterStruc( Dma32Bit ) \
  524. ((HalPaeEnabled() && (Dma32Bit)) ? &MasterAdapter32 : &MasterAdapter24)
  525. #define HalpMaximumMapBufferRegisters( Dma32Bit ) \
  526. (HalpMasterAdapterStruc( Dma32Bit )->MaxBufferPages)
  527. #define HalpMaximumMapRegisters( Dma32Bit ) \
  528. (Dma32Bit ? MAXIMUM_PCI_MAP_REGISTER : MAXIMUM_ISA_MAP_REGISTER)
  529. #define HalpMapBufferSize( Dma32Bit ) \
  530. (HalpMasterAdapterStruc( Dma32Bit )->MapBufferSize)
  531. #define HalpMapBufferPhysicalAddress( Dma32Bit ) \
  532. (HalpMasterAdapterStruc( Dma32Bit )->MapBufferPhysicalAddress)
  533. #define HalpMasterAdapter( Dma32Bit ) \
  534. HalpMasterAdapterStruc( Dma32Bit )->AdapterObject
  535. #else
  536. extern PHYSICAL_ADDRESS HalpMapBufferPhysicalAddress;
  537. extern ULONG HalpMapBufferSize;
  538. extern PADAPTER_OBJECT MasterAdapterObject;
  539. #define HalpAllocateAdapterEx( _m, _a, _c, _d ) \
  540. HalpAllocateAdapter( _m, _a, _c )
  541. #define HalpMaximumMapBufferRegisters( Dma32Bit ) \
  542. (MAXIMUM_MAP_BUFFER_SIZE / PAGE_SIZE)
  543. #define HalpMaximumMapRegisters( Dma32Bit ) \
  544. (MAXIMUM_ISA_MAP_REGISTER)
  545. #define HalpMapBufferSize( Dma32Bit ) HalpMapBufferSize
  546. #define HalpMapBufferPhysicalAddress( Dma32Bit ) \
  547. (HalpMapBufferPhysicalAddress)
  548. #define HalpMasterAdapter( Dma32Bit ) MasterAdapterObject
  549. #endif
  550. extern ULONG HalpBusType;
  551. extern ULONG HalpCpuType;
  552. extern UCHAR HalpSerialLen;
  553. extern UCHAR HalpSerialNumber[];
  554. #if defined(_AMD64_)
  555. //
  556. // Amd64 decodes 48 bits of virtual address space.
  557. //
  558. #define MI_DECODE_MASK (((ULONG64)1 << 48) - 1)
  559. #define VA_TRUNC(x) ((ULONG64)(x) & MI_DECODE_MASK)
  560. #else
  561. #define VA_TRUNC(x) (x)
  562. #endif
  563. //
  564. // The following macros are taken from mm\i386\mi386.h. We need them here
  565. // so the HAL can map its own memory before memory-management has been
  566. // initialized, or during a BugCheck.
  567. //
  568. // MiGetPdeAddress returns the address of the PDE which maps the
  569. // given virtual address.
  570. //
  571. #define MiGetPdeAddressX86(va) ((PHARDWARE_PTE)(((((ULONG_PTR)(va)) >> 22) << 2) + PDE_BASE))
  572. //
  573. // MiGetPteAddress returns the address of the PTE which maps the
  574. // given virtual address.
  575. //
  576. #define MiGetPteAddressX86(va) ((PHARDWARE_PTE)(((((ULONG_PTR)(va)) >> 12) << 2) + PTE_BASE))
  577. //
  578. // MiGetPteIndex returns the index within a page table of the PTE for the
  579. // given virtual address
  580. //
  581. #define MiGetPteIndexX86(va) (((ULONG_PTR)(va) >> PAGE_SHIFT) & 0x3FF)
  582. #define MiGetPteIndexPae(va) (((ULONG_PTR)(VA_TRUNC(va)) >> PAGE_SHIFT) & 0x1FF)
  583. //
  584. // The following macros are taken from mm\i386\mipae.h. We need them here
  585. // so the HAL can map its own memory before memory-management has been
  586. // initialized, or during a BugCheck.
  587. //
  588. // MiGetPdeAddressPae returns the address of the PDE which maps the
  589. // given virtual address.
  590. //
  591. #define MiGetPdeAddressPae(va) ((PHARDWARE_PTE_X86PAE)(PDE_BASE_X86PAE + ((((ULONG_PTR)(VA_TRUNC(va))) >> 21) << 3)))
  592. //
  593. // MiGetPteAddressPae returns the address of the PTE which maps the
  594. // given virtual address.
  595. //
  596. #define MiGetPteAddressPae(va) ((PHARDWARE_PTE_X86PAE)(PTE_BASE + ((((ULONG_PTR)(VA_TRUNC(va))) >> 12) << 3)))
  597. //
  598. // Resource usage information
  599. //
  600. #pragma pack(1)
  601. typedef struct {
  602. UCHAR Flags;
  603. } IDTUsageFlags;
  604. typedef struct {
  605. KIRQL Irql;
  606. UCHAR BusReleativeVector;
  607. } IDTUsage;
  608. typedef struct _HalAddressUsage{
  609. struct _HalAddressUsage *Next;
  610. CM_RESOURCE_TYPE Type; // Port or Memory
  611. UCHAR Flags; // same as IDTUsage.Flags
  612. struct {
  613. ULONG Start;
  614. ULONG Length;
  615. } Element[];
  616. } ADDRESS_USAGE;
  617. #pragma pack()
  618. #define IDTOwned 0x01 // IDT is not available for others
  619. #define InterruptLatched 0x02 // Level or Latched
  620. #define RomResource 0x04 // ROM
  621. #define InternalUsage 0x11 // Report usage on internal bus
  622. #define DeviceUsage 0x21 // Report usage on device bus
  623. extern IDTUsageFlags HalpIDTUsageFlags[];
  624. extern IDTUsage HalpIDTUsage[];
  625. extern ADDRESS_USAGE *HalpAddressUsageList;
  626. #define HalpRegisterAddressUsage(a) \
  627. (a)->Next = HalpAddressUsageList, HalpAddressUsageList = (a);
  628. //
  629. // Temp definitions to thunk into supporting new bus extension format
  630. //
  631. VOID
  632. HalpRegisterInternalBusHandlers (
  633. VOID
  634. );
  635. PBUS_HANDLER
  636. HalpAllocateBusHandler (
  637. IN INTERFACE_TYPE InterfaceType,
  638. IN BUS_DATA_TYPE BusDataType,
  639. IN ULONG BusNumber,
  640. IN INTERFACE_TYPE ParentBusDataType,
  641. IN ULONG ParentBusNumber,
  642. IN ULONG BusSpecificData
  643. );
  644. #define HalpHandlerForBus HaliHandlerForBus
  645. #define HalpSetBusHandlerParent(c,p) (c)->ParentHandler = p;
  646. //
  647. // Define function prototypes.
  648. //
  649. VOID
  650. HalInitSystemPhase2(
  651. VOID
  652. );
  653. KIRQL
  654. HaliRaiseIrqlToDpcLevel (
  655. VOID
  656. );
  657. BOOLEAN
  658. HalpGrowMapBuffers(
  659. PADAPTER_OBJECT AdapterObject,
  660. ULONG Amount
  661. );
  662. PADAPTER_OBJECT
  663. HalpAllocateAdapter(
  664. IN ULONG MapRegistersPerChannel,
  665. IN PVOID AdapterBaseVa,
  666. IN PVOID MapRegisterBase
  667. );
  668. HAL_INTERRUPT_SERVICE_PROTOTYPE(HalpClockInterrupt);
  669. KIRQL
  670. HalpDisableAllInterrupts (
  671. VOID
  672. );
  673. VOID
  674. HalpReenableInterrupts (
  675. KIRQL NewIrql
  676. );
  677. #if defined(_AMD64_)
  678. VOID
  679. HalpInitializeProfiling (
  680. ULONG Number
  681. );
  682. NTSTATUS
  683. HalpSetProfileSourceInterval(
  684. IN KPROFILE_SOURCE ProfileSource,
  685. IN OUT ULONG_PTR *Interval
  686. );
  687. NTSTATUS
  688. HalpQueryProfileInformation(
  689. IN HAL_QUERY_INFORMATION_CLASS InformationClass,
  690. IN ULONG BufferSize,
  691. OUT PVOID Buffer,
  692. OUT PULONG ReturnedLength
  693. );
  694. #endif
  695. HAL_INTERRUPT_SERVICE_PROTOTYPE(HalpProfileInterrupt);
  696. VOID
  697. HalpInitializeClock(
  698. VOID
  699. );
  700. VOID
  701. HalpInitializeStallExecution(
  702. IN CCHAR ProcessorNumber
  703. );
  704. VOID
  705. HalpRemoveFences (
  706. VOID
  707. );
  708. VOID
  709. HalpInitializePICs(
  710. BOOLEAN EnableInterrupts
  711. );
  712. VOID
  713. HalpIrq13Handler (
  714. VOID
  715. );
  716. VOID
  717. HalpFlushTLB (
  718. VOID
  719. );
  720. VOID
  721. HalpSerialize (
  722. VOID
  723. );
  724. PVOID
  725. HalpMapPhysicalMemory64(
  726. IN PHYSICAL_ADDRESS PhysicalAddress,
  727. IN ULONG NumberPages
  728. );
  729. PVOID
  730. HalpMapPhysicalMemoryWriteThrough64(
  731. IN PHYSICAL_ADDRESS PhysicalAddress,
  732. IN ULONG NumberPages
  733. );
  734. ULONG
  735. HalpAllocPhysicalMemory(
  736. IN PLOADER_PARAMETER_BLOCK LoaderBlock,
  737. IN ULONG MaxPhysicalAddress,
  738. IN ULONG NoPages,
  739. IN BOOLEAN bAlignOn64k
  740. );
  741. VOID
  742. HalpUnmapVirtualAddress(
  743. IN PVOID VirtualAddress,
  744. IN ULONG NumberPages
  745. );
  746. PVOID
  747. HalpRemapVirtualAddress64 (
  748. IN PVOID VirtualAddress,
  749. IN PHYSICAL_ADDRESS PhysicalAddress,
  750. IN BOOLEAN WriteThrough
  751. );
  752. PHYSICAL_ADDRESS
  753. __inline
  754. HalpPtrToPhysicalAddress(
  755. IN PVOID Address
  756. )
  757. /*++
  758. Routine Description:
  759. This routine converts a physical address expressed as a PVOID into
  760. a physical address expresses as PHYSICAL_ADDRESS.
  761. Arguments:
  762. Address - PVOID representation of the physical address.
  763. Return Value:
  764. PHYSICAL_ADDRESS representation of the physical address.
  765. --*/
  766. {
  767. PHYSICAL_ADDRESS physicalAddress;
  768. physicalAddress.QuadPart = (ULONG_PTR)Address;
  769. return physicalAddress;
  770. }
  771. #if defined(_HALPAE_)
  772. //
  773. // This hal is to be PAE compatible. Therefore, physical addresses must
  774. // be treated as 64-bit entitites instead of PVOID.
  775. //
  776. #define _PHYS64_
  777. #endif
  778. #if defined(_PHYS64_)
  779. //
  780. // HALs with _PHYS64_ defined pass physical addresses as PHYSICAL_ADDRESS,
  781. // so call the 64-bit versions of these routines directly.
  782. //
  783. #define HalpMapPhysicalMemory HalpMapPhysicalMemory64
  784. #define HalpMapPhysicalMemoryWriteThrough HalpMapPhysicalMemoryWriteThrough64
  785. #define HalpRemapVirtualAddress HalpRemapVirtualAddress64
  786. #define HalpMapPhysicalRange(_addr_,_len_) \
  787. HalpMapPhysicalMemory((_addr_), \
  788. HalpRangePages((_addr_).QuadPart,(_len_)))
  789. #define HalpUnMapPhysicalRange(_addr_,_len_) \
  790. HalpUnmapVirtualAddress((_addr_), \
  791. HalpRangePages((ULONG_PTR)(_addr_),(_len_)))
  792. #else
  793. //
  794. // HALs without _PHYS64_ defined pass physical addresses as PVOIDs. Convert
  795. // such parameters to PHYSICAL_ADDRESS before passing to the 64-bit routines.
  796. //
  797. PVOID
  798. __inline
  799. HalpMapPhysicalMemory(
  800. IN PVOID PhysicalAddress,
  801. IN ULONG NumberPages
  802. )
  803. {
  804. PHYSICAL_ADDRESS physicalAddress;
  805. physicalAddress = HalpPtrToPhysicalAddress( PhysicalAddress );
  806. return HalpMapPhysicalMemory64( physicalAddress, NumberPages );
  807. }
  808. PVOID
  809. __inline
  810. HalpMapPhysicalMemoryWriteThrough(
  811. IN PVOID PhysicalAddress,
  812. IN ULONG NumberPages
  813. )
  814. {
  815. PHYSICAL_ADDRESS physicalAddress;
  816. physicalAddress = HalpPtrToPhysicalAddress( PhysicalAddress );
  817. return HalpMapPhysicalMemoryWriteThrough64( physicalAddress, NumberPages );
  818. }
  819. PVOID
  820. __inline
  821. HalpRemapVirtualAddress(
  822. IN PVOID VirtualAddress,
  823. IN PVOID PhysicalAddress,
  824. IN BOOLEAN WriteThrough
  825. )
  826. {
  827. PHYSICAL_ADDRESS physicalAddress;
  828. physicalAddress = HalpPtrToPhysicalAddress( PhysicalAddress );
  829. return HalpRemapVirtualAddress64( VirtualAddress,
  830. physicalAddress,
  831. WriteThrough );
  832. }
  833. #define HalpMapPhysicalRangeWriteThrough(_addr_,_len_) \
  834. HalpMapPhysicalMemoryWriteThrough((_addr_), \
  835. HalpRangePages((ULONG_PTR)(_addr_),(_len_)))
  836. #define HalpMapPhysicalRange(_addr_,_len_) \
  837. HalpMapPhysicalMemory((_addr_), \
  838. HalpRangePages((ULONG_PTR)(_addr_),(_len_)))
  839. #define HalpUnMapPhysicalRange(_addr_,_len_) \
  840. HalpUnmapVirtualAddress((_addr_), \
  841. HalpRangePages((ULONG_PTR)(_addr_),(_len_)))
  842. #endif
  843. ULONG
  844. __inline
  845. HalpRangePages(
  846. IN ULONGLONG Address,
  847. IN ULONG Length
  848. )
  849. {
  850. ULONG startPage;
  851. ULONG endPage;
  852. startPage = (ULONG)(Address / PAGE_SIZE);
  853. endPage = (ULONG)((Address + Length + PAGE_SIZE - 1) / PAGE_SIZE);
  854. return endPage - startPage;
  855. }
  856. BOOLEAN
  857. HalpBiosDisplayReset(
  858. IN VOID
  859. );
  860. HAL_DISPLAY_BIOS_INFORMATION
  861. HalpGetDisplayBiosInformation (
  862. VOID
  863. );
  864. VOID
  865. HalpInitializeCmos (
  866. VOID
  867. );
  868. VOID
  869. HalpReadCmosTime (
  870. PTIME_FIELDS TimeFields
  871. );
  872. VOID
  873. HalpWriteCmosTime (
  874. PTIME_FIELDS TimeFields
  875. );
  876. VOID
  877. HalpAcquireCmosSpinLock (
  878. VOID
  879. );
  880. VOID
  881. HalpReleaseCmosSpinLock (
  882. VOID
  883. );
  884. VOID
  885. HalpResetAllProcessors (
  886. VOID
  887. );
  888. VOID
  889. HalpWriteResetCommand (
  890. VOID
  891. );
  892. VOID
  893. HalpCpuID (
  894. ULONG InEax,
  895. PULONG OutEax,
  896. PULONG OutEbx,
  897. PULONG OutEcx,
  898. PULONG OutEdx
  899. );
  900. #if defined(_WIN64)
  901. #define HalpYieldProcessor()
  902. #else
  903. VOID
  904. HalpYieldProcessor (
  905. VOID
  906. );
  907. #endif
  908. ULONGLONG
  909. FASTCALL
  910. RDMSR (
  911. IN ULONG MsrAddress
  912. );
  913. VOID
  914. WRMSR (
  915. IN ULONG MsrAddress,
  916. IN ULONGLONG MsrValue
  917. );
  918. NTSTATUS
  919. HalpEnableInterruptHandler (
  920. IN UCHAR ReportFlags,
  921. IN ULONG BusInterruptVector,
  922. IN ULONG SystemInterruptVector,
  923. IN KIRQL SystemIrql,
  924. IN PHAL_INTERRUPT_SERVICE_ROUTINE HalInterruptServiceRoutine,
  925. IN KINTERRUPT_MODE InterruptMode
  926. );
  927. VOID
  928. HalpRegisterVector (
  929. IN UCHAR ReportFlags,
  930. IN ULONG BusInterruptVector,
  931. IN ULONG SystemInterruptVector,
  932. IN KIRQL SystemIrql
  933. );
  934. VOID
  935. HalpReportResourceUsage (
  936. IN PUNICODE_STRING HalName,
  937. IN INTERFACE_TYPE DeviceInterfaceToUse
  938. );
  939. VOID
  940. HalpYearIs(
  941. IN ULONG Year
  942. );
  943. VOID
  944. HalpRecordEisaInterruptVectors(
  945. VOID
  946. );
  947. VOID
  948. HalpMcaCurrentProcessorSetConfig(
  949. VOID
  950. );
  951. NTSTATUS
  952. HalpGetNextProcessorApicId(
  953. IN ULONG ProcessorNumber,
  954. IN OUT UCHAR *ApicId
  955. );
  956. VOID
  957. FASTCALL
  958. HalpIoDelay (
  959. VOID
  960. );
  961. //
  962. // Defines for HalpFeatureBits
  963. //
  964. #define HAL_PERF_EVENTS 0x00000001
  965. #define HAL_NO_SPECULATION 0x00000002
  966. #define HAL_MCA_PRESENT 0x00000004 // Intel MCA Available
  967. #define HAL_MCE_PRESENT 0x00000008 // ONLY Pentium style MCE available
  968. #define HAL_CR4_PRESENT 0x00000010
  969. #define HAL_WNI_PRESENT 0x00000020
  970. #define HAL_NX_PRESENT 0x00000040 // from extended processor features
  971. extern ULONG HalpFeatureBits;
  972. extern USHORT HalpPciIrqMask;
  973. //
  974. // Defines for Processor Features returned from CPUID instruction
  975. //
  976. #define CPUID_MCA_MASK 0x4000
  977. #define CPUID_MCE_MASK 0x0080
  978. #define CPUID_VME_MASK 0x0002
  979. #define CPUID_WNI_MASK 0x04000000
  980. #define CPUID_NX_MASK 0x00100000
  981. NTSTATUS
  982. HalpGetMceInformation(
  983. IN PHAL_ERROR_INFO ErrorInfo,
  984. OUT PULONG ErrorInfoLength
  985. );
  986. NTSTATUS
  987. HalpMceRegisterKernelDriver(
  988. IN PKERNEL_ERROR_HANDLER_INFO KernelErrorHandler,
  989. IN ULONG InfoSize
  990. );
  991. //
  992. // Token passed in by WMI to distinguish it from the MCA logging driver.
  993. //
  994. #define HALP_KERNEL_TOKEN 0x59364117
  995. NTSTATUS
  996. HalpGetMcaLog(
  997. OUT PMCA_EXCEPTION Exception,
  998. IN ULONG BufferSize,
  999. OUT PULONG ReturnedLength
  1000. );
  1001. NTSTATUS
  1002. HalpMcaRegisterDriver(
  1003. IN PMCA_DRIVER_INFO pMcaDriverInfo // Info about registering driver
  1004. );
  1005. VOID
  1006. HalpMcaInit(
  1007. VOID
  1008. );
  1009. //
  1010. // Disable the Local APIC on UP (PIC 8259) PentiumPro systems to work around
  1011. // spurious interrupt errata.
  1012. //
  1013. #define APIC_BASE_MSR 0x1B
  1014. #define APIC_ENABLED 0x0000000000000800
  1015. //
  1016. // PnP stuff
  1017. //
  1018. #define HAL_BUS_INTERFACE_STD_VERSION 1
  1019. #define HAL_IRQ_TRANSLATOR_VERSION 0
  1020. #define HAL_MEMIO_TRANSLATOR_VERSION 1
  1021. VOID
  1022. HalTranslatorReference(
  1023. PVOID Context
  1024. );
  1025. VOID
  1026. HalTranslatorDereference(
  1027. PVOID Context
  1028. );
  1029. NTSTATUS
  1030. HalIrqTranslateResources(
  1031. IN PVOID Context,
  1032. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  1033. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  1034. IN ULONG AlternativesCount, OPTIONAL
  1035. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  1036. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1037. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  1038. );
  1039. NTSTATUS
  1040. HalIrqTranslateResourcesRoot(
  1041. IN PVOID Context,
  1042. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  1043. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  1044. IN ULONG AlternativesCount, OPTIONAL
  1045. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  1046. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1047. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  1048. );
  1049. NTSTATUS
  1050. HalIrqTranslateResourceRequirementsRoot(
  1051. IN PVOID Context,
  1052. IN PIO_RESOURCE_DESCRIPTOR Source,
  1053. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1054. OUT PULONG TargetCount,
  1055. OUT PIO_RESOURCE_DESCRIPTOR *Target
  1056. );
  1057. NTSTATUS
  1058. HalIrqTranslateResourceRequirementsIsa(
  1059. IN PVOID Context,
  1060. IN PIO_RESOURCE_DESCRIPTOR Source,
  1061. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1062. OUT PULONG TargetCount,
  1063. OUT PIO_RESOURCE_DESCRIPTOR *Target
  1064. );
  1065. NTSTATUS
  1066. HalIrqTranslateResourcesIsa(
  1067. IN PVOID Context,
  1068. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  1069. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  1070. IN ULONG AlternativesCount, OPTIONAL
  1071. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  1072. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1073. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  1074. );
  1075. NTSTATUS
  1076. HalpTransMemIoResourceRequirement(
  1077. IN PVOID Context,
  1078. IN PIO_RESOURCE_DESCRIPTOR Source,
  1079. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1080. OUT PULONG TargetCount,
  1081. OUT PIO_RESOURCE_DESCRIPTOR *Target
  1082. );
  1083. NTSTATUS
  1084. HalpTransMemIoResource(
  1085. IN PVOID Context,
  1086. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  1087. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  1088. IN ULONG AlternativesCount, OPTIONAL
  1089. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  1090. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1091. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  1092. );
  1093. NTSTATUS
  1094. HalIrqTranslateRequirementsPciBridge(
  1095. IN PVOID Context,
  1096. IN PIO_RESOURCE_DESCRIPTOR Source,
  1097. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1098. OUT PULONG TargetCount,
  1099. OUT PIO_RESOURCE_DESCRIPTOR *Target
  1100. );
  1101. NTSTATUS
  1102. HalIrqTranslateResourcesPciBridge(
  1103. IN PVOID Context,
  1104. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  1105. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  1106. IN ULONG AlternativesCount, OPTIONAL
  1107. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  1108. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1109. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  1110. );
  1111. NTSTATUS
  1112. HalpIrqTranslateRequirementsPci(
  1113. IN PVOID Context,
  1114. IN PIO_RESOURCE_DESCRIPTOR Source,
  1115. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1116. OUT PULONG TargetCount,
  1117. OUT PIO_RESOURCE_DESCRIPTOR *Target
  1118. );
  1119. NTSTATUS
  1120. HalpIrqTranslateResourcesPci(
  1121. IN PVOID Context,
  1122. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  1123. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  1124. IN ULONG AlternativesCount, OPTIONAL
  1125. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  1126. IN PDEVICE_OBJECT PhysicalDeviceObject,
  1127. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  1128. );
  1129. BOOLEAN
  1130. HalpTranslateSystemBusAddress(
  1131. IN PBUS_HANDLER BusHandler,
  1132. IN PBUS_HANDLER RootHandler,
  1133. IN PHYSICAL_ADDRESS BusAddress,
  1134. IN OUT PULONG AddressSpace,
  1135. OUT PPHYSICAL_ADDRESS TranslatedAddress
  1136. );
  1137. ULONG
  1138. HalpGetSystemInterruptVector(
  1139. IN PBUS_HANDLER BusHandler,
  1140. IN PBUS_HANDLER RootHandler,
  1141. IN ULONG InterruptLevel,
  1142. IN ULONG InterruptVector,
  1143. OUT PKIRQL Irql,
  1144. OUT PKAFFINITY Affinity
  1145. );
  1146. ULONG
  1147. HalpGetIsaIrqState(
  1148. ULONG Vector
  1149. );
  1150. extern INT_ROUTE_INTERFACE_STANDARD PciIrqRoutingInterface;
  1151. #if defined(_WIN64)
  1152. #define MM_HAL_RESERVED ((PVOID)HAL_VA_START)
  1153. #else
  1154. #define MM_HAL_RESERVED ((PVOID)0xffc00000)
  1155. #endif
  1156. #if defined(_HALPAE_)
  1157. #if defined(_AMD64_)
  1158. //
  1159. // For the purposes of the AMD64 HAL, "PAE" mode is always enabled, therefore
  1160. // no run-time PAE checks are necessary.
  1161. //
  1162. #define HalPaeEnabled() TRUE
  1163. #else // _AMD64_
  1164. //
  1165. // This hal supports PAE mode. Therefore checks need to be made at run-time
  1166. // to determine whether PAE is enabled or not.
  1167. //
  1168. BOOLEAN
  1169. __inline
  1170. HalPaeEnabled(
  1171. VOID
  1172. )
  1173. {
  1174. return SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] != FALSE;
  1175. }
  1176. #endif // _AMD64_
  1177. #else
  1178. //
  1179. // This hal does not support PAE mode. Therefore no run-time PAE checks
  1180. // are necessary.
  1181. //
  1182. #define HalPaeEnabled() FALSE
  1183. #endif
  1184. //
  1185. // The following inline functions and macros are used so that PHARDWARE_PTE
  1186. // can be used as a pointer to a four-byte legacy PTE or an eight-byte
  1187. // PAE PTE.
  1188. //
  1189. // With the exception of the PageFrameNumber field, all fields in these two
  1190. // different PTE formats are identical. Therefore access to these fields
  1191. // can be made directly.
  1192. //
  1193. // However, code in a PAE-enabled HAL may not access the PageFrameNumber
  1194. // of a PTE directly, nor may it make any assumptions about the size of a
  1195. // PTE or the number of address bits decoded by the page directory pointer
  1196. // table, the page directory or the page table. Instead, the following
  1197. // inline functions should be used.
  1198. //
  1199. ULONG
  1200. __inline
  1201. HalPteSize(
  1202. VOID
  1203. )
  1204. /*++
  1205. Routine Description:
  1206. This routine returns the size, in bytes, of a PTE.
  1207. Arguments:
  1208. None.
  1209. Return Value:
  1210. The size, in bytes, of a PTE.
  1211. --*/
  1212. {
  1213. if (HalPaeEnabled() != FALSE) {
  1214. return sizeof(HARDWARE_PTE_X86PAE);
  1215. } else {
  1216. return sizeof(HARDWARE_PTE_X86);
  1217. }
  1218. }
  1219. PHARDWARE_PTE
  1220. __inline
  1221. HalpIndexPteArray(
  1222. IN PHARDWARE_PTE BasePte,
  1223. IN ULONG Index
  1224. )
  1225. /*++
  1226. Routine Description:
  1227. This routine returns the address of a PTE within an array of PTEs.
  1228. Arguments:
  1229. BasePte - Pointer to the PTE array.
  1230. Index - Index within the PTE array.
  1231. Return Value:
  1232. Address of BasePte[ Index ]
  1233. --*/
  1234. {
  1235. PHARDWARE_PTE pointerPte;
  1236. pointerPte = (PHARDWARE_PTE)((ULONG_PTR)BasePte + Index * HalPteSize());
  1237. return pointerPte;
  1238. }
  1239. VOID
  1240. __inline
  1241. HalpAdvancePte(
  1242. IN OUT PHARDWARE_PTE *PointerPte,
  1243. IN ULONG Count
  1244. )
  1245. /*++
  1246. Routine Description:
  1247. This routine advances the value of a PTE pointer by the specified number
  1248. of PTEs.
  1249. Arguments:
  1250. PointerPte - Pointer to the PTE pointer to increment.
  1251. Count - Number of PTEs to advance the PTE pointer.
  1252. Return Value:
  1253. None.
  1254. --*/
  1255. {
  1256. *PointerPte = HalpIndexPteArray( *PointerPte, Count );
  1257. }
  1258. VOID
  1259. __inline
  1260. HalpIncrementPte(
  1261. IN PHARDWARE_PTE *PointerPte
  1262. )
  1263. /*++
  1264. Routine Description:
  1265. This routine increments the value of a PTE pointer by one PTE.
  1266. Arguments:
  1267. PointerPte - Pointer to the PTE pointer to increment.
  1268. Return Value:
  1269. None.
  1270. --*/
  1271. {
  1272. HalpAdvancePte( PointerPte, 1 );
  1273. }
  1274. VOID
  1275. __inline
  1276. HalpSetPageFrameNumber(
  1277. IN OUT PHARDWARE_PTE PointerPte,
  1278. IN ULONGLONG PageFrameNumber
  1279. )
  1280. /*++
  1281. Routine Description:
  1282. This routine sets the PageFrameNumber within a PTE.
  1283. Arguments:
  1284. PointerPte - Pointer to the PTE to modify.
  1285. Return Value:
  1286. None.
  1287. --*/
  1288. {
  1289. PHARDWARE_PTE_X86PAE pointerPtePae;
  1290. if (HalPaeEnabled() != FALSE) {
  1291. pointerPtePae = (PHARDWARE_PTE_X86PAE)PointerPte;
  1292. pointerPtePae->PageFrameNumber = PageFrameNumber;
  1293. } else {
  1294. PointerPte->PageFrameNumber = (ULONG_PTR)PageFrameNumber;
  1295. }
  1296. }
  1297. ULONGLONG
  1298. __inline
  1299. HalpGetPageFrameNumber(
  1300. IN PHARDWARE_PTE PointerPte
  1301. )
  1302. /*++
  1303. Routine Description:
  1304. This routine retrieves PageFrameNumber from within a PTE.
  1305. Arguments:
  1306. PointerPte - Pointer to the PTE to read.
  1307. Return Value:
  1308. The page frame number within the PTE.
  1309. --*/
  1310. {
  1311. PHARDWARE_PTE_X86PAE pointerPtePae;
  1312. ULONGLONG pageFrameNumber;
  1313. if (HalPaeEnabled() != FALSE) {
  1314. pointerPtePae = (PHARDWARE_PTE_X86PAE)PointerPte;
  1315. pageFrameNumber = pointerPtePae->PageFrameNumber;
  1316. } else {
  1317. pageFrameNumber = PointerPte->PageFrameNumber;
  1318. }
  1319. return pageFrameNumber;
  1320. }
  1321. VOID
  1322. __inline
  1323. HalpCopyPageFrameNumber(
  1324. OUT PHARDWARE_PTE DestinationPte,
  1325. IN PHARDWARE_PTE SourcePte
  1326. )
  1327. /*++
  1328. Routine Description:
  1329. This routine copies the page frame number from one PTE to another PTE.
  1330. Arguments:
  1331. DestinationPte - Pointer to the PTE in which the new page frame number
  1332. will be stored.
  1333. PointerPte - Pointer to the PTE from which the page frame number will be
  1334. read.
  1335. Return Value:
  1336. None.
  1337. --*/
  1338. {
  1339. ULONGLONG pageFrameNumber;
  1340. pageFrameNumber = HalpGetPageFrameNumber( SourcePte );
  1341. HalpSetPageFrameNumber( DestinationPte, pageFrameNumber );
  1342. }
  1343. BOOLEAN
  1344. __inline
  1345. HalpIsPteFree(
  1346. IN PHARDWARE_PTE PointerPte
  1347. )
  1348. /*++
  1349. Routine Description:
  1350. This routine determines whether a PTE is free or not. A free PTE is defined
  1351. here as one containing all zeros.
  1352. Arguments:
  1353. PointerPte - Pointer to the PTE for which the detmination is desired.
  1354. Return Value:
  1355. TRUE - The PTE is free.
  1356. FALSE - The PTE is not free.
  1357. --*/
  1358. {
  1359. ULONGLONG pteContents;
  1360. if (HalPaeEnabled() != FALSE) {
  1361. pteContents = *(PULONGLONG)PointerPte;
  1362. } else {
  1363. pteContents = *(PULONG)PointerPte;
  1364. }
  1365. if (pteContents == 0) {
  1366. return TRUE;
  1367. } else {
  1368. return FALSE;
  1369. }
  1370. }
  1371. VOID
  1372. __inline
  1373. HalpFreePte(
  1374. IN PHARDWARE_PTE PointerPte
  1375. )
  1376. /*++
  1377. Routine Description:
  1378. This routine sets a PTE to the free state. It does this by setting the
  1379. entire PTE to zero.
  1380. Arguments:
  1381. PointerPte - Pointer to the PTE to free.
  1382. Return Value:
  1383. None.
  1384. --*/
  1385. {
  1386. if (HalPaeEnabled() != FALSE) {
  1387. *((PULONGLONG)PointerPte) = 0;
  1388. } else {
  1389. *((PULONG)PointerPte) = 0;
  1390. }
  1391. }
  1392. PHARDWARE_PTE
  1393. __inline
  1394. MiGetPteAddress(
  1395. IN PVOID Va
  1396. )
  1397. /*++
  1398. Routine Description:
  1399. Given a virtual address, this routine returns a pointer to the mapping PTE.
  1400. Arguments:
  1401. Va - Virtual Address for which a PTE pointer is desired.
  1402. Return Value:
  1403. None.
  1404. --*/
  1405. {
  1406. PHARDWARE_PTE pointerPte;
  1407. if (HalPaeEnabled() != FALSE) {
  1408. pointerPte = (PHARDWARE_PTE)MiGetPteAddressPae( Va );
  1409. } else {
  1410. pointerPte = MiGetPteAddressX86( Va );
  1411. }
  1412. return pointerPte;
  1413. }
  1414. PHARDWARE_PTE
  1415. __inline
  1416. MiGetPdeAddress(
  1417. IN PVOID Va
  1418. )
  1419. /*++
  1420. Routine Description:
  1421. Given a virtual address, this routine returns a pointer to the mapping PDE.
  1422. Arguments:
  1423. Va - Virtual Address for which a PDE pointer is desired.
  1424. Return Value:
  1425. None.
  1426. --*/
  1427. {
  1428. PHARDWARE_PTE pointerPte;
  1429. if (HalPaeEnabled() != FALSE) {
  1430. pointerPte = (PHARDWARE_PTE)MiGetPdeAddressPae( Va );
  1431. } else {
  1432. pointerPte = MiGetPdeAddressX86( Va );
  1433. }
  1434. return pointerPte;
  1435. }
  1436. ULONG
  1437. __inline
  1438. MiGetPteIndex(
  1439. IN PVOID Va
  1440. )
  1441. /*++
  1442. Routine Description:
  1443. Given a virtual address, this routine returns the index of the mapping
  1444. PTE within its page table.
  1445. Arguments:
  1446. Va - Virtual Address for which the PTE index is desired.
  1447. Return Value:
  1448. None.
  1449. --*/
  1450. {
  1451. ULONG_PTR index;
  1452. if (HalPaeEnabled() != FALSE) {
  1453. index = MiGetPteIndexPae( Va );
  1454. } else {
  1455. index = MiGetPteIndexX86( Va );
  1456. }
  1457. return (ULONG)index;
  1458. }
  1459. ULONG
  1460. __inline
  1461. MiGetPdiShift(
  1462. VOID
  1463. )
  1464. /*++
  1465. Routine Description:
  1466. Returns the number of bits that an address should be shifted right in order
  1467. to right-justify the portion of the address mapped by a page directory
  1468. entry.
  1469. Arguments:
  1470. None.
  1471. Return Value:
  1472. The number of bits to shift right.
  1473. --*/
  1474. {
  1475. ULONG shift;
  1476. if (HalPaeEnabled() != FALSE) {
  1477. shift = PDI_SHIFT_X86PAE;
  1478. } else {
  1479. shift = PDI_SHIFT_X86;
  1480. }
  1481. return shift;
  1482. }
  1483. //
  1484. // ACPI specific stuff
  1485. //
  1486. NTSTATUS
  1487. HalpSetupAcpiPhase0(
  1488. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  1489. );
  1490. NTSTATUS
  1491. HalpAcpiFindRsdtPhase0(
  1492. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  1493. );
  1494. VOID
  1495. HaliHaltSystem(
  1496. VOID
  1497. );
  1498. VOID
  1499. HalpCheckPowerButton(
  1500. VOID
  1501. );
  1502. VOID
  1503. HalpRegisterHibernate(
  1504. VOID
  1505. );
  1506. VOID
  1507. FASTCALL
  1508. HalProcessorThrottle (
  1509. IN UCHAR Throttle
  1510. );
  1511. VOID
  1512. HalpSaveInterruptControllerState(
  1513. VOID
  1514. );
  1515. VOID
  1516. HalpSaveDmaControllerState(
  1517. VOID
  1518. );
  1519. VOID
  1520. HalpSaveTimerState(
  1521. VOID
  1522. );
  1523. VOID
  1524. HalpRestoreInterruptControllerState(
  1525. VOID
  1526. );
  1527. VOID
  1528. HalpSetInterruptControllerWakeupState(
  1529. ULONG Context
  1530. );
  1531. VOID
  1532. HalpRestorePicEdgeLevelRegister(
  1533. VOID
  1534. );
  1535. VOID
  1536. HalpSetAcpiEdgeLevelRegister(
  1537. VOID
  1538. );
  1539. VOID
  1540. HalpRestoreDmaControllerState(
  1541. VOID
  1542. );
  1543. VOID
  1544. HalpRestoreTimerState(
  1545. VOID
  1546. );
  1547. NTSTATUS
  1548. HalacpiGetInterruptTranslator(
  1549. IN INTERFACE_TYPE ParentInterfaceType,
  1550. IN ULONG ParentBusNumber,
  1551. IN INTERFACE_TYPE BridgeInterfaceType,
  1552. IN USHORT Size,
  1553. IN USHORT Version,
  1554. OUT PTRANSLATOR_INTERFACE Translator,
  1555. OUT PULONG BridgeBusNumber
  1556. );
  1557. VOID
  1558. HalpInitNonBusHandler (
  1559. VOID
  1560. );
  1561. VOID
  1562. HalpMapNvsArea(
  1563. VOID
  1564. );
  1565. VOID
  1566. HalpPreserveNvsArea(
  1567. VOID
  1568. );
  1569. VOID
  1570. HalpRestoreNvsArea(
  1571. VOID
  1572. );
  1573. VOID
  1574. HalpFreeNvsBuffers(
  1575. VOID
  1576. );
  1577. VOID
  1578. HalpPowerStateCallback(
  1579. IN PVOID CallbackContext,
  1580. IN PVOID Argument1,
  1581. IN PVOID Argument2
  1582. );
  1583. NTSTATUS
  1584. HalpBuildResumeStructures(
  1585. VOID
  1586. );
  1587. NTSTATUS
  1588. HalpFreeResumeStructures(
  1589. VOID
  1590. );
  1591. typedef struct {
  1592. UCHAR MasterMask;
  1593. UCHAR SlaveMask;
  1594. UCHAR MasterEdgeLevelControl;
  1595. UCHAR SlaveEdgeLevelControl;
  1596. } PIC_CONTEXT, *PPIC_CONTEXT;
  1597. #define EISA_DMA_CHANNELS 8
  1598. typedef struct {
  1599. UCHAR Dma1ExtendedModePort;
  1600. UCHAR Dma2ExtendedModePort;
  1601. DMA1_CONTROL Dma1Control;
  1602. DMA2_CONTROL Dma2Control;
  1603. } DMA_CONTEXT, *PDMA_CONTEXT;
  1604. typedef struct {
  1605. UCHAR nothing;
  1606. } TIMER_CONTEXT, *PTIMER_CONTEXT;
  1607. typedef struct {
  1608. PIC_CONTEXT PicState;
  1609. DMA_CONTEXT DmaState;
  1610. } MOTHERBOARD_CONTEXT, *PMOTHERBOARD_CONTEXT;
  1611. typedef struct {
  1612. UCHAR ChannelMode;
  1613. UCHAR ChannelExtendedMode;
  1614. UCHAR ChannelMask;
  1615. BOOLEAN ChannelProgrammed; // Adapter created, mode set
  1616. #if DBG
  1617. BOOLEAN ChannelBusy;
  1618. #endif
  1619. } DMA_CHANNEL_CONTEXT;
  1620. extern MOTHERBOARD_CONTEXT HalpMotherboardState;
  1621. extern PVOID HalpSleepPageLock;
  1622. extern PVOID HalpSleepPage16Lock;
  1623. extern DMA_CHANNEL_CONTEXT HalpDmaChannelState[];
  1624. ULONG
  1625. HalpcGetCmosDataByType(
  1626. IN CMOS_DEVICE_TYPE CmosType,
  1627. IN ULONG SourceAddress,
  1628. IN PUCHAR DataBuffer,
  1629. IN ULONG ByteCount
  1630. );
  1631. ULONG
  1632. HalpcSetCmosDataByType(
  1633. IN CMOS_DEVICE_TYPE CmosType,
  1634. IN ULONG SourceAddress,
  1635. IN PUCHAR DataBuffer,
  1636. IN ULONG ByteCount
  1637. );
  1638. NTSTATUS
  1639. HalpOpenRegistryKey(
  1640. OUT PHANDLE Handle,
  1641. IN HANDLE BaseHandle OPTIONAL,
  1642. IN PUNICODE_STRING KeyName,
  1643. IN ACCESS_MASK DesiredAccess,
  1644. IN BOOLEAN Create
  1645. );
  1646. #ifdef WANT_IRQ_ROUTING
  1647. NTSTATUS
  1648. HalpInitIrqArbiter (
  1649. IN PDEVICE_OBJECT DeviceObject
  1650. );
  1651. NTSTATUS
  1652. HalpFillInIrqArbiter (
  1653. IN PDEVICE_OBJECT HalFdo,
  1654. IN LPCGUID InterfaceType,
  1655. IN USHORT Version,
  1656. IN PVOID InterfaceSpecificData,
  1657. IN ULONG InterfaceBufferSize,
  1658. IN OUT PINTERFACE Interface,
  1659. IN OUT PULONG Length
  1660. );
  1661. VOID
  1662. HalpIrqArbiterInterfaceReference(
  1663. IN PVOID Context
  1664. );
  1665. VOID
  1666. HalpIrqArbiterInterfaceDereference(
  1667. IN PVOID Context
  1668. );
  1669. #endif
  1670. //
  1671. // PnPBIOS specific stuff
  1672. //
  1673. VOID
  1674. HalpMarkChipsetDecode(
  1675. BOOLEAN FullDecodeChipset
  1676. );
  1677. ULONG
  1678. HalpPhase0SetPciDataByOffset (
  1679. ULONG BusNumber,
  1680. ULONG SlotNumber,
  1681. PVOID Buffer,
  1682. ULONG Offset,
  1683. ULONG Length
  1684. );
  1685. ULONG
  1686. HalpPhase0GetPciDataByOffset (
  1687. ULONG BusNumber,
  1688. ULONG SlotNumber,
  1689. PVOID Buffer,
  1690. ULONG Offset,
  1691. ULONG Length
  1692. );
  1693. NTSTATUS
  1694. HalpSetupPciDeviceForDebugging(
  1695. IN PLOADER_PARAMETER_BLOCK LoaderBlock, OPTIONAL
  1696. IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
  1697. );
  1698. NTSTATUS
  1699. HalpReleasePciDeviceForDebugging(
  1700. IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
  1701. );
  1702. VOID
  1703. HalpRegisterKdSupportFunctions(
  1704. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  1705. );
  1706. VOID
  1707. HalpRegisterPciDebuggingDeviceInfo(
  1708. VOID
  1709. );
  1710. #endif // _HALP_H_