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.

1121 lines
32 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. ixusage.c
  5. Abstract:
  6. Author:
  7. Ken Reneris (kenr)
  8. Environment:
  9. Kernel mode only.
  10. Revision History:
  11. --*/
  12. #include "halp.h"
  13. #include "kdcom.h"
  14. #include "acpitabl.h"
  15. #define KEY_VALUE_BUFFER_SIZE 1024
  16. //
  17. // Array to remember hal's IDT usage
  18. //
  19. #ifdef ALLOC_DATA_PRAGMA
  20. #pragma data_seg("INITCONST") //Yes, this says INITCONST, but that is fine.
  21. #endif
  22. //
  23. // IDT vector usage info
  24. //
  25. IDTUsage HalpIDTUsage[MAXIMUM_IDTVECTOR+1] = {0};
  26. #ifdef ALLOC_DATA_PRAGMA
  27. #pragma data_seg()
  28. #endif
  29. //
  30. // IDT vector usage info
  31. //
  32. IDTUsageFlags HalpIDTUsageFlags[MAXIMUM_IDTVECTOR+1] = {0};
  33. extern WCHAR HalpSzSystem[];
  34. extern WCHAR HalpSzSerialNumber[];
  35. extern ADDRESS_USAGE HalpDetectedROM;
  36. extern ULONG HalDisableFirmwareMapper;
  37. KAFFINITY HalpActiveProcessors;
  38. PUCHAR KdComPortInUse = NULL;
  39. ADDRESS_USAGE HalpComIoSpace = {
  40. NULL, CmResourceTypePort, DeviceUsage,
  41. {
  42. 0x2F8, 0x8, // Default is 2F8 for COM2. This will be changed.
  43. 0, 0
  44. }
  45. };
  46. BOOLEAN HalpGetInfoFromACPI = FALSE;
  47. USHORT HalpComPortIrqMapping[5][2] = {
  48. {COM1_PORT, 4},
  49. {COM2_PORT, 3},
  50. {COM3_PORT, 4},
  51. {COM4_PORT, 3},
  52. {0,0}
  53. };
  54. VOID
  55. HalpGetResourceSortValue (
  56. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc,
  57. OUT PULONG sortscale,
  58. OUT PLARGE_INTEGER sortvalue
  59. );
  60. VOID
  61. HalpReportSerialNumber (
  62. VOID
  63. );
  64. VOID
  65. HalpMarkAcpiHal(
  66. VOID
  67. );
  68. #ifndef ACPI_HAL
  69. VOID
  70. HalpInheritROMBlocks (
  71. VOID
  72. );
  73. VOID
  74. HalpAddROMRanges (
  75. VOID
  76. );
  77. #endif
  78. #ifdef ALLOC_PRAGMA
  79. #pragma alloc_text(INIT,HalpEnableInterruptHandler)
  80. #pragma alloc_text(INIT,HalpRegisterVector)
  81. #pragma alloc_text(INIT,HalpGetResourceSortValue)
  82. #pragma alloc_text(INIT,HalpReportResourceUsage)
  83. #pragma alloc_text(INIT,HalpReportSerialNumber)
  84. #pragma alloc_text(PAGE, HalpMarkAcpiHal)
  85. #ifndef ACPI_HAL
  86. #pragma alloc_text(INIT,HalpInheritROMBlocks)
  87. #pragma alloc_text(INIT,HalpAddROMRanges)
  88. #endif
  89. #endif
  90. #if !defined(_WIN64)
  91. NTSTATUS
  92. HalpEnableInterruptHandler (
  93. IN UCHAR ReportFlags,
  94. IN ULONG BusInterruptVector,
  95. IN ULONG SystemInterruptVector,
  96. IN KIRQL SystemIrql,
  97. IN PHAL_INTERRUPT_SERVICE_ROUTINE HalInterruptServiceRoutine,
  98. IN KINTERRUPT_MODE InterruptMode
  99. )
  100. /*++
  101. Routine Description:
  102. This function connects & registers an IDT vectors usage by the HAL.
  103. Arguments:
  104. Return Value:
  105. --*/
  106. {
  107. #ifndef ACPI_HAL
  108. //
  109. // Remember which vector the hal is connecting so it can be reported
  110. // later on
  111. //
  112. // If this is an ACPI HAL, the vectors will be claimed by the BIOS.
  113. // This is done for Win98 compatibility.
  114. //
  115. HalpRegisterVector (ReportFlags, BusInterruptVector, SystemInterruptVector, SystemIrql);
  116. #endif
  117. //
  118. // Connect the IDT and enable the vector now
  119. //
  120. KiSetHandlerAddressToIDT(SystemInterruptVector, HalInterruptServiceRoutine);
  121. HalEnableSystemInterrupt(SystemInterruptVector, SystemIrql, InterruptMode);
  122. return STATUS_SUCCESS;
  123. }
  124. #endif
  125. VOID
  126. HalpRegisterVector (
  127. IN UCHAR ReportFlags,
  128. IN ULONG BusInterruptVector,
  129. IN ULONG SystemInterruptVector,
  130. IN KIRQL SystemIrql
  131. )
  132. /*++
  133. Routine Description:
  134. This registers an IDT vectors usage by the HAL.
  135. Arguments:
  136. Return Value:
  137. --*/
  138. {
  139. #if DBG
  140. // There are only 0ff IDT entries...
  141. ASSERT (SystemInterruptVector <= MAXIMUM_IDTVECTOR &&
  142. BusInterruptVector <= MAXIMUM_IDTVECTOR);
  143. #endif
  144. //
  145. // Remember which vector the hal is connecting so it can be reported
  146. // later on
  147. //
  148. HalpIDTUsageFlags[SystemInterruptVector].Flags = ReportFlags;
  149. HalpIDTUsage[SystemInterruptVector].Irql = SystemIrql;
  150. HalpIDTUsage[SystemInterruptVector].BusReleativeVector = (UCHAR) BusInterruptVector;
  151. }
  152. VOID
  153. HalpGetResourceSortValue (
  154. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc,
  155. OUT PULONG sortscale,
  156. OUT PLARGE_INTEGER sortvalue
  157. )
  158. /*++
  159. Routine Description:
  160. Used by HalpReportResourceUsage in order to properly sort
  161. partial_resource_descriptors.
  162. Arguments:
  163. pRCurLoc - resource descriptor
  164. Return Value:
  165. sortscale - scaling of resource descriptor for sorting
  166. sortvalue - value to sort on
  167. --*/
  168. {
  169. switch (pRCurLoc->Type) {
  170. case CmResourceTypeInterrupt:
  171. *sortscale = 0;
  172. *sortvalue = RtlConvertUlongToLargeInteger(
  173. pRCurLoc->u.Interrupt.Level );
  174. break;
  175. case CmResourceTypePort:
  176. *sortscale = 1;
  177. *sortvalue = pRCurLoc->u.Port.Start;
  178. break;
  179. case CmResourceTypeMemory:
  180. *sortscale = 2;
  181. *sortvalue = pRCurLoc->u.Memory.Start;
  182. break;
  183. default:
  184. *sortscale = 4;
  185. *sortvalue = RtlConvertUlongToLargeInteger (0);
  186. break;
  187. }
  188. }
  189. #ifndef ACPI_HAL
  190. VOID
  191. HalpInheritROMBlocks (void)
  192. {
  193. PBUS_HANDLER Bus;
  194. PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor;
  195. PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
  196. PKEY_VALUE_FULL_INFORMATION KeyValueBuffer;
  197. PCM_ROM_BLOCK BiosBlock;
  198. OBJECT_ATTRIBUTES ObjectAttributes;
  199. UNICODE_STRING SectionName;
  200. UNICODE_STRING WorkString;
  201. HANDLE RegistryHandle;
  202. NTSTATUS Status;
  203. LARGE_INTEGER ViewBase;
  204. PVOID BaseAddress;
  205. PVOID destination;
  206. ULONG ViewSize;
  207. ULONG ResultLength;
  208. ULONG Index;
  209. ULONG LastMappedAddress;
  210. Bus = HaliHandlerForBus (PCIBus, 0);
  211. if (!Bus) {
  212. //
  213. //No root bus????
  214. //
  215. return;
  216. }
  217. //
  218. // Set up and open KeyPath
  219. //
  220. RtlInitUnicodeString(&SectionName,HalpSzSystem);
  221. InitializeObjectAttributes(
  222. &ObjectAttributes,
  223. &SectionName,
  224. OBJ_CASE_INSENSITIVE,
  225. (HANDLE)NULL,
  226. NULL
  227. );
  228. Status = ZwOpenKey(
  229. &RegistryHandle,
  230. KEY_READ,
  231. &ObjectAttributes
  232. );
  233. if (!NT_SUCCESS(Status)) {
  234. return;
  235. }
  236. //
  237. // Allocate space for the data
  238. //
  239. KeyValueBuffer = ExAllocatePoolWithTag(
  240. PagedPool,
  241. KEY_VALUE_BUFFER_SIZE,
  242. ' MDV'
  243. );
  244. if (KeyValueBuffer == NULL) {
  245. ZwClose(RegistryHandle);
  246. return ;
  247. }
  248. //
  249. // Get the data for the rom information
  250. //
  251. RtlInitUnicodeString(
  252. &WorkString,
  253. L"Configuration Data"
  254. );
  255. Status = ZwQueryValueKey(
  256. RegistryHandle,
  257. &WorkString,
  258. KeyValueFullInformation,
  259. KeyValueBuffer,
  260. KEY_VALUE_BUFFER_SIZE,
  261. &ResultLength
  262. );
  263. if (!NT_SUCCESS(Status)) {
  264. ZwClose(RegistryHandle);
  265. ExFreePool(KeyValueBuffer);
  266. return ;
  267. }
  268. //
  269. //At this point, we have the data, so go ahead and
  270. //add in all of the range, except VGA, we can
  271. //assume we're not going to want to drop another card there
  272. //
  273. HalpAddRange( &Bus->BusAddresses->Memory,
  274. 0,
  275. 0,
  276. 0xC0000,
  277. 0xFFFFF
  278. );
  279. ResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)
  280. ((PUCHAR) KeyValueBuffer + KeyValueBuffer->DataOffset);
  281. if ((KeyValueBuffer->DataLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) ||
  282. (ResourceDescriptor->PartialResourceList.Count < 2)
  283. ) {
  284. ZwClose(RegistryHandle);
  285. ExFreePool(KeyValueBuffer);
  286. // No rom blocks.
  287. return;
  288. }
  289. PartialResourceDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
  290. ((PUCHAR)ResourceDescriptor +
  291. sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
  292. ResourceDescriptor->PartialResourceList.PartialDescriptors[0]
  293. .u.DeviceSpecificData.DataSize);
  294. if (KeyValueBuffer->DataLength < ((PUCHAR)PartialResourceDescriptor -
  295. (PUCHAR)ResourceDescriptor + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)
  296. + sizeof(CM_ROM_BLOCK))
  297. ) {
  298. ZwClose(RegistryHandle);
  299. ExFreePool(KeyValueBuffer);
  300. return;// STATUS_ILL_FORMED_SERVICE_ENTRY;
  301. }
  302. BiosBlock = (PCM_ROM_BLOCK)((PUCHAR)PartialResourceDescriptor +
  303. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  304. Index = PartialResourceDescriptor->u.DeviceSpecificData.DataSize /
  305. sizeof(CM_ROM_BLOCK);
  306. //
  307. // N.B. Rom blocks begin on 2K (not necessarily page) boundaries
  308. // They end on 512 byte boundaries. This means that we have
  309. // to keep track of the last page mapped, and round the next
  310. // Rom block up to the next page boundary if necessary.
  311. //
  312. LastMappedAddress = 0xC0000;
  313. while (Index) {
  314. #if 0
  315. DbgPrint(
  316. "Bios Block, PhysAddr = %lx, size = %lx\n",
  317. BiosBlock->Address,
  318. BiosBlock->Size
  319. );
  320. #endif
  321. if ((Index > 1) &&
  322. ((BiosBlock->Address + BiosBlock->Size) == BiosBlock[1].Address)
  323. ) {
  324. //
  325. // Coalesce adjacent blocks
  326. //
  327. BiosBlock[1].Address = BiosBlock[0].Address;
  328. BiosBlock[1].Size += BiosBlock[0].Size;
  329. Index--;
  330. BiosBlock++;
  331. continue;
  332. }
  333. BaseAddress = (PVOID)(BiosBlock->Address);
  334. ViewSize = BiosBlock->Size;
  335. if ((ULONG)BaseAddress < LastMappedAddress) {
  336. if (ViewSize > (LastMappedAddress - (ULONG)BaseAddress)) {
  337. ViewSize = ViewSize - (LastMappedAddress - (ULONG)BaseAddress);
  338. BaseAddress = (PVOID)LastMappedAddress;
  339. } else {
  340. ViewSize = 0;
  341. }
  342. }
  343. ViewBase.LowPart = (ULONG)BaseAddress;
  344. if (ViewSize > 0) {
  345. HalpRemoveRange ( &Bus->BusAddresses->Memory,
  346. ViewBase.LowPart,
  347. ViewSize);
  348. LastMappedAddress = (ULONG)BaseAddress + ViewSize;
  349. }
  350. Index--;
  351. BiosBlock++;
  352. }
  353. //
  354. // Free up the handles
  355. //
  356. ZwClose(RegistryHandle);
  357. ExFreePool(KeyValueBuffer);
  358. }
  359. VOID
  360. HalpAddROMRanges (
  361. VOID
  362. )
  363. {
  364. PCM_FULL_RESOURCE_DESCRIPTOR resourceDescriptor;
  365. PCM_PARTIAL_RESOURCE_DESCRIPTOR partialResourceDescriptor;
  366. PKEY_VALUE_FULL_INFORMATION keyValueBuffer;
  367. PCM_ROM_BLOCK biosBlock;
  368. ULONG resultLength;
  369. OBJECT_ATTRIBUTES objectAttributes;
  370. UNICODE_STRING sectionName;
  371. UNICODE_STRING workString;
  372. HANDLE registryHandle;
  373. NTSTATUS status;
  374. LARGE_INTEGER viewBase;
  375. PVOID baseAddress;
  376. ULONG viewSize;
  377. ULONG index;
  378. ULONG element;
  379. ULONG lastMappedAddress;
  380. ADDRESS_USAGE *addrUsage;
  381. RtlInitUnicodeString(&sectionName, HalpSzSystem);
  382. InitializeObjectAttributes( &objectAttributes,
  383. &sectionName,
  384. OBJ_CASE_INSENSITIVE,
  385. (HANDLE)NULL,
  386. NULL);
  387. status = ZwOpenKey( &registryHandle,
  388. KEY_READ,
  389. &objectAttributes);
  390. if (NT_SUCCESS(status)) {
  391. //
  392. // Allocate space for the data
  393. //
  394. keyValueBuffer = ExAllocatePoolWithTag( PagedPool,
  395. KEY_VALUE_BUFFER_SIZE,
  396. ' MDV');
  397. if (keyValueBuffer) {
  398. //
  399. // Get the data for the rom information
  400. //
  401. RtlInitUnicodeString( &workString,
  402. L"Configuration Data");
  403. status = ZwQueryValueKey( registryHandle,
  404. &workString,
  405. KeyValueFullInformation,
  406. keyValueBuffer,
  407. KEY_VALUE_BUFFER_SIZE,
  408. &resultLength);
  409. if (NT_SUCCESS(status)) {
  410. resourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PUCHAR)keyValueBuffer + keyValueBuffer->DataOffset);
  411. if ( keyValueBuffer->DataLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR) &&
  412. resourceDescriptor->PartialResourceList.Count >= 2) {
  413. partialResourceDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)((PUCHAR)resourceDescriptor +
  414. sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
  415. resourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize);
  416. if ( keyValueBuffer->DataLength >=
  417. ((PUCHAR)partialResourceDescriptor - (PUCHAR)resourceDescriptor + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + sizeof(CM_ROM_BLOCK))) {
  418. addrUsage = &HalpDetectedROM;
  419. //
  420. // N.B. Rom blocks begin on 2K (not necessarily page) boundaries
  421. // They end on 512 byte boundaries. This means that we have
  422. // to keep track of the last page mapped, and round the next
  423. // Rom block up to the next page boundary if necessary.
  424. //
  425. biosBlock = (PCM_ROM_BLOCK)((PUCHAR)partialResourceDescriptor + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  426. lastMappedAddress = 0xC0000;
  427. for ( index = partialResourceDescriptor->u.DeviceSpecificData.DataSize / sizeof(CM_ROM_BLOCK), element = 0;
  428. index;
  429. index--, biosBlock++) {
  430. //
  431. // Coalesce adjacent blocks
  432. //
  433. if ( index > 1 && (biosBlock->Address + biosBlock->Size) == biosBlock[1].Address) {
  434. biosBlock[1].Address = biosBlock[0].Address;
  435. biosBlock[1].Size += biosBlock[0].Size;
  436. continue;
  437. }
  438. baseAddress = (PVOID)(biosBlock->Address);
  439. viewSize = biosBlock->Size;
  440. if ((ULONG)baseAddress < lastMappedAddress) {
  441. if (viewSize > (lastMappedAddress - (ULONG)baseAddress)) {
  442. viewSize = viewSize - (lastMappedAddress - (ULONG)baseAddress);
  443. baseAddress = (PVOID)lastMappedAddress;
  444. } else {
  445. viewSize = 0;
  446. }
  447. }
  448. viewBase.LowPart = (ULONG)baseAddress;
  449. if (viewSize > 0) {
  450. addrUsage->Element[element].Start = viewBase.LowPart;
  451. addrUsage->Element[element].Length = viewSize;
  452. element++;
  453. lastMappedAddress = (ULONG)baseAddress + viewSize;
  454. }
  455. }
  456. //
  457. // Register address usage if we found at least one ROM block.
  458. //
  459. if (element) {
  460. addrUsage->Element[element].Start = 0;
  461. addrUsage->Element[element].Length = 0;
  462. HalpRegisterAddressUsage(addrUsage);
  463. }
  464. }
  465. }
  466. }
  467. ExFreePool(keyValueBuffer);
  468. }
  469. ZwClose(registryHandle);
  470. }
  471. }
  472. #endif
  473. VOID
  474. HalpReportResourceUsage (
  475. IN PUNICODE_STRING HalName,
  476. IN INTERFACE_TYPE DeviceInterfaceToUse
  477. )
  478. /*++
  479. Routine Description:
  480. Arguments:
  481. Return Value:
  482. --*/
  483. {
  484. PCM_RESOURCE_LIST RawResourceList, TranslatedResourceList;
  485. PCM_FULL_RESOURCE_DESCRIPTOR pRFullDesc, pTFullDesc;
  486. PCM_PARTIAL_RESOURCE_LIST pRPartList, pTPartList;
  487. PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, pTCurLoc;
  488. PCM_PARTIAL_RESOURCE_DESCRIPTOR pRSortLoc, pTSortLoc;
  489. CM_PARTIAL_RESOURCE_DESCRIPTOR RPartialDesc, TPartialDesc;
  490. ULONG i, j, k, ListSize, Count;
  491. ULONG curscale, sortscale;
  492. UCHAR pass, reporton;
  493. INTERFACE_TYPE interfacetype;
  494. ULONG CurrentIDT, CurrentElement;
  495. ADDRESS_USAGE *CurrentAddress;
  496. LARGE_INTEGER curvalue, sortvalue;
  497. #ifdef ACPI_HAL
  498. extern PDEBUG_PORT_TABLE HalpDebugPortTable;
  499. #endif
  500. //
  501. // Claim the debugger com port resource if it is in use
  502. //
  503. if (KdComPortInUse != NULL) {
  504. HalpComIoSpace.Element[0].Start = (ULONG)(ULONG_PTR)KdComPortInUse;
  505. HalpRegisterAddressUsage(&HalpComIoSpace);
  506. #ifdef ACPI_HAL
  507. if (HalpDebugPortTable) {
  508. if (HalpDebugPortTable->BaseAddress.AddressSpaceID == 1) {
  509. HalpGetInfoFromACPI = TRUE;
  510. }
  511. }
  512. #endif
  513. //
  514. // The debugger does not use any interrupts. However for consistent
  515. // behaviour between a machine with and without a debugger, we claim
  516. // an interrupt for the debugger if the debugger port address is one
  517. // for COM1-4.
  518. //
  519. if (!HalpGetInfoFromACPI) {
  520. for (i = 0; HalpComPortIrqMapping[i][0]; i++) {
  521. if ((PUCHAR)HalpComPortIrqMapping[i][0] == KdComPortInUse) {
  522. HalpRegisterVector( DeviceUsage | InterruptLatched,
  523. HalpComPortIrqMapping[i][1],
  524. HalpComPortIrqMapping[i][1] +
  525. PRIMARY_VECTOR_BASE,
  526. HIGH_LEVEL);
  527. break;
  528. }
  529. }
  530. }
  531. }
  532. #ifndef ACPI_HAL // ACPI HALs don't deal with address maps
  533. HalpInheritROMBlocks();
  534. HalpAddROMRanges();
  535. #endif
  536. //
  537. // Allocate some space to build the resource structure
  538. //
  539. RawResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(
  540. NonPagedPool,
  541. PAGE_SIZE*2,
  542. HAL_POOL_TAG);
  543. TranslatedResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(
  544. NonPagedPool,
  545. PAGE_SIZE*2,
  546. HAL_POOL_TAG);
  547. if (!RawResourceList || !TranslatedResourceList) {
  548. //
  549. // These allocations were critical.
  550. //
  551. KeBugCheckEx(HAL_MEMORY_ALLOCATION,
  552. PAGE_SIZE*4,
  553. 1,
  554. (ULONG_PTR)__FILE__,
  555. __LINE__
  556. );
  557. }
  558. // This functions assumes unset fields are zero
  559. RtlZeroMemory(RawResourceList, PAGE_SIZE*2);
  560. RtlZeroMemory(TranslatedResourceList, PAGE_SIZE*2);
  561. //
  562. // Initialize the lists
  563. //
  564. RawResourceList->List[0].InterfaceType = (INTERFACE_TYPE) -1;
  565. pRFullDesc = RawResourceList->List;
  566. pRCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) RawResourceList->List;
  567. pTCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) TranslatedResourceList->List;
  568. //
  569. // Make sure all vectors 00-2f are reserved
  570. // 00-1E reserved by Intel
  571. // 1F reserved by Intel for APIC (apc priority level)
  572. // 20-2e reserved by Microsoft
  573. // 2f reserved by Microsoft for APIC (dpc priority level)
  574. //
  575. for(i=0; i < PRIMARY_VECTOR_BASE; i++) {
  576. if (!(HalpIDTUsageFlags[i].Flags & IDTOwned)) {
  577. HalpIDTUsageFlags[i].Flags = InternalUsage;
  578. HalpIDTUsage[i].BusReleativeVector = (UCHAR) i;
  579. }
  580. }
  581. for(pass=0; pass < 2; pass++) {
  582. if (pass == 0) {
  583. //
  584. // First pass - build resource lists for resources reported
  585. // reported against device usage.
  586. //
  587. reporton = DeviceUsage & ~IDTOwned;
  588. interfacetype = DeviceInterfaceToUse;
  589. } else {
  590. //
  591. // Second pass = build reousce lists for resources reported
  592. // as internal usage.
  593. //
  594. reporton = InternalUsage & ~IDTOwned;
  595. interfacetype = Internal;
  596. }
  597. CurrentIDT = 0;
  598. CurrentElement = 0;
  599. CurrentAddress = HalpAddressUsageList;
  600. for (; ;) {
  601. if (CurrentIDT <= MAXIMUM_IDTVECTOR) {
  602. //
  603. // Check to see if CurrentIDT needs to be reported
  604. //
  605. if (!(HalpIDTUsageFlags[CurrentIDT].Flags & reporton)) {
  606. // Don't report on this one
  607. CurrentIDT++;
  608. continue;
  609. }
  610. //
  611. // Report CurrentIDT resource
  612. //
  613. RPartialDesc.Type = CmResourceTypeInterrupt;
  614. RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
  615. RPartialDesc.Flags =
  616. HalpIDTUsageFlags[CurrentIDT].Flags & InterruptLatched ?
  617. CM_RESOURCE_INTERRUPT_LATCHED :
  618. CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
  619. RPartialDesc.u.Interrupt.Vector = HalpIDTUsage[CurrentIDT].BusReleativeVector;
  620. RPartialDesc.u.Interrupt.Level = HalpIDTUsage[CurrentIDT].BusReleativeVector;
  621. RPartialDesc.u.Interrupt.Affinity = HalpActiveProcessors;
  622. RtlCopyMemory (&TPartialDesc, &RPartialDesc, sizeof TPartialDesc);
  623. TPartialDesc.u.Interrupt.Vector = CurrentIDT;
  624. TPartialDesc.u.Interrupt.Level = HalpIDTUsage[CurrentIDT].Irql;
  625. CurrentIDT++;
  626. } else {
  627. //
  628. // Check to see if CurrentAddress needs to be reported
  629. //
  630. if (!CurrentAddress) {
  631. break; // No addresses left
  632. }
  633. if (!(CurrentAddress->Flags & reporton)) {
  634. // Don't report on this list
  635. CurrentElement = 0;
  636. CurrentAddress = CurrentAddress->Next;
  637. continue;
  638. }
  639. if (!CurrentAddress->Element[CurrentElement].Length) {
  640. // End of current list, go to next list
  641. CurrentElement = 0;
  642. CurrentAddress = CurrentAddress->Next;
  643. continue;
  644. }
  645. //
  646. // Report CurrentAddress
  647. //
  648. RPartialDesc.Type = (UCHAR) CurrentAddress->Type;
  649. RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
  650. if (RPartialDesc.Type == CmResourceTypePort) {
  651. i = 1; // address space port
  652. RPartialDesc.Flags = CM_RESOURCE_PORT_IO;
  653. if (HalpBusType == MACHINE_TYPE_EISA) {
  654. RPartialDesc.Flags |= CM_RESOURCE_PORT_16_BIT_DECODE;
  655. }
  656. #ifdef ACPI_HAL
  657. RPartialDesc.Flags |= CM_RESOURCE_PORT_16_BIT_DECODE;
  658. #endif
  659. } else {
  660. i = 0; // address space memory
  661. if (CurrentAddress->Flags & RomResource) {
  662. RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_ONLY;
  663. } else {
  664. RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
  665. }
  666. }
  667. // Notice: assuming u.Memory and u.Port have the same layout
  668. RPartialDesc.u.Memory.Start.HighPart = 0;
  669. RPartialDesc.u.Memory.Start.LowPart =
  670. CurrentAddress->Element[CurrentElement].Start;
  671. RPartialDesc.u.Memory.Length =
  672. CurrentAddress->Element[CurrentElement].Length;
  673. // translated address = Raw address
  674. RtlCopyMemory (&TPartialDesc, &RPartialDesc, sizeof TPartialDesc);
  675. HalTranslateBusAddress (
  676. interfacetype, // device bus or internal
  677. 0, // bus number
  678. RPartialDesc.u.Memory.Start, // source address
  679. &i, // address space
  680. &TPartialDesc.u.Memory.Start ); // translated address
  681. if (RPartialDesc.Type == CmResourceTypePort && i == 0) {
  682. TPartialDesc.Flags = CM_RESOURCE_PORT_MEMORY;
  683. }
  684. CurrentElement++;
  685. }
  686. //
  687. // Include the current resource in the HALs list
  688. //
  689. if (pRFullDesc->InterfaceType != interfacetype) {
  690. //
  691. // Interface type changed, add another full section
  692. //
  693. RawResourceList->Count++;
  694. TranslatedResourceList->Count++;
  695. pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc;
  696. pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc;
  697. pRFullDesc->InterfaceType = interfacetype;
  698. pTFullDesc->InterfaceType = interfacetype;
  699. pRPartList = &pRFullDesc->PartialResourceList;
  700. pTPartList = &pTFullDesc->PartialResourceList;
  701. //
  702. // Bump current location pointers up
  703. //
  704. pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
  705. pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
  706. }
  707. pRPartList->Count++;
  708. pTPartList->Count++;
  709. RtlCopyMemory (pRCurLoc, &RPartialDesc, sizeof RPartialDesc);
  710. RtlCopyMemory (pTCurLoc, &TPartialDesc, sizeof TPartialDesc);
  711. pRCurLoc++;
  712. pTCurLoc++;
  713. }
  714. }
  715. ListSize = (ULONG) ( ((PUCHAR) pRCurLoc) - ((PUCHAR) RawResourceList) );
  716. //
  717. // The HAL's resource usage structures have been built
  718. // Sort the partial lists based on the Raw resource values
  719. //
  720. pRFullDesc = RawResourceList->List;
  721. pTFullDesc = TranslatedResourceList->List;
  722. for (i=0; i < RawResourceList->Count; i++) {
  723. pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
  724. pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
  725. Count = pRFullDesc->PartialResourceList.Count;
  726. for (j=0; j < Count; j++) {
  727. HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue);
  728. pRSortLoc = pRCurLoc;
  729. pTSortLoc = pTCurLoc;
  730. for (k=j; k < Count; k++) {
  731. HalpGetResourceSortValue (pRSortLoc, &sortscale, &sortvalue);
  732. if (sortscale < curscale ||
  733. (sortscale == curscale &&
  734. RtlLargeIntegerLessThan (sortvalue, curvalue)) ) {
  735. //
  736. // Swap the elements..
  737. //
  738. RtlCopyMemory (&RPartialDesc, pRCurLoc, sizeof RPartialDesc);
  739. RtlCopyMemory (pRCurLoc, pRSortLoc, sizeof RPartialDesc);
  740. RtlCopyMemory (pRSortLoc, &RPartialDesc, sizeof RPartialDesc);
  741. // swap translated descriptor as well
  742. RtlCopyMemory (&TPartialDesc, pTCurLoc, sizeof TPartialDesc);
  743. RtlCopyMemory (pTCurLoc, pTSortLoc, sizeof TPartialDesc);
  744. RtlCopyMemory (pTSortLoc, &TPartialDesc, sizeof TPartialDesc);
  745. // get new curscale & curvalue
  746. HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue);
  747. }
  748. pRSortLoc++;
  749. pTSortLoc++;
  750. }
  751. pRCurLoc++;
  752. pTCurLoc++;
  753. }
  754. pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc;
  755. pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc;
  756. }
  757. HalpMarkAcpiHal();
  758. //
  759. // Inform the IO system of our resources..
  760. //
  761. IoReportHalResourceUsage (
  762. HalName,
  763. RawResourceList,
  764. TranslatedResourceList,
  765. ListSize
  766. );
  767. ExFreePool (RawResourceList);
  768. ExFreePool (TranslatedResourceList);
  769. //
  770. // Add system's serial number
  771. //
  772. HalpReportSerialNumber ();
  773. }
  774. VOID
  775. HalpReportSerialNumber (
  776. VOID
  777. )
  778. {
  779. OBJECT_ATTRIBUTES objectAttributes;
  780. UNICODE_STRING unicodeString;
  781. HANDLE hSystem;
  782. NTSTATUS status;
  783. if (!HalpSerialLen) {
  784. return ;
  785. }
  786. //
  787. // Open HKEY_LOCAL_MACHINE\Hardware\Description\System
  788. //
  789. RtlInitUnicodeString (&unicodeString, HalpSzSystem);
  790. InitializeObjectAttributes (
  791. &objectAttributes,
  792. &unicodeString,
  793. OBJ_CASE_INSENSITIVE,
  794. NULL, // handle
  795. NULL
  796. );
  797. status = ZwOpenKey (&hSystem, KEY_READ | KEY_WRITE, &objectAttributes);
  798. if (NT_SUCCESS(status)) {
  799. //
  800. // Add "Serial Number" as REG_BINARY
  801. //
  802. RtlInitUnicodeString (&unicodeString, HalpSzSerialNumber);
  803. ZwSetValueKey (
  804. hSystem,
  805. &unicodeString,
  806. 0L,
  807. REG_BINARY,
  808. HalpSerialNumber,
  809. HalpSerialLen
  810. );
  811. ZwClose (hSystem);
  812. }
  813. }
  814. VOID
  815. HalpMarkAcpiHal(
  816. VOID
  817. )
  818. /*++
  819. Routine Description:
  820. Arguments:
  821. None.
  822. Return Value:
  823. None.
  824. --*/
  825. {
  826. UNICODE_STRING unicodeString;
  827. HANDLE hCurrentControlSet, handle;
  828. NTSTATUS status;
  829. PAGED_CODE();
  830. //
  831. // Open/create System\CurrentControlSet key.
  832. //
  833. RtlInitUnicodeString(&unicodeString, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
  834. status = HalpOpenRegistryKey (
  835. &hCurrentControlSet,
  836. NULL,
  837. &unicodeString,
  838. KEY_ALL_ACCESS,
  839. FALSE
  840. );
  841. if (!NT_SUCCESS(status)) {
  842. return;
  843. }
  844. //
  845. // Open HKLM\System\CurrentControlSet\Control\Pnp
  846. //
  847. RtlInitUnicodeString(&unicodeString, L"Control\\Pnp");
  848. status = HalpOpenRegistryKey (
  849. &handle,
  850. hCurrentControlSet,
  851. &unicodeString,
  852. KEY_ALL_ACCESS,
  853. TRUE
  854. );
  855. ZwClose(hCurrentControlSet);
  856. if (!NT_SUCCESS(status)) {
  857. return;
  858. }
  859. RtlInitUnicodeString(&unicodeString, L"DisableFirmwareMapper");
  860. ZwSetValueKey(handle,
  861. &unicodeString,
  862. 0,
  863. REG_DWORD,
  864. &HalDisableFirmwareMapper,
  865. sizeof(HalDisableFirmwareMapper)
  866. );
  867. ZwClose(handle);
  868. }