ReactOS  0.4.14-dev-991-g696cdc6
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>
24 DBG_DEFAULT_CHANNEL(HWDETECT);
25 
27 
28 static
31 {
33  PUCHAR Ptr;
34  ULONG Sum;
35  ULONG i;
36 
37  Table = (PPCI_IRQ_ROUTING_TABLE)0xF0000;
38  while ((ULONG_PTR)Table < 0x100000)
39  {
40  if (Table->Signature == 'RIP$')
41  {
42  TRACE("Found signature\n");
43 
44  if (Table->TableSize < FIELD_OFFSET(PCI_IRQ_ROUTING_TABLE, Slot) ||
45  Table->TableSize % 16 != 0)
46  {
47  ERR("Invalid routing table size (%u) at 0x%p. Continue searching...\n", Table->TableSize, Table);
49  continue;
50  }
51 
52  Ptr = (PUCHAR)Table;
53  Sum = 0;
54  for (i = 0; i < Table->TableSize; i++)
55  {
56  Sum += Ptr[i];
57  }
58 
59  if ((Sum & 0xFF) != 0)
60  {
61  ERR("Invalid routing table checksum (%#lx) at 0x%p. Continue searching...\n", Sum & 0xFF, Table);
62  }
63  else
64  {
65  TRACE("Valid checksum (%#lx): found routing table at 0x%p\n", Sum & 0xFF, Table);
66  return Table;
67  }
68  }
69 
71  }
72 
73  ERR("No valid routing table found!\n");
74 
75  return NULL;
76 }
77 
78 
79 BOOLEAN
81 {
82  REGS RegsIn;
83  REGS RegsOut;
84 
85  RegsIn.b.ah = 0xB1; /* Subfunction B1h */
86  RegsIn.b.al = 0x01; /* PCI BIOS present */
87 
88  Int386(0x1A, &RegsIn, &RegsOut);
89 
90  if (INT386_SUCCESS(RegsOut) &&
91  (RegsOut.d.edx == ' ICP') &&
92  (RegsOut.b.ah == 0))
93  {
94  TRACE("Found PCI bios\n");
95 
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);
100 
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;
105 
106  return TRUE;
107  }
108 
109  TRACE("No PCI bios found\n");
110 
111  return FALSE;
112 }
113 
114 
115 static
116 VOID
118 {
119  PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
120  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
123  ULONG Size;
124 
126  if (Table != NULL)
127  {
128  TRACE("Table size: %u\n", Table->TableSize);
129 
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)
135  {
136  ERR("Failed to allocate resource descriptor\n");
137  return;
138  }
139 
140  /* Initialize resource descriptor */
141  memset(PartialResourceList, 0, Size);
142  PartialResourceList->Version = 1;
143  PartialResourceList->Revision = 1;
144  PartialResourceList->Count = 2;
145 
146  PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
147  PartialDescriptor->Type = CmResourceTypeBusNumber;
149  PartialDescriptor->u.BusNumber.Start = 0;
150  PartialDescriptor->u.BusNumber.Length = 1;
151 
152  PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
153  PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
154  PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
155  PartialDescriptor->u.DeviceSpecificData.DataSize = Table->TableSize;
156 
157  memcpy(&PartialResourceList->PartialDescriptors[2],
158  Table,
159  Table->TableSize);
160 
161  FldrCreateComponentKey(BusKey,
163  RealModeIrqRoutingTable,
164  0x0,
165  0x0,
166  0xFFFFFFFF,
167  "PCI Real-mode IRQ Routing Table",
168  PartialResourceList,
169  Size,
170  &TableKey);
171  }
172 }
173 
174 
175 VOID
177 {
178  PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
179  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
180  PCI_REGISTRY_INFO BusData;
182  ULONG Size;
184  ULONG i;
185 
186  /* Report the PCI BIOS */
187  if (FindPciBios(&BusData))
188  {
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)
193  {
194  ERR("Failed to allocate resource descriptor\n");
195  return;
196  }
197 
198  /* Initialize resource descriptor */
199  memset(PartialResourceList, 0, Size);
200 
201  /* Create new bus key */
202  FldrCreateComponentKey(SystemKey,
203  AdapterClass,
204  MultiFunctionAdapter,
205  0x0,
206  0x0,
207  0xFFFFFFFF,
208  "PCI BIOS",
209  PartialResourceList,
210  Size,
211  &BiosKey);
212 
213  /* Increment bus number */
214  (*BusNumber)++;
215 
216  DetectPciIrqRoutingTable(BiosKey);
217 
218  /* Report PCI buses */
219  for (i = 0; i < (ULONG)BusData.NoBuses; i++)
220  {
221  /* Check if this is the first bus */
222  if (i == 0)
223  {
224  /* Set 'Configuration Data' value */
226  PartialDescriptors) +
228  sizeof(PCI_REGISTRY_INFO);
229  PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
230  if (!PartialResourceList)
231  {
232  ERR("Failed to allocate resource descriptor\n");
233  return;
234  }
235 
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],
246  &BusData,
247  sizeof(PCI_REGISTRY_INFO));
248  }
249  else
250  {
251  /* Set 'Configuration Data' value */
253  PartialDescriptors);
254  PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
255  if (!PartialResourceList)
256  {
257  ERR("Failed to allocate resource descriptor\n");
258  return;
259  }
260 
261  /* Initialize resource descriptor */
262  memset(PartialResourceList, 0, Size);
263  }
264 
265  /* Create the bus key */
266  FldrCreateComponentKey(SystemKey,
267  AdapterClass,
268  MultiFunctionAdapter,
269  0x0,
270  0x0,
271  0xFFFFFFFF,
272  "PCI",
273  PartialResourceList,
274  Size,
275  &BusKey);
276 
277  /* Increment bus number */
278  (*BusNumber)++;
279  }
280  }
281 }
282 
283 /* EOF */
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
ASMGENDATA Table[]
Definition: genincdata.c:61
#define TRUE
Definition: types.h:120
DBG_DEFAULT_CHANNEL(HWDETECT)
GLint x0
Definition: linetemp.h:95
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
struct _PCI_REGISTRY_INFO PCI_REGISTRY_INFO
UCHAR HardwareMechanism
Definition: pci.h:110
unsigned char ah
Definition: pcbios.h:126
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378::@387 DeviceSpecificData
UCHAR MinorRevision
Definition: pci.h:108
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378 u
static VOID DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey)
Definition: hwpci.c:117
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR
static PPCI_IRQ_ROUTING_TABLE GetPciIrqRoutingTable(VOID)
Definition: hwpci.c:30
BOOLEAN(* FIND_PCI_BIOS)(PPCI_REGISTRY_INFO BusData)
Definition: hardware.h:43
uint32_t ULONG_PTR
Definition: typedefs.h:64
int __cdecl Int386(int ivec, REGS *in, REGS *out)
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
FIND_PCI_BIOS FindPciBios
Definition: hwpci.c:26
UCHAR MajorRevision
Definition: pci.h:107
#define INT386_SUCCESS(regs)
Definition: pcbios.h:173
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: mm.h:163
#define TRACE(s)
Definition: solgame.cpp:4
unsigned char bl
Definition: pcbios.h:128
VOID DetectPciBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
Definition: hwpci.c:176
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
unsigned char cl
Definition: pcbios.h:131
struct _PCI_IRQ_ROUTING_TABLE * PPCI_IRQ_ROUTING_TABLE
BYTEREGS b
Definition: pcbios.h:157
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char al
Definition: pcbios.h:125
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
DWORDREGS d
Definition: pcbios.h:155
VOID NTAPI 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 PCHAR IdentifierString, IN PCM_PARTIAL_RESOURCE_LIST ResourceList, IN ULONG Size, OUT PCONFIGURATION_COMPONENT_DATA *ComponentKey)
Definition: archwsup.c:147
#define ERR(fmt,...)
Definition: debug.h:109
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378::@386 BusNumber
unsigned char bh
Definition: pcbios.h:129
BOOLEAN PcFindPciBios(PPCI_REGISTRY_INFO BusData)
Definition: hwpci.c:80
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
UCHAR NoBuses
Definition: pci.h:109
unsigned int ULONG
Definition: retypes.h:1
Definition: pcbios.h:152
#define CmResourceTypeBusNumber
Definition: hwresource.cpp:128
#define memset(x, y, z)
Definition: compat.h:39
unsigned long edx
Definition: pcbios.h:88
#define TAG_HW_RESOURCE_LIST
Definition: hardware.h:26