Source code of Windows XP (NT5)
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.

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