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.
28 #include "../../reactos/registry.h"
31 typedef struct _ROUTING_SLOT
45 } __attribute__((packed
)) ROUTING_SLOT
, *PROUTING_SLOT
;
47 typedef struct _PCI_IRQ_ROUTING_TABLE
55 ULONG CompatibleRouter
;
60 } __attribute__((packed
)) PCI_IRQ_ROUTING_TABLE
, *PPCI_IRQ_ROUTING_TABLE
;
62 typedef struct _CM_PCI_BUS_DATA
66 UCHAR HardwareMechanism
;
67 } __attribute__((packed
)) CM_PCI_BUS_DATA
, *PCM_PCI_BUS_DATA
;
70 static PPCI_IRQ_ROUTING_TABLE
71 GetPciIrqRoutingTable(VOID
)
73 PPCI_IRQ_ROUTING_TABLE Table
;
78 Table
= (PPCI_IRQ_ROUTING_TABLE
)0xF0000;
79 while ((ULONG
)Table
< 0x100000)
81 if (Table
->Signature
== 0x52495024)
83 DbgPrint((DPRINT_HWDETECT
,
84 "Found signature\n"));
88 for (i
= 0; i
< Table
->Size
; i
++)
93 if ((Sum
& 0xFF) != 0)
95 DbgPrint((DPRINT_HWDETECT
,
96 "Invalid routing table\n"));
100 DbgPrint((DPRINT_HWDETECT
,
101 "Valid checksum\n"));
106 Table
= (PPCI_IRQ_ROUTING_TABLE
)((ULONG
)Table
+ 0x10);
114 FindPciBios(PCM_PCI_BUS_DATA BusData
)
119 RegsIn
.b
.ah
= 0xB1; /* Subfunction B1h */
120 RegsIn
.b
.al
= 0x01; /* PCI BIOS present */
122 Int386(0x1A, &RegsIn
, &RegsOut
);
124 if (INT386_SUCCESS(RegsOut
) && RegsOut
.d
.edx
== 0x20494350 && RegsOut
.b
.ah
== 0)
126 DbgPrint((DPRINT_HWDETECT
, "Found PCI bios\n"));
128 DbgPrint((DPRINT_HWDETECT
, "AL: %x\n", RegsOut
.b
.al
));
129 DbgPrint((DPRINT_HWDETECT
, "BH: %x\n", RegsOut
.b
.bh
));
130 DbgPrint((DPRINT_HWDETECT
, "BL: %x\n", RegsOut
.b
.bl
));
131 DbgPrint((DPRINT_HWDETECT
, "CL: %x\n", RegsOut
.b
.cl
));
133 BusData
->BusCount
= RegsOut
.b
.cl
+ 1;
134 BusData
->PciVersion
= RegsOut
.w
.bx
;
135 BusData
->HardwareMechanism
= RegsOut
.b
.cl
;
141 DbgPrint((DPRINT_HWDETECT
, "No PCI bios found\n"));
148 DetectPciIrqRoutingTable(FRLDRHKEY BusKey
)
150 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
151 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
152 PPCI_IRQ_ROUTING_TABLE Table
;
157 Table
= GetPciIrqRoutingTable();
160 DbgPrint((DPRINT_HWDETECT
, "Table size: %u\n", Table
->Size
));
162 Error
= RegCreateKey(BusKey
,
163 "RealModeIrqRoutingTable\\0",
165 if (Error
!= ERROR_SUCCESS
)
167 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
171 /* Set 'Component Information' */
172 SetComponentInformation(TableKey
,
177 /* Set 'Identifier' value */
178 Error
= RegSetValue(TableKey
,
181 (PUCHAR
)"PCI Real-mode IRQ Routing Table",
183 if (Error
!= ERROR_SUCCESS
)
185 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
189 /* Set 'Configuration Data' value */
190 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
192 FullResourceDescriptor
= MmAllocateMemory(Size
);
193 if (FullResourceDescriptor
== NULL
)
195 DbgPrint((DPRINT_HWDETECT
,
196 "Failed to allocate resource descriptor\n"));
200 /* Initialize resource descriptor */
201 memset(FullResourceDescriptor
, 0, Size
);
202 FullResourceDescriptor
->InterfaceType
= Isa
;
203 FullResourceDescriptor
->BusNumber
= 0;
204 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
206 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
207 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
208 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
209 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= Table
->Size
;
211 memcpy(((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
),
215 /* Set 'Configuration Data' value */
216 Error
= RegSetValue(TableKey
,
217 "Configuration Data",
218 REG_FULL_RESOURCE_DESCRIPTOR
,
219 (PUCHAR
) FullResourceDescriptor
,
221 MmFreeMemory(FullResourceDescriptor
);
222 if (Error
!= ERROR_SUCCESS
)
224 DbgPrint((DPRINT_HWDETECT
,
225 "RegSetValue(Configuration Data) failed (Error %u)\n",
234 DetectPciBios(FRLDRHKEY SystemKey
, ULONG
*BusNumber
)
236 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
237 CM_PCI_BUS_DATA BusData
;
247 /* Report the PCI BIOS */
248 if (FindPciBios(&BusData
))
250 /* Create new bus key */
252 "MultifunctionAdapter\\%u", *BusNumber
);
253 Error
= RegCreateKey(SystemKey
,
256 if (Error
!= ERROR_SUCCESS
)
258 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
262 /* Set 'Component Information' */
263 SetComponentInformation(BiosKey
,
268 /* Increment bus number */
271 /* Set 'Identifier' value */
272 Error
= RegSetValue(BiosKey
,
277 if (Error
!= ERROR_SUCCESS
)
279 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
283 /* Set 'Configuration Data' value */
284 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
285 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
286 FullResourceDescriptor
= MmAllocateMemory(Size
);
287 if (FullResourceDescriptor
== NULL
)
289 DbgPrint((DPRINT_HWDETECT
,
290 "Failed to allocate resource descriptor\n"));
294 /* Initialize resource descriptor */
295 memset(FullResourceDescriptor
, 0, Size
);
296 FullResourceDescriptor
->InterfaceType
= Internal
;
297 FullResourceDescriptor
->BusNumber
= 0;
298 FullResourceDescriptor
->PartialResourceList
.Count
= 0;
300 /* Set 'Configuration Data' value */
301 Error
= RegSetValue(BiosKey
,
302 "Configuration Data",
303 REG_FULL_RESOURCE_DESCRIPTOR
,
304 (PUCHAR
) FullResourceDescriptor
,
306 MmFreeMemory(FullResourceDescriptor
);
307 if (Error
!= ERROR_SUCCESS
)
309 DbgPrint((DPRINT_HWDETECT
,
310 "RegSetValue(Configuration Data) failed (Error %u)\n",
315 DetectPciIrqRoutingTable(BiosKey
);
320 * Enabling this piece of code will corrupt the boot sequence!
321 * This is probably caused by a bug in the registry code!
324 /* Report PCI buses */
325 for (i
= 0; i
< (ULONG
)BusData
.BusCount
; i
++)
328 "MultifunctionAdapter\\%u", *BusNumber
);
329 Error
= RegCreateKey(SystemKey
,
332 if (Error
!= ERROR_SUCCESS
)
334 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
335 printf("RegCreateKey() failed (Error %u)\n", (int)Error
);
339 /* Set 'Component Information' */
340 SetComponentInformation(BusKey
,
345 /* Increment bus number */
349 /* Set 'Identifier' value */
350 Error
= RegSetValue(BusKey
,
355 if (Error
!= ERROR_SUCCESS
)
357 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));