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) { 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); } }
static VOID DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber) { PCM_PARTIAL_RESOURCE_LIST PartialResourceList; PCONFIGURATION_COMPONENT_DATA BusKey; ULONG Size; /* Set 'Configuration Data' value */ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); PartialResourceList = MmHeapAlloc(Size); if (PartialResourceList == NULL) { TRACE( "Failed to allocate resource descriptor\n"); return; } /* Initialize resource descriptor */ memset(PartialResourceList, 0, Size); PartialResourceList->Version = 1; PartialResourceList->Revision = 1; PartialResourceList->Count = 0; /* Create new bus key */ FldrCreateComponentKey(SystemKey, AdapterClass, MultiFunctionAdapter, 0x0, 0x0, 0xFFFFFFFF, "ISA", PartialResourceList, Size, &BusKey); /* Increment bus number */ (*BusNumber)++; MmHeapFree(PartialResourceList); /* Detect ISA/BIOS devices */ DetectBiosDisks(SystemKey, BusKey); /* FIXME: Detect more ISA devices */ }
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)) { /* 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)++; } } }
static VOID DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey, PCONFIGURATION_COMPONENT_DATA BusKey) { PCM_PARTIAL_RESOURCE_LIST PartialResourceList; PCM_INT13_DRIVE_PARAMETER Int13Drives; GEOMETRY Geometry; PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey; UCHAR DiskCount, i; ULONG Size; BOOLEAN Changed; /* Count the number of visible drives */ DiskReportError(FALSE); DiskCount = 0; /* There are some really broken BIOSes out there. There are even BIOSes * that happily report success when you ask them to read from non-existent * harddisks. So, we set the buffer to known contents first, then try to * read. If the BIOS reports success but the buffer contents haven't * changed then we fail anyway */ memset((PVOID) DISKREADBUFFER, 0xcd, 512); while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER)) { Changed = FALSE; for (i = 0; ! Changed && i < 512; i++) { Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd; } if (! Changed) { TRACE("BIOS reports success for disk %d but data didn't change\n", (int)DiskCount); break; } DiskCount++; memset((PVOID) DISKREADBUFFER, 0xcd, 512); } DiskReportError(TRUE); TRACE("BIOS reports %d harddisk%s\n", (int)DiskCount, (DiskCount == 1) ? "": "s"); //DetectBiosFloppyController(BusKey); /* Allocate resource descriptor */ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) + sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount; PartialResourceList = MmHeapAlloc(Size); 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 = 1; PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific; PartialResourceList->PartialDescriptors[0].ShareDisposition = 0; PartialResourceList->PartialDescriptors[0].Flags = 0; PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize = sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount; /* Get harddisk Int13 geometry data */ Int13Drives = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST)); for (i = 0; i < DiskCount; i++) { if (MachDiskGetDriveGeometry(0x80 + i, &Geometry)) { Int13Drives[i].DriveSelect = 0x80 + i; Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1; Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors; Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1; Int13Drives[i].NumberDrives = DiskCount; TRACE( "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n", 0x80 + i, Geometry.Cylinders - 1, Geometry.Heads -1, Geometry.Sectors, Geometry.BytesPerSector); } } FldrCreateComponentKey(BusKey, ControllerClass, DiskController, Output | Input, 0, 0xFFFFFFFF, NULL, PartialResourceList, Size, &ControllerKey); TRACE("Created key: DiskController\\0\n"); MmHeapFree(PartialResourceList); /* Create and fill subkey for each harddisk */ for (i = 0; i < DiskCount; i++) { PCM_PARTIAL_RESOURCE_LIST PartialResourceList; ULONG Size; CHAR Identifier[20]; /* Get disk values */ PartialResourceList = GetHarddiskConfigurationData(0x80 + i, &Size); GetHarddiskIdentifier(Identifier, 0x80 + i); /* Create disk key */ FldrCreateComponentKey(ControllerKey, PeripheralClass, DiskPeripheral, Output | Input, 0, 0xFFFFFFFF, Identifier, PartialResourceList, Size, &DiskKey); if (PartialResourceList) MmHeapFree(PartialResourceList); } }
VOID DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber) { PCONFIGURATION_COMPONENT_DATA BiosKey; PCM_PARTIAL_RESOURCE_LIST PartialResourceList; PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; PRSDP_DESCRIPTOR Rsdp; PACPI_BIOS_DATA AcpiBiosData; ULONG TableSize; Rsdp = FindAcpiBios(); if (Rsdp) { /* Set up the flag in the loader block */ AcpiPresent = TRUE; /* Calculate the table size */ TableSize = PcBiosMapCount * sizeof(BIOS_MEMORY_MAP) + sizeof(ACPI_BIOS_DATA) - sizeof(BIOS_MEMORY_MAP); /* Set 'Configuration Data' value */ PartialResourceList = FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize, TAG_HW_RESOURCE_LIST); if (PartialResourceList == NULL) { ERR("Failed to allocate resource descriptor\n"); return; } memset(PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize); PartialResourceList->Version = 0; PartialResourceList->Revision = 0; PartialResourceList->Count = 1; PartialDescriptor = &PartialResourceList->PartialDescriptors[0]; PartialDescriptor->Type = CmResourceTypeDeviceSpecific; PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; PartialDescriptor->u.DeviceSpecificData.DataSize = TableSize; /* Fill the table */ AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1]; AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address; AcpiBiosData->Count = PcBiosMapCount; memcpy(AcpiBiosData->MemoryMap, PcBiosMemoryMap, PcBiosMapCount * sizeof(BIOS_MEMORY_MAP)); TRACE("RSDT %p, data size %x\n", Rsdp->rsdt_physical_address, TableSize); /* Create new bus key */ FldrCreateComponentKey(SystemKey, AdapterClass, MultiFunctionAdapter, 0x0, 0x0, 0xFFFFFFFF, "ACPI BIOS", PartialResourceList, sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize, &BiosKey); /* Increment bus number */ (*BusNumber)++; } }