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
);
28 static PPCI_IRQ_ROUTING_TABLE
29 GetPciIrqRoutingTable(VOID
)
31 PPCI_IRQ_ROUTING_TABLE Table
;
36 Table
= (PPCI_IRQ_ROUTING_TABLE
)0xF0000;
37 while ((ULONG_PTR
)Table
< 0x100000)
39 if (Table
->Signature
== 'RIP$')
41 TRACE("Found signature\n");
45 for (i
= 0; i
< Table
->TableSize
; i
++)
50 if ((Sum
& 0xFF) != 0)
52 ERR("Invalid routing table\n");
56 TRACE("Valid checksum\n");
61 Table
= (PPCI_IRQ_ROUTING_TABLE
)((ULONG_PTR
)Table
+ 0x10);
69 FindPciBios(PPCI_REGISTRY_INFO BusData
)
74 RegsIn
.b
.ah
= 0xB1; /* Subfunction B1h */
75 RegsIn
.b
.al
= 0x01; /* PCI BIOS present */
77 Int386(0x1A, &RegsIn
, &RegsOut
);
79 if (INT386_SUCCESS(RegsOut
) && RegsOut
.d
.edx
== 0x20494350 && RegsOut
.b
.ah
== 0)
81 TRACE("Found PCI bios\n");
83 TRACE("AL: %x\n", RegsOut
.b
.al
);
84 TRACE("BH: %x\n", RegsOut
.b
.bh
);
85 TRACE("BL: %x\n", RegsOut
.b
.bl
);
86 TRACE("CL: %x\n", RegsOut
.b
.cl
);
88 BusData
->NoBuses
= RegsOut
.b
.cl
+ 1;
89 BusData
->MajorRevision
= RegsOut
.b
.bh
;
90 BusData
->MinorRevision
= RegsOut
.b
.bl
;
91 BusData
->HardwareMechanism
= RegsOut
.b
.al
;
97 TRACE("No PCI bios found\n");
104 DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey
)
106 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
107 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
108 PPCI_IRQ_ROUTING_TABLE Table
;
109 PCONFIGURATION_COMPONENT_DATA TableKey
;
112 Table
= GetPciIrqRoutingTable();
115 TRACE("Table size: %u\n", Table
->TableSize
);
117 /* Set 'Configuration Data' value */
118 Size
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
, PartialDescriptors
) +
119 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) + Table
->TableSize
;
120 PartialResourceList
= MmHeapAlloc(Size
);
121 if (PartialResourceList
== NULL
)
123 ERR("Failed to allocate resource descriptor\n");
127 /* Initialize resource descriptor */
128 memset(PartialResourceList
, 0, Size
);
129 PartialResourceList
->Version
= 1;
130 PartialResourceList
->Revision
= 1;
131 PartialResourceList
->Count
= 2;
133 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
134 PartialDescriptor
->Type
= CmResourceTypeBusNumber
;
135 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
136 PartialDescriptor
->u
.BusNumber
.Start
= 0;
137 PartialDescriptor
->u
.BusNumber
.Length
= 1;
139 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
140 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
141 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
142 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= Table
->TableSize
;
144 memcpy(&PartialResourceList
->PartialDescriptors
[2],
145 Table
, Table
->TableSize
);
147 FldrCreateComponentKey(BusKey
,
149 RealModeIrqRoutingTable
,
153 "PCI Real-mode IRQ Routing Table",
158 MmHeapFree(PartialResourceList
);
164 DetectPciBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
166 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
167 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
168 PCI_REGISTRY_INFO BusData
;
169 PCONFIGURATION_COMPONENT_DATA BiosKey
;
171 PCONFIGURATION_COMPONENT_DATA BusKey
;
174 /* Report the PCI BIOS */
175 if (FindPciBios(&BusData
))
177 /* Set 'Configuration Data' value */
178 Size
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
,
180 PartialResourceList
= MmHeapAlloc(Size
);
181 if (PartialResourceList
== NULL
)
183 ERR("Failed to allocate resource descriptor\n");
187 /* Initialize resource descriptor */
188 memset(PartialResourceList
, 0, Size
);
190 /* Create new bus key */
191 FldrCreateComponentKey(SystemKey
,
193 MultiFunctionAdapter
,
202 /* Increment bus number */
205 MmHeapFree(PartialResourceList
);
207 DetectPciIrqRoutingTable(BiosKey
);
209 /* Report PCI buses */
210 for (i
= 0; i
< (ULONG
)BusData
.NoBuses
; i
++)
212 /* Check if this is the first bus */
215 /* Set 'Configuration Data' value */
216 Size
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
,
217 PartialDescriptors
) +
218 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
219 sizeof(PCI_REGISTRY_INFO
);
220 PartialResourceList
= MmHeapAlloc(Size
);
221 if (!PartialResourceList
)
223 ERR("Failed to allocate resource descriptor\n");
227 /* Initialize resource descriptor */
228 memset(PartialResourceList
, 0, Size
);
229 PartialResourceList
->Version
= 1;
230 PartialResourceList
->Revision
= 1;
231 PartialResourceList
->Count
= 1;
232 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
233 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
234 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
235 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(PCI_REGISTRY_INFO
);
236 memcpy(&PartialResourceList
->PartialDescriptors
[1],
238 sizeof(PCI_REGISTRY_INFO
));
242 /* Set 'Configuration Data' value */
243 Size
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
,
245 PartialResourceList
= MmHeapAlloc(Size
);
246 if (!PartialResourceList
)
248 ERR("Failed to allocate resource descriptor\n");
252 /* Initialize resource descriptor */
253 memset(PartialResourceList
, 0, Size
);
256 /* Create the bus key */
257 FldrCreateComponentKey(SystemKey
,
259 MultiFunctionAdapter
,
268 MmHeapFree(PartialResourceList
);
270 /* Increment bus number */