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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 DBG_DEFAULT_CHANNEL(HWDETECT
);
29 PPCI_IRQ_ROUTING_TABLE
30 GetPciIrqRoutingTable(VOID
)
32 PPCI_IRQ_ROUTING_TABLE Table
;
37 Table
= (PPCI_IRQ_ROUTING_TABLE
)0xF0000;
38 while ((ULONG_PTR
)Table
< 0x100000)
40 if (Table
->Signature
== 'RIP$')
42 TRACE("Found signature\n");
44 if (Table
->TableSize
< FIELD_OFFSET(PCI_IRQ_ROUTING_TABLE
, Slot
) ||
45 Table
->TableSize
% 16 != 0)
47 ERR("Invalid routing table size (%u) at 0x%p. Continue searching...\n", Table
->TableSize
, Table
);
48 Table
= (PPCI_IRQ_ROUTING_TABLE
)((ULONG_PTR
)Table
+ 0x10);
54 for (i
= 0; i
< Table
->TableSize
; i
++)
59 if ((Sum
& 0xFF) != 0)
61 ERR("Invalid routing table checksum (%#lx) at 0x%p. Continue searching...\n", Sum
& 0xFF, Table
);
65 TRACE("Valid checksum (%#lx): found routing table at 0x%p\n", Sum
& 0xFF, Table
);
70 Table
= (PPCI_IRQ_ROUTING_TABLE
)((ULONG_PTR
)Table
+ 0x10);
73 ERR("No valid routing table found!\n");
80 FindPciBios(PPCI_REGISTRY_INFO BusData
)
85 RegsIn
.b
.ah
= 0xB1; /* Subfunction B1h */
86 RegsIn
.b
.al
= 0x01; /* PCI BIOS present */
88 Int386(0x1A, &RegsIn
, &RegsOut
);
90 if (INT386_SUCCESS(RegsOut
) &&
91 (RegsOut
.d
.edx
== 0x20494350) &&
94 TRACE("Found PCI bios\n");
96 TRACE("AL: %x\n", RegsOut
.b
.al
);
97 TRACE("BH: %x\n", RegsOut
.b
.bh
);
98 TRACE("BL: %x\n", RegsOut
.b
.bl
);
99 TRACE("CL: %x\n", RegsOut
.b
.cl
);
101 BusData
->NoBuses
= RegsOut
.b
.cl
+ 1;
102 BusData
->MajorRevision
= RegsOut
.b
.bh
;
103 BusData
->MinorRevision
= RegsOut
.b
.bl
;
104 BusData
->HardwareMechanism
= RegsOut
.b
.al
;
109 TRACE("No PCI bios found\n");
117 DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey
)
119 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
120 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
121 PPCI_IRQ_ROUTING_TABLE Table
;
122 PCONFIGURATION_COMPONENT_DATA TableKey
;
125 Table
= GetPciIrqRoutingTable();
128 TRACE("Table size: %u\n", Table
->TableSize
);
130 /* Set 'Configuration Data' value */
131 Size
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
, PartialDescriptors
) +
132 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) + Table
->TableSize
;
133 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
134 if (PartialResourceList
== NULL
)
136 ERR("Failed to allocate resource descriptor\n");
140 /* Initialize resource descriptor */
141 memset(PartialResourceList
, 0, Size
);
142 PartialResourceList
->Version
= 1;
143 PartialResourceList
->Revision
= 1;
144 PartialResourceList
->Count
= 2;
146 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
147 PartialDescriptor
->Type
= CmResourceTypeBusNumber
;
148 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
149 PartialDescriptor
->u
.BusNumber
.Start
= 0;
150 PartialDescriptor
->u
.BusNumber
.Length
= 1;
152 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
153 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
154 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
155 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= Table
->TableSize
;
157 memcpy(&PartialResourceList
->PartialDescriptors
[2],
161 FldrCreateComponentKey(BusKey
,
163 RealModeIrqRoutingTable
,
167 "PCI Real-mode IRQ Routing Table",
176 DetectPciBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
178 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
179 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
180 PCI_REGISTRY_INFO BusData
;
181 PCONFIGURATION_COMPONENT_DATA BiosKey
;
183 PCONFIGURATION_COMPONENT_DATA BusKey
;
186 /* Report the PCI BIOS */
187 if (FindPciBios(&BusData
))
189 /* Set 'Configuration Data' value */
190 Size
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
, PartialDescriptors
);
191 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
192 if (PartialResourceList
== NULL
)
194 ERR("Failed to allocate resource descriptor\n");
198 /* Initialize resource descriptor */
199 memset(PartialResourceList
, 0, Size
);
201 /* Create new bus key */
202 FldrCreateComponentKey(SystemKey
,
204 MultiFunctionAdapter
,
213 /* Increment bus number */
216 DetectPciIrqRoutingTable(BiosKey
);
218 /* Report PCI buses */
219 for (i
= 0; i
< (ULONG
)BusData
.NoBuses
; i
++)
221 /* Check if this is the first bus */
224 /* Set 'Configuration Data' value */
225 Size
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
,
226 PartialDescriptors
) +
227 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
228 sizeof(PCI_REGISTRY_INFO
);
229 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
230 if (!PartialResourceList
)
232 ERR("Failed to allocate resource descriptor\n");
236 /* Initialize resource descriptor */
237 memset(PartialResourceList
, 0, Size
);
238 PartialResourceList
->Version
= 1;
239 PartialResourceList
->Revision
= 1;
240 PartialResourceList
->Count
= 1;
241 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
242 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
243 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
244 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(PCI_REGISTRY_INFO
);
245 memcpy(&PartialResourceList
->PartialDescriptors
[1],
247 sizeof(PCI_REGISTRY_INFO
));
251 /* Set 'Configuration Data' value */
252 Size
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
,
254 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
255 if (!PartialResourceList
)
257 ERR("Failed to allocate resource descriptor\n");
261 /* Initialize resource descriptor */
262 memset(PartialResourceList
, 0, Size
);
265 /* Create the bus key */
266 FldrCreateComponentKey(SystemKey
,
268 MultiFunctionAdapter
,
277 /* Increment bus number */