ReactOS 0.4.17-dev-934-g091855f
hwpci.c
Go to the documentation of this file.
1/*
2 * PROJECT: FreeLoader
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: PCI BIOS detection routines
5 * COPYRIGHT: Copyright 2004 Eric Kohl <eric.kohl@reactos.org>
6 */
7
8#include <freeldr.h>
9
10#include <debug.h>
12
13/*
14 * Specification:
15 * - https://pcisig.com/PCIConventional/Specs/Firmware/Bios_2.1
16 * - http://www.o3one.org/hwdocs/bios_doc/pci_bios_21.pdf
17 * - https://hackipedia.org/browse.cgi/Computer/Platform/PC,%20IBM%20compatible/Busses/PCI/BIOS
18 */
19static
23{
24 REGS RegsIn;
25 REGS RegsOut;
26
27 RegsIn.b.ah = 0xB1; /* Subfunction B1h */
28 RegsIn.b.al = 0x01; /* PCI BIOS present */
29
30 Int386(0x1A, &RegsIn, &RegsOut);
31
32 if (INT386_SUCCESS(RegsOut) &&
33 (RegsOut.d.edx == ' ICP') &&
34 (RegsOut.b.ah == 0))
35 {
36 TRACE("Found PCI BIOS\n");
37
38 TRACE("AL: %x\n", RegsOut.b.al);
39 TRACE("BH: %x\n", RegsOut.b.bh);
40 TRACE("BL: %x\n", RegsOut.b.bl);
41 TRACE("CL: %x\n", RegsOut.b.cl);
42
43 BusData->MajorRevision = RegsOut.b.bh;
44 BusData->MinorRevision = RegsOut.b.bl;
45 BusData->NoBuses = RegsOut.b.cl + 1;
46 BusData->HardwareMechanism = RegsOut.b.al;
47 return TRUE;
48 }
49
50 TRACE("No PCI BIOS found\n");
51 return FALSE;
52}
53
54/*
55 * NOTE: The PCI IRQ Routing Table is a legacy pre-ACPI mechanism that serves
56 * to dynamically route PCI interrupts to interrupt requests (IRQs)[^1][^2][^3].
57 * On the other hand, on ACPI-aware systems, ACPI-specific methods are used[^4][^5].
58 *
59 * References:
60 * [^1]: https://web.archive.org/web/20101230191251/https://www.microsoft.com/whdc/archive/pciirq.mspx
61 * [^2]: https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/182604
62 * [^3]: https://lisans.cozum.info.tr/networking/Interrupt%20sharing%20on%20PCI-devices.htm
63 * [^4]: https://web.archive.org/web/20111012153449/http://msdn.microsoft.com/en-us/windows/hardware/gg454523
64 * [^5]: https://github.com/jaykhandkar/pci-interrupt-routing
65 */
66static
69{
71 PUCHAR Ptr;
72 ULONG Sum;
73 ULONG i;
74
76 while ((ULONG_PTR)Table < 0x100000)
77 {
78 if (Table->Signature == 'RIP$')
79 {
80 TRACE("Found signature\n");
81
82 if (Table->TableSize < FIELD_OFFSET(PCI_IRQ_ROUTING_TABLE, Slot) ||
83 Table->TableSize % 16 != 0)
84 {
85 ERR("Invalid routing table size (%u) at 0x%p. Continue searching...\n", Table->TableSize, Table);
87 continue;
88 }
89
90 Ptr = (PUCHAR)Table;
91 Sum = 0;
92 for (i = 0; i < Table->TableSize; i++)
93 {
94 Sum += Ptr[i];
95 }
96
97 if ((Sum & 0xFF) != 0)
98 {
99 ERR("Invalid routing table checksum (%#lx) at 0x%p. Continue searching...\n", Sum & 0xFF, Table);
100 }
101 else
102 {
103 TRACE("Valid checksum (%#lx): found routing table at 0x%p\n", Sum & 0xFF, Table);
104 return Table;
105 }
106 }
107
109 }
110
111 ERR("No valid routing table found!\n");
112
113 return NULL;
114}
115
116static
117VOID
120{
122 PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
123 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
125 ULONG Size;
126
128 if (!Table)
129 return;
130
131 TRACE("Table size: %u\n", Table->TableSize);
132
133 /* Set 'Configuration Data' value */
134 Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors[2]) + Table->TableSize;
135 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
136 if (PartialResourceList == NULL)
137 {
138 ERR("Failed to allocate resource descriptor\n");
139 return;
140 }
141
142 /* Initialize resource descriptor */
143 RtlZeroMemory(PartialResourceList, Size);
144 PartialResourceList->Version = 1;
145 PartialResourceList->Revision = 1;
146 PartialResourceList->Count = 2;
147
148 PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
149 PartialDescriptor->Type = CmResourceTypeBusNumber;
151 PartialDescriptor->u.BusNumber.Start = 0;
152 PartialDescriptor->u.BusNumber.Length = 1;
153
154 PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
155 PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
157 PartialDescriptor->u.DeviceSpecificData.DataSize = Table->TableSize;
158
159 RtlCopyMemory(&PartialResourceList->PartialDescriptors[2],
160 Table, Table->TableSize);
161
165 0,
166 0,
167 0xFFFFFFFF,
168 "PCI Real-mode IRQ Routing Table",
169 PartialResourceList,
170 Size,
171 &TableKey);
172}
173
179{
180 PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
182 ULONG Size;
183
184 /* Report the PCI BIOS */
185 if (!PcFindPciBios(BusData))
186 return FALSE;
187
188 /* Set 'Configuration Data' value */
189 Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
190 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
191 if (PartialResourceList == NULL)
192 {
193 ERR("Failed to allocate resource descriptor\n");
194 return FALSE;
195 }
196
197 /* Initialize resource descriptor */
198 RtlZeroMemory(PartialResourceList, Size);
199
200 /* Create new bus key */
201 FldrCreateComponentKey(SystemKey,
204 0,
205 0,
206 0xFFFFFFFF,
207 "PCI BIOS",
208 PartialResourceList,
209 Size,
210 &BiosKey);
211
212 /* Increment bus number */
213 (*BusNumber)++;
214
216 return TRUE;
217}
218
219/* 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:68
static BOOLEAN PcFindPciBios(_Out_ PPCI_REGISTRY_INFO BusData)
Definition: hwpci.c:21
static VOID DetectPciIrqRoutingTable(_In_ PCONFIGURATION_COMPONENT_DATA BusKey)
Definition: hwpci.c:118
BOOLEAN PcDetectPciBus(_In_ PCONFIGURATION_COMPONENT_DATA SystemKey, _Inout_ PULONG BusNumber, _Out_ PPCI_REGISTRY_INFO BusData)
Definition: hwpci.c:175
#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 _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define INT386_SUCCESS(regs)
Definition: pcbios.h:181
int __cdecl Int386(int ivec, REGS *in, REGS *out)
_In_ ULONG BusNumber
Definition: pciidex.h:65
#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::@486::@494 BusNumber
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@486::@495 DeviceSpecificData
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@486 u
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: restypes.h:100
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