* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
-typedef struct _ROUTING_SLOT
-{
- UCHAR BusNumber;
- UCHAR DeviceNumber;
- UCHAR LinkA;
- USHORT BitmapA;
- UCHAR LinkB;
- USHORT BitmapB;
- UCHAR LinkC;
- USHORT BitmapC;
- UCHAR LinkD;
- USHORT BitmapD;
- UCHAR SlotNumber;
- UCHAR Reserved;
-} __attribute__((packed)) ROUTING_SLOT, *PROUTING_SLOT;
-
-typedef struct _PCI_IRQ_ROUTING_TABLE
-{
- ULONG Signature;
- USHORT Version;
- USHORT Size;
- UCHAR RouterBus;
- UCHAR RouterSlot;
- USHORT ExclusiveIRQs;
- ULONG CompatibleRouter;
- ULONG MiniportData;
- UCHAR Reserved[11];
- UCHAR Checksum;
- ROUTING_SLOT Slot[1];
-} __attribute__((packed)) PCI_IRQ_ROUTING_TABLE, *PPCI_IRQ_ROUTING_TABLE;
-
-typedef struct _CM_PCI_BUS_DATA
-{
- UCHAR BusCount;
- USHORT PciVersion;
- UCHAR HardwareMechanism;
-} __attribute__((packed)) CM_PCI_BUS_DATA, *PCM_PCI_BUS_DATA;
-
-
static PPCI_IRQ_ROUTING_TABLE
GetPciIrqRoutingTable(VOID)
{
ULONG i;
Table = (PPCI_IRQ_ROUTING_TABLE)0xF0000;
- while ((ULONG)Table < 0x100000)
+ while ((ULONG_PTR)Table < 0x100000)
{
- if (Table->Signature == 0x52495024)
+ if (Table->Signature == 'RIP$')
{
- DbgPrint((DPRINT_HWDETECT,
- "Found signature\n"));
+ DPRINTM(DPRINT_HWDETECT,
+ "Found signature\n");
Ptr = (PUCHAR)Table;
Sum = 0;
- for (i = 0; i < Table->Size; i++)
+ for (i = 0; i < Table->TableSize; i++)
{
Sum += Ptr[i];
}
if ((Sum & 0xFF) != 0)
{
- DbgPrint((DPRINT_HWDETECT,
- "Invalid routing table\n"));
+ DPRINTM(DPRINT_HWDETECT,
+ "Invalid routing table\n");
return NULL;
}
- DbgPrint((DPRINT_HWDETECT,
- "Valid checksum\n"));
+ DPRINTM(DPRINT_HWDETECT,
+ "Valid checksum\n");
return Table;
}
- Table = (PPCI_IRQ_ROUTING_TABLE)((ULONG)Table + 0x10);
+ Table = (PPCI_IRQ_ROUTING_TABLE)((ULONG_PTR)Table + 0x10);
}
return NULL;
static BOOLEAN
-FindPciBios(PCM_PCI_BUS_DATA BusData)
+FindPciBios(PPCI_REGISTRY_INFO BusData)
{
REGS RegsIn;
REGS RegsOut;
if (INT386_SUCCESS(RegsOut) && RegsOut.d.edx == 0x20494350 && RegsOut.b.ah == 0)
{
- DbgPrint((DPRINT_HWDETECT, "Found PCI bios\n"));
+ DPRINTM(DPRINT_HWDETECT, "Found PCI bios\n");
- DbgPrint((DPRINT_HWDETECT, "AL: %x\n", RegsOut.b.al));
- DbgPrint((DPRINT_HWDETECT, "BH: %x\n", RegsOut.b.bh));
- DbgPrint((DPRINT_HWDETECT, "BL: %x\n", RegsOut.b.bl));
- DbgPrint((DPRINT_HWDETECT, "CL: %x\n", RegsOut.b.cl));
+ 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);
- BusData->BusCount = RegsOut.b.cl + 1;
- BusData->PciVersion = RegsOut.w.bx;
- BusData->HardwareMechanism = RegsOut.b.cl;
+ BusData->NoBuses = RegsOut.b.cl + 1;
+ BusData->MajorRevision = RegsOut.b.bh;
+ BusData->MinorRevision = RegsOut.b.bl;
+ BusData->HardwareMechanism = RegsOut.b.al;
return TRUE;
}
- DbgPrint((DPRINT_HWDETECT, "No PCI bios found\n"));
+ DPRINTM(DPRINT_HWDETECT, "No PCI bios found\n");
return FALSE;
}
static VOID
-DetectPciIrqRoutingTable(FRLDRHKEY BusKey)
+DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey)
{
- PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PPCI_IRQ_ROUTING_TABLE Table;
- FRLDRHKEY TableKey;
+ PCONFIGURATION_COMPONENT_DATA TableKey;
ULONG Size;
- LONG Error;
Table = GetPciIrqRoutingTable();
if (Table != NULL)
{
- DbgPrint((DPRINT_HWDETECT, "Table size: %u\n", Table->Size));
-
- Error = RegCreateKey(BusKey,
- L"RealModeIrqRoutingTable\\0",
- &TableKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* Set 'Component Information' */
- SetComponentInformation(TableKey,
- 0x0,
- 0x0,
- 0xFFFFFFFF);
-
- /* Set 'Identifier' value */
- Error = RegSetValue(TableKey,
- L"Identifier",
- REG_SZ,
- (PCHAR)L"PCI Real-mode IRQ Routing Table",
- 32 * sizeof(WCHAR));
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
- return;
- }
+ DPRINTM(DPRINT_HWDETECT, "Table size: %u\n", Table->TableSize);
/* Set 'Configuration Data' value */
- Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
- Table->Size;
- FullResourceDescriptor = MmAllocateMemory(Size);
- if (FullResourceDescriptor == NULL)
- {
- DbgPrint((DPRINT_HWDETECT,
- "Failed to allocate resource descriptor\n"));
- return;
- }
+ 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(FullResourceDescriptor, 0, Size);
- FullResourceDescriptor->InterfaceType = Isa;
- FullResourceDescriptor->BusNumber = 0;
- FullResourceDescriptor->PartialResourceList.Count = 1;
-
- PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
+ 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->Size;
-
- memcpy((PVOID)((ULONG_PTR)FullResourceDescriptor + sizeof(CM_FULL_RESOURCE_DESCRIPTOR)),
- Table,
- Table->Size);
-
- /* Set 'Configuration Data' value */
- Error = RegSetValue(TableKey,
- L"Configuration Data",
- REG_FULL_RESOURCE_DESCRIPTOR,
- (PCHAR) FullResourceDescriptor,
- Size);
- MmFreeMemory(FullResourceDescriptor);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT,
- "RegSetValue(Configuration Data) failed (Error %u)\n",
- (int)Error));
- return;
- }
+ 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);
}
}
VOID
-DetectPciBios(FRLDRHKEY SystemKey, ULONG *BusNumber)
+DetectPciBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
{
- PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
- CM_PCI_BUS_DATA BusData;
- WCHAR Buffer[80];
- FRLDRHKEY BiosKey;
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ PCI_REGISTRY_INFO BusData;
+ PCONFIGURATION_COMPONENT_DATA BiosKey;
ULONG Size;
- LONG Error;
-#if 0
- FRLDRHKEY BusKey;
+ PCONFIGURATION_COMPONENT_DATA BusKey;
ULONG i;
- WCHAR szPci[] = L"PCI";
-#endif
/* Report the PCI BIOS */
if (FindPciBios(&BusData))
{
- /* Create new bus key */
- swprintf(Buffer,
- L"MultifunctionAdapter\\%u", *BusNumber);
- Error = RegCreateKey(SystemKey,
- Buffer,
- &BiosKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
- return;
- }
+ /* 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;
+ }
- /* Set 'Component Information' */
- SetComponentInformation(BiosKey,
- 0x0,
- 0x0,
- 0xFFFFFFFF);
+ /* 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)++;
- /* Set 'Identifier' value */
- Error = RegSetValue(BiosKey,
- L"Identifier",
- REG_SZ,
- (PCHAR)L"PCI BIOS",
- 9 * sizeof(WCHAR));
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
- FullResourceDescriptor = MmAllocateMemory(Size);
- if (FullResourceDescriptor == NULL)
- {
- DbgPrint((DPRINT_HWDETECT,
- "Failed to allocate resource descriptor\n"));
- return;
- }
-
- /* Initialize resource descriptor */
- memset(FullResourceDescriptor, 0, Size);
- FullResourceDescriptor->InterfaceType = PCIBus;
- FullResourceDescriptor->BusNumber = 0;
- FullResourceDescriptor->PartialResourceList.Version = 1;
- FullResourceDescriptor->PartialResourceList.Revision = 1;
- FullResourceDescriptor->PartialResourceList.Count = 1;
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeBusNumber;
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive;
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.BusNumber.Start = 0;
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.BusNumber.Length = 1;
-
- /* Set 'Configuration Data' value */
- Error = RegSetValue(BiosKey,
- L"Configuration Data",
- REG_FULL_RESOURCE_DESCRIPTOR,
- (PCHAR) FullResourceDescriptor,
- Size);
- MmFreeMemory(FullResourceDescriptor);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT,
- "RegSetValue(Configuration Data) failed (Error %u)\n",
- (int)Error));
- return;
- }
+ MmHeapFree(PartialResourceList);
DetectPciIrqRoutingTable(BiosKey);
-#if 0
- /*
- * FIXME:
- * Enabling this piece of code will corrupt the boot sequence!
- * This is probably caused by a bug in the registry code!
- */
-
/* Report PCI buses */
- for (i = 0; i < (ULONG)BusData.BusCount; i++)
- {
- swprintf(Buffer,
- L"MultifunctionAdapter\\%u", *BusNumber);
- Error = RegCreateKey(SystemKey,
- Buffer,
- &BusKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
- printf("RegCreateKey() failed (Error %u)\n", (int)Error);
- return;
- }
-
- /* Set 'Component Information' */
- SetComponentInformation(BusKey,
- 0x0,
- 0x0,
- 0xFFFFFFFF);
-
- /* Increment bus number */
- (*BusNumber)++;
-
-
- /* Set 'Identifier' value */
- Error = RegSetValue(BusKey,
- L"Identifier",
- REG_SZ,
- (PCSTR)szPci,
- sizeof(szPci));
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
- return;
- }
- }
-#endif
-
+ 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)++;
+ }
}
}