4 * Copyright (C) 2004 Eric Kohl
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 typedef struct _ROUTING_SLOT
40 } __attribute__((packed
)) ROUTING_SLOT
, *PROUTING_SLOT
;
42 typedef struct _PCI_IRQ_ROUTING_TABLE
50 ULONG CompatibleRouter
;
55 } __attribute__((packed
)) PCI_IRQ_ROUTING_TABLE
, *PPCI_IRQ_ROUTING_TABLE
;
57 typedef struct _CM_PCI_BUS_DATA
61 UCHAR HardwareMechanism
;
62 } __attribute__((packed
)) CM_PCI_BUS_DATA
, *PCM_PCI_BUS_DATA
;
65 static PPCI_IRQ_ROUTING_TABLE
66 GetPciIrqRoutingTable(VOID
)
68 PPCI_IRQ_ROUTING_TABLE Table
;
73 Table
= (PPCI_IRQ_ROUTING_TABLE
)0xF0000;
74 while ((ULONG
)Table
< 0x100000)
76 if (Table
->Signature
== 0x52495024)
78 DbgPrint((DPRINT_HWDETECT
,
79 "Found signature\n"));
83 for (i
= 0; i
< Table
->Size
; i
++)
88 if ((Sum
& 0xFF) != 0)
90 DbgPrint((DPRINT_HWDETECT
,
91 "Invalid routing table\n"));
95 DbgPrint((DPRINT_HWDETECT
,
101 Table
= (PPCI_IRQ_ROUTING_TABLE
)((ULONG
)Table
+ 0x10);
109 FindPciBios(PCM_PCI_BUS_DATA BusData
)
114 RegsIn
.b
.ah
= 0xB1; /* Subfunction B1h */
115 RegsIn
.b
.al
= 0x01; /* PCI BIOS present */
117 Int386(0x1A, &RegsIn
, &RegsOut
);
119 if (INT386_SUCCESS(RegsOut
) && RegsOut
.d
.edx
== 0x20494350 && RegsOut
.b
.ah
== 0)
121 DbgPrint((DPRINT_HWDETECT
, "Found PCI bios\n"));
123 DbgPrint((DPRINT_HWDETECT
, "AL: %x\n", RegsOut
.b
.al
));
124 DbgPrint((DPRINT_HWDETECT
, "BH: %x\n", RegsOut
.b
.bh
));
125 DbgPrint((DPRINT_HWDETECT
, "BL: %x\n", RegsOut
.b
.bl
));
126 DbgPrint((DPRINT_HWDETECT
, "CL: %x\n", RegsOut
.b
.cl
));
128 BusData
->BusCount
= RegsOut
.b
.cl
+ 1;
129 BusData
->PciVersion
= RegsOut
.w
.bx
;
130 BusData
->HardwareMechanism
= RegsOut
.b
.cl
;
136 DbgPrint((DPRINT_HWDETECT
, "No PCI bios found\n"));
143 DetectPciIrqRoutingTable(FRLDRHKEY BusKey
)
145 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
146 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
147 PPCI_IRQ_ROUTING_TABLE Table
;
152 Table
= GetPciIrqRoutingTable();
155 DbgPrint((DPRINT_HWDETECT
, "Table size: %u\n", Table
->Size
));
157 Error
= RegCreateKey(BusKey
,
158 L
"RealModeIrqRoutingTable\\0",
160 if (Error
!= ERROR_SUCCESS
)
162 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
166 /* Set 'Component Information' */
167 SetComponentInformation(TableKey
,
172 /* Set 'Identifier' value */
173 Error
= RegSetValue(TableKey
,
176 (PCHAR
)L
"PCI Real-mode IRQ Routing Table",
178 if (Error
!= ERROR_SUCCESS
)
180 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
184 /* Set 'Configuration Data' value */
185 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
187 FullResourceDescriptor
= MmAllocateMemory(Size
);
188 if (FullResourceDescriptor
== NULL
)
190 DbgPrint((DPRINT_HWDETECT
,
191 "Failed to allocate resource descriptor\n"));
195 /* Initialize resource descriptor */
196 memset(FullResourceDescriptor
, 0, Size
);
197 FullResourceDescriptor
->InterfaceType
= Isa
;
198 FullResourceDescriptor
->BusNumber
= 0;
199 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
201 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
202 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
203 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
204 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= Table
->Size
;
206 memcpy((PVOID
)((ULONG_PTR
)FullResourceDescriptor
+ sizeof(CM_FULL_RESOURCE_DESCRIPTOR
)),
210 /* Set 'Configuration Data' value */
211 Error
= RegSetValue(TableKey
,
212 L
"Configuration Data",
213 REG_FULL_RESOURCE_DESCRIPTOR
,
214 (PCHAR
) FullResourceDescriptor
,
216 MmFreeMemory(FullResourceDescriptor
);
217 if (Error
!= ERROR_SUCCESS
)
219 DbgPrint((DPRINT_HWDETECT
,
220 "RegSetValue(Configuration Data) failed (Error %u)\n",
229 DetectPciBios(FRLDRHKEY SystemKey
, ULONG
*BusNumber
)
231 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
232 CM_PCI_BUS_DATA BusData
;
240 WCHAR szPci
[] = L
"PCI";
243 /* Report the PCI BIOS */
244 if (FindPciBios(&BusData
))
246 /* Create new bus key */
248 L
"MultifunctionAdapter\\%u", *BusNumber
);
249 Error
= RegCreateKey(SystemKey
,
252 if (Error
!= ERROR_SUCCESS
)
254 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
258 /* Set 'Component Information' */
259 SetComponentInformation(BiosKey
,
264 /* Increment bus number */
267 /* Set 'Identifier' value */
268 Error
= RegSetValue(BiosKey
,
273 if (Error
!= ERROR_SUCCESS
)
275 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
279 /* Set 'Configuration Data' value */
280 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
281 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
282 FullResourceDescriptor
= MmAllocateMemory(Size
);
283 if (FullResourceDescriptor
== NULL
)
285 DbgPrint((DPRINT_HWDETECT
,
286 "Failed to allocate resource descriptor\n"));
290 /* Initialize resource descriptor */
291 memset(FullResourceDescriptor
, 0, Size
);
292 FullResourceDescriptor
->InterfaceType
= PCIBus
;
293 FullResourceDescriptor
->BusNumber
= 0;
294 FullResourceDescriptor
->PartialResourceList
.Count
= 0;
296 /* Set 'Configuration Data' value */
297 Error
= RegSetValue(BiosKey
,
298 L
"Configuration Data",
299 REG_FULL_RESOURCE_DESCRIPTOR
,
300 (PCHAR
) FullResourceDescriptor
,
302 MmFreeMemory(FullResourceDescriptor
);
303 if (Error
!= ERROR_SUCCESS
)
305 DbgPrint((DPRINT_HWDETECT
,
306 "RegSetValue(Configuration Data) failed (Error %u)\n",
311 DetectPciIrqRoutingTable(BiosKey
);
316 * Enabling this piece of code will corrupt the boot sequence!
317 * This is probably caused by a bug in the registry code!
320 /* Report PCI buses */
321 for (i
= 0; i
< (ULONG
)BusData
.BusCount
; i
++)
324 L
"MultifunctionAdapter\\%u", *BusNumber
);
325 Error
= RegCreateKey(SystemKey
,
328 if (Error
!= ERROR_SUCCESS
)
330 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
331 printf("RegCreateKey() failed (Error %u)\n", (int)Error
);
335 /* Set 'Component Information' */
336 SetComponentInformation(BusKey
,
341 /* Increment bus number */
345 /* Set 'Identifier' value */
346 Error
= RegSetValue(BusKey
,
351 if (Error
!= ERROR_SUCCESS
)
353 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));