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.

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