#define NDEBUG
#include <debug.h>
-static PPCI_IRQ_ROUTING_TABLE
+DBG_DEFAULT_CHANNEL(HWDETECT);
+
+static
+PPCI_IRQ_ROUTING_TABLE
GetPciIrqRoutingTable(VOID)
{
- PPCI_IRQ_ROUTING_TABLE Table;
- PUCHAR Ptr;
- ULONG Sum;
- ULONG i;
+ PPCI_IRQ_ROUTING_TABLE Table;
+ PUCHAR Ptr;
+ ULONG Sum;
+ ULONG i;
- Table = (PPCI_IRQ_ROUTING_TABLE)0xF0000;
- while ((ULONG_PTR)Table < 0x100000)
+ Table = (PPCI_IRQ_ROUTING_TABLE)0xF0000;
+ while ((ULONG_PTR)Table < 0x100000)
{
- if (Table->Signature == 'RIP$')
- {
- DPRINTM(DPRINT_HWDETECT,
- "Found signature\n");
-
- Ptr = (PUCHAR)Table;
- Sum = 0;
- for (i = 0; i < Table->TableSize; i++)
- {
- Sum += Ptr[i];
- }
-
- if ((Sum & 0xFF) != 0)
- {
- DPRINTM(DPRINT_HWDETECT,
- "Invalid routing table\n");
- return NULL;
- }
-
- DPRINTM(DPRINT_HWDETECT,
- "Valid checksum\n");
-
- return Table;
- }
-
- Table = (PPCI_IRQ_ROUTING_TABLE)((ULONG_PTR)Table + 0x10);
+ if (Table->Signature == 'RIP$')
+ {
+ TRACE("Found signature\n");
+
+ if (Table->TableSize < FIELD_OFFSET(PCI_IRQ_ROUTING_TABLE, Slot) ||
+ Table->TableSize % 16 != 0)
+ {
+ ERR("Invalid routing table size (%u) at %p. Continue searching...\n", Table->TableSize, Table);
+ Table = (PPCI_IRQ_ROUTING_TABLE)((ULONG_PTR)Table + 0x10);
+ continue;
+ }
+
+ Ptr = (PUCHAR)Table;
+ Sum = 0;
+ for (i = 0; i < Table->TableSize; i++)
+ {
+ Sum += Ptr[i];
+ }
+
+ if ((Sum & 0xFF) != 0)
+ {
+ ERR("Invalid routing table checksum (%#lx) at %p. Continue searching...\n", Sum & 0xFF, Table);
+ }
+ else
+ {
+ TRACE("Valid checksum\n");
+ return Table;
+ }
+ }
+
+ Table = (PPCI_IRQ_ROUTING_TABLE)((ULONG_PTR)Table + 0x10);
}
- return NULL;
+ ERR("No valid routing table found!\n");
+
+ return NULL;
}
static BOOLEAN
FindPciBios(PPCI_REGISTRY_INFO BusData)
{
- REGS RegsIn;
- REGS RegsOut;
+ REGS RegsIn;
+ REGS RegsOut;
- RegsIn.b.ah = 0xB1; /* Subfunction B1h */
- RegsIn.b.al = 0x01; /* PCI BIOS present */
+ RegsIn.b.ah = 0xB1; /* Subfunction B1h */
+ RegsIn.b.al = 0x01; /* PCI BIOS present */
- Int386(0x1A, &RegsIn, &RegsOut);
+ Int386(0x1A, &RegsIn, &RegsOut);
- if (INT386_SUCCESS(RegsOut) && RegsOut.d.edx == 0x20494350 && RegsOut.b.ah == 0)
+ if (INT386_SUCCESS(RegsOut) &&
+ (RegsOut.d.edx == 0x20494350) &&
+ (RegsOut.b.ah == 0))
{
- DPRINTM(DPRINT_HWDETECT, "Found PCI bios\n");
+ TRACE("Found PCI bios\n");
- DPRINTM(DPRINT_HWDETECT, "AL: %x\n", RegsOut.b.al);
- DPRINTM(DPRINT_HWDETECT, "BH: %x\n", RegsOut.b.bh);
- DPRINTM(DPRINT_HWDETECT, "BL: %x\n", RegsOut.b.bl);
- DPRINTM(DPRINT_HWDETECT, "CL: %x\n", RegsOut.b.cl);
+ TRACE("AL: %x\n", RegsOut.b.al);
+ TRACE("BH: %x\n", RegsOut.b.bh);
+ TRACE("BL: %x\n", RegsOut.b.bl);
+ TRACE("CL: %x\n", RegsOut.b.cl);
- BusData->NoBuses = RegsOut.b.cl + 1;
- BusData->MajorRevision = RegsOut.b.bh;
- BusData->MinorRevision = RegsOut.b.bl;
- BusData->HardwareMechanism = RegsOut.b.al;
+ BusData->NoBuses = RegsOut.b.cl + 1;
+ BusData->MajorRevision = RegsOut.b.bh;
+ BusData->MinorRevision = RegsOut.b.bl;
+ BusData->HardwareMechanism = RegsOut.b.al;
- return TRUE;
+ return TRUE;
}
+ TRACE("No PCI bios found\n");
- DPRINTM(DPRINT_HWDETECT, "No PCI bios found\n");
-
- return FALSE;
+ return FALSE;
}
-static VOID
+static
+VOID
DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey)
{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
- PPCI_IRQ_ROUTING_TABLE Table;
- PCONFIGURATION_COMPONENT_DATA TableKey;
- ULONG Size;
-
- Table = GetPciIrqRoutingTable();
- if (Table != NULL)
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ PPCI_IRQ_ROUTING_TABLE Table;
+ PCONFIGURATION_COMPONENT_DATA TableKey;
+ ULONG Size;
+
+ Table = GetPciIrqRoutingTable();
+ if (Table != NULL)
{
- DPRINTM(DPRINT_HWDETECT, "Table size: %u\n", Table->TableSize);
-
- /* Set 'Configuration Data' value */
- Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
- 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + Table->TableSize;
- PartialResourceList = MmHeapAlloc(Size);
- if (PartialResourceList == NULL)
- {
- DPRINTM(DPRINT_HWDETECT,
- "Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 2;
-
- PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
- PartialDescriptor->Type = CmResourceTypeBusNumber;
- PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
- PartialDescriptor->u.BusNumber.Start = 0;
- PartialDescriptor->u.BusNumber.Length = 1;
-
- PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
- PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
- PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
- PartialDescriptor->u.DeviceSpecificData.DataSize = Table->TableSize;
-
- memcpy(&PartialResourceList->PartialDescriptors[2],
- Table, Table->TableSize);
-
- FldrCreateComponentKey(BusKey,
- PeripheralClass,
- RealModeIrqRoutingTable,
- 0x0,
- 0x0,
- 0xFFFFFFFF,
- "PCI Real-mode IRQ Routing Table",
- PartialResourceList,
- Size,
- &TableKey);
-
- MmHeapFree(PartialResourceList);
+ TRACE("Table size: %u\n", Table->TableSize);
+
+ /* Set 'Configuration Data' value */
+ Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
+ 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + Table->TableSize;
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 2;
+
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+ PartialDescriptor->Type = CmResourceTypeBusNumber;
+ PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ PartialDescriptor->u.BusNumber.Start = 0;
+ PartialDescriptor->u.BusNumber.Length = 1;
+
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
+ PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
+ PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+ PartialDescriptor->u.DeviceSpecificData.DataSize = Table->TableSize;
+
+ memcpy(&PartialResourceList->PartialDescriptors[2],
+ Table,
+ Table->TableSize);
+
+ FldrCreateComponentKey(BusKey,
+ PeripheralClass,
+ RealModeIrqRoutingTable,
+ 0x0,
+ 0x0,
+ 0xFFFFFFFF,
+ "PCI Real-mode IRQ Routing Table",
+ PartialResourceList,
+ Size,
+ &TableKey);
}
}
VOID
DetectPciBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
- PCI_REGISTRY_INFO BusData;
- PCONFIGURATION_COMPONENT_DATA BiosKey;
- ULONG Size;
- PCONFIGURATION_COMPONENT_DATA BusKey;
- ULONG i;
-
- /* Report the PCI BIOS */
- if (FindPciBios(&BusData))
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ PCI_REGISTRY_INFO BusData;
+ PCONFIGURATION_COMPONENT_DATA BiosKey;
+ ULONG Size;
+ PCONFIGURATION_COMPONENT_DATA BusKey;
+ ULONG i;
+
+ /* Report the PCI BIOS */
+ if (FindPciBios(&BusData))
{
- /* Set 'Configuration Data' value */
- Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
- PartialDescriptors);
- PartialResourceList = MmHeapAlloc(Size);
- if (PartialResourceList == NULL)
- {
- DPRINTM(DPRINT_HWDETECT,
- "Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
-
- /* Create new bus key */
- FldrCreateComponentKey(SystemKey,
- AdapterClass,
- MultiFunctionAdapter,
- 0x0,
- 0x0,
- 0xFFFFFFFF,
- "PCI BIOS",
- PartialResourceList,
- Size,
- &BiosKey);
-
- /* Increment bus number */
- (*BusNumber)++;
-
- MmHeapFree(PartialResourceList);
-
- DetectPciIrqRoutingTable(BiosKey);
-
- /* Report PCI buses */
- for (i = 0; i < (ULONG)BusData.NoBuses; i++)
- {
- /* Check if this is the first bus */
- if (i == 0)
- {
- /* Set 'Configuration Data' value */
- Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
- PartialDescriptors) +
- sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
- sizeof(PCI_REGISTRY_INFO);
- PartialResourceList = MmHeapAlloc(Size);
- if (!PartialResourceList)
- {
- DPRINTM(DPRINT_HWDETECT,
- "Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 1;
- PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
- PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
- PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
- PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(PCI_REGISTRY_INFO);
- memcpy(&PartialResourceList->PartialDescriptors[1],
- &BusData,
- sizeof(PCI_REGISTRY_INFO));
- }
- else
- {
- /* Set 'Configuration Data' value */
- Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
- PartialDescriptors);
- PartialResourceList = MmHeapAlloc(Size);
- if (!PartialResourceList)
- {
- DPRINTM(DPRINT_HWDETECT,
- "Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
- }
-
- /* Create the bus key */
- FldrCreateComponentKey(SystemKey,
- AdapterClass,
- MultiFunctionAdapter,
- 0x0,
- 0x0,
- 0xFFFFFFFF,
- "PCI",
- PartialResourceList,
- Size,
- &BusKey);
-
- MmHeapFree(PartialResourceList);
-
- /* Increment bus number */
- (*BusNumber)++;
- }
+ /* Set 'Configuration Data' value */
+ Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+
+ /* Create new bus key */
+ FldrCreateComponentKey(SystemKey,
+ AdapterClass,
+ MultiFunctionAdapter,
+ 0x0,
+ 0x0,
+ 0xFFFFFFFF,
+ "PCI BIOS",
+ PartialResourceList,
+ Size,
+ &BiosKey);
+
+ /* Increment bus number */
+ (*BusNumber)++;
+
+ DetectPciIrqRoutingTable(BiosKey);
+
+ /* Report PCI buses */
+ for (i = 0; i < (ULONG)BusData.NoBuses; i++)
+ {
+ /* Check if this is the first bus */
+ if (i == 0)
+ {
+ /* Set 'Configuration Data' value */
+ Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
+ PartialDescriptors) +
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
+ sizeof(PCI_REGISTRY_INFO);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (!PartialResourceList)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 1;
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+ PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
+ PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+ PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(PCI_REGISTRY_INFO);
+ memcpy(&PartialResourceList->PartialDescriptors[1],
+ &BusData,
+ sizeof(PCI_REGISTRY_INFO));
+ }
+ else
+ {
+ /* Set 'Configuration Data' value */
+ Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
+ PartialDescriptors);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (!PartialResourceList)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+ }
+
+ /* Create the bus key */
+ FldrCreateComponentKey(SystemKey,
+ AdapterClass,
+ MultiFunctionAdapter,
+ 0x0,
+ 0x0,
+ 0xFFFFFFFF,
+ "PCI",
+ PartialResourceList,
+ Size,
+ &BusKey);
+
+ /* Increment bus number */
+ (*BusNumber)++;
+ }
}
}