ReactOS 0.4.16-dev-2615-g89221f5
hwpci.c
Go to the documentation of this file.
1/*
2 * FreeLoader
3 *
4 * Copyright (C) 2004 Eric Kohl
5 *
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.
10 *
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.
15 *
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.
19 */
20
21#include <freeldr.h>
22
23#include <debug.h>
25
26static
29{
31 PUCHAR Ptr;
32 ULONG Sum;
33 ULONG i;
34
36 while ((ULONG_PTR)Table < 0x100000)
37 {
38 if (Table->Signature == 'RIP$')
39 {
40 TRACE("Found signature\n");
41
42 if (Table->TableSize < FIELD_OFFSET(PCI_IRQ_ROUTING_TABLE, Slot) ||
43 Table->TableSize % 16 != 0)
44 {
45 ERR("Invalid routing table size (%u) at 0x%p. Continue searching...\n", Table->TableSize, Table);
47 continue;
48 }
49
50 Ptr = (PUCHAR)Table;
51 Sum = 0;
52 for (i = 0; i < Table->TableSize; i++)
53 {
54 Sum += Ptr[i];
55 }
56
57 if ((Sum & 0xFF) != 0)
58 {
59 ERR("Invalid routing table checksum (%#lx) at 0x%p. Continue searching...\n", Sum & 0xFF, Table);
60 }
61 else
62 {
63 TRACE("Valid checksum (%#lx): found routing table at 0x%p\n", Sum & 0xFF, Table);
64 return Table;
65 }
66 }
67
69 }
70
71 ERR("No valid routing table found!\n");
72
73 return NULL;
74}
75
78{
79 REGS RegsIn;
80 REGS RegsOut;
81
82 RegsIn.b.ah = 0xB1; /* Subfunction B1h */
83 RegsIn.b.al = 0x01; /* PCI BIOS present */
84
85 Int386(0x1A, &RegsIn, &RegsOut);
86
87 if (INT386_SUCCESS(RegsOut) &&
88 (RegsOut.d.edx == ' ICP') &&
89 (RegsOut.b.ah == 0))
90 {
91 TRACE("Found PCI bios\n");
92
93 TRACE("AL: %x\n", RegsOut.b.al);
94 TRACE("BH: %x\n", RegsOut.b.bh);
95 TRACE("BL: %x\n", RegsOut.b.bl);
96 TRACE("CL: %x\n", RegsOut.b.cl);
97
98 BusData->NoBuses = RegsOut.b.cl + 1;
99 BusData->MajorRevision = RegsOut.b.bh;
100 BusData->MinorRevision = RegsOut.b.bl;
101 BusData->HardwareMechanism = RegsOut.b.al;
102
103 return TRUE;
104 }
105
106 TRACE("No PCI bios found\n");
107
108 return FALSE;
109}
110
111static
112VOID
114{
115 PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
116 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
119 ULONG Size;
120
122 if (Table != NULL)
123 {
124 TRACE("Table size: %u\n", Table->TableSize);
125
126 /* Set 'Configuration Data' value */
127 Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors[2]) + Table->TableSize;
128 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
129 if (PartialResourceList == NULL)
130 {
131 ERR("Failed to allocate resource descriptor\n");
132 return;
133 }
134
135 /* Initialize resource descriptor */
136 RtlZeroMemory(PartialResourceList, Size);
137 PartialResourceList->Version = 1;
138 PartialResourceList->Revision = 1;
139 PartialResourceList->Count = 2;
140
141 PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
142 PartialDescriptor->Type = CmResourceTypeBusNumber;
144 PartialDescriptor->u.BusNumber.Start = 0;
145 PartialDescriptor->u.BusNumber.Length = 1;
146
147 PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
148 PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
150 PartialDescriptor->u.DeviceSpecificData.DataSize = Table->TableSize;
151
152 RtlCopyMemory(&PartialResourceList->PartialDescriptors[2],
153 Table, Table->TableSize);
154
158 0,
159 0,
160 0xFFFFFFFF,
161 "PCI Real-mode IRQ Routing Table",
162 PartialResourceList,
163 Size,
164 &TableKey);
165 }
166}
167
168VOID
172 _In_ FIND_PCI_BIOS MachFindPciBios)
173{
174 PCI_REGISTRY_INFO BusData;
175 PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
176 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
179 ULONG Size;
180 ULONG i;
181
182 /* Report the PCI BIOS */
183 if (!MachFindPciBios(&BusData))
184 return;
185
186 /* Set 'Configuration Data' value */
187 Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
188 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
189 if (PartialResourceList == NULL)
190 {
191 ERR("Failed to allocate resource descriptor\n");
192 return;
193 }
194
195 /* Initialize resource descriptor */
196 RtlZeroMemory(PartialResourceList, Size);
197
198 /* Create new bus key */
199 FldrCreateComponentKey(SystemKey,
202 0,
203 0,
204 0xFFFFFFFF,
205 "PCI BIOS",
206 PartialResourceList,
207 Size,
208 &BiosKey);
209
210 /* Increment bus number */
211 (*BusNumber)++;
212
214
215 /* Report PCI buses */
216 for (i = 0; i < (ULONG)BusData.NoBuses; i++)
217 {
218 /* Check if this is the first bus */
219 if (i == 0)
220 {
221 /* Set 'Configuration Data' value */
222 Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors[1]) +
223 sizeof(BusData);
224 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
225 if (!PartialResourceList)
226 {
227 ERR("Failed to allocate resource descriptor! Ignoring remaining PCI buses. (i = %lu, NoBuses = %lu)\n",
228 i, (ULONG)BusData.NoBuses);
229 return;
230 }
231
232 /* Initialize resource descriptor */
233 RtlZeroMemory(PartialResourceList, Size);
234 PartialResourceList->Version = 1;
235 PartialResourceList->Revision = 1;
236 PartialResourceList->Count = 1;
237
238 PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
239 PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
241 PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(BusData);
242
243 RtlCopyMemory(&PartialResourceList->PartialDescriptors[1],
244 &BusData, sizeof(BusData));
245 }
246 else
247 {
248 /* Set 'Configuration Data' value */
249 Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
250 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
251 if (!PartialResourceList)
252 {
253 ERR("Failed to allocate resource descriptor! Ignoring remaining PCI buses. (i = %lu, NoBuses = %lu)\n",
254 i, (ULONG)BusData.NoBuses);
255 return;
256 }
257
258 /* Initialize resource descriptor */
259 RtlZeroMemory(PartialResourceList, Size);
260 }
261
262 /* Create the bus key */
263 FldrCreateComponentKey(SystemKey,
266 0,
267 0,
268 0xFFFFFFFF,
269 "PCI",
270 PartialResourceList,
271 Size,
272 &BusKey);
273
274 /* Increment bus number */
275 (*BusNumber)++;
276 }
277}
278
279/* EOF */
unsigned char BOOLEAN
Definition: actypes.h:127
VOID FldrCreateComponentKey(_In_ PCONFIGURATION_COMPONENT_DATA SystemNode, _In_ CONFIGURATION_CLASS Class, _In_ CONFIGURATION_TYPE Type, _In_ IDENTIFIER_FLAG Flags, _In_ ULONG Key, _In_ ULONG Affinity, _In_ PCSTR IdentifierString, _In_ PCM_PARTIAL_RESOURCE_LIST ResourceList, _In_ ULONG Size, _Out_ PCONFIGURATION_COMPONENT_DATA *ComponentKey)
Definition: archwsup.c:224
#define ERR(fmt,...)
Definition: precomp.h:57
static PPCI_IRQ_ROUTING_TABLE GetPciIrqRoutingTable(VOID)
Definition: hwpci.c:28
VOID DetectPciBios(_In_ PCONFIGURATION_COMPONENT_DATA SystemKey, _Inout_ PULONG BusNumber, _In_ FIND_PCI_BIOS MachFindPciBios)
Definition: hwpci.c:169
static VOID DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey)
Definition: hwpci.c:113
BOOLEAN PcFindPciBios(PPCI_REGISTRY_INFO BusData)
Definition: hwpci.c:77
BOOLEAN(* FIND_PCI_BIOS)(PPCI_REGISTRY_INFO BusData)
Definition: hardware.h:74
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: heap.c:533
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
ASMGENDATA Table[]
Definition: genincdata.c:61
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define INT386_SUCCESS(regs)
Definition: pcbios.h:181
int __cdecl Int386(int ivec, REGS *in, REGS *out)
#define CmResourceTypeDeviceSpecific
Definition: restypes.h:108
#define CmResourceTypeBusNumber
Definition: restypes.h:109
@ AdapterClass
Definition: arc.h:102
@ PeripheralClass
Definition: arc.h:104
@ MultiFunctionAdapter
Definition: arc.h:125
@ RealModeIrqRoutingTable
Definition: arc.h:152
struct _PCI_IRQ_ROUTING_TABLE * PPCI_IRQ_ROUTING_TABLE
#define TRACE(s)
Definition: solgame.cpp:4
unsigned char bl
Definition: pcbios.h:136
unsigned char cl
Definition: pcbios.h:139
unsigned char al
Definition: pcbios.h:133
unsigned char ah
Definition: pcbios.h:134
unsigned char bh
Definition: pcbios.h:137
unsigned long edx
Definition: pcbios.h:96
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@392 BusNumber
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@393 DeviceSpecificData
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: restypes.h:100
UCHAR MajorRevision
Definition: pci.h:107
UCHAR NoBuses
Definition: pci.h:109
UCHAR HardwareMechanism
Definition: pci.h:110
UCHAR MinorRevision
Definition: pci.h:108
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define TAG_HW_RESOURCE_LIST
Definition: uefidisk.c:15
Definition: pcbios.h:161
DWORDREGS d
Definition: pcbios.h:163
BYTEREGS b
Definition: pcbios.h:165
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
@ CmResourceShareDeviceExclusive
Definition: cmtypes.h:241
@ CmResourceShareUndetermined
Definition: cmtypes.h:240
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160