ReactOS 0.4.17-dev-966-gf06eace
madt.c File Reference
#include <hal.h>
#include <acpi.h>
#include <smp.h>
#include <debug.h>
Include dependency graph for madt.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static VOID HalpMadtAddProcessor (_In_ ULONG ApicId, _In_ ULONG ProcessorId, _In_ ULONG Flags)
 Adds the processor of a local APIC or local x2APIC entry.
 
static VOID HalpMadtAddIoApic (_In_ ACPI_MADT_IO_APIC *IoApic)
 Records the I/O APIC of an I/O APIC entry.
 
static VOID HalpMadtAddInterruptOverride (_In_ ACPI_MADT_INTERRUPT_OVERRIDE *Override)
 Records the routing of an interrupt source override entry.
 
static VOID HalpMadtParseEntries (_In_ ACPI_TABLE_MADT *MadtTable)
 Walks the interrupt controller entries of the MADT.
 
static VOID HalpMadtPlaceBootProcessor (VOID)
 Moves the boot processor to the first entry, since NT processor numbers follow the entry order.
 
VOID HalpParseApicTables (_In_ PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID HalpPrintApicTables (VOID)
 

Variables

HALP_APIC_INFO_TABLE HalpApicInfoTable
 
PROCESSOR_IDENTITY HalpProcessorIdentity [MAXIMUM_PROCESSORS]
 
ULONG HalpPicVectorRedirect [16]
 
static ULONG HalpMadtIgnoredEntries
 
static BOOLEAN HalpMadtTruncated
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file madt.c.

Function Documentation

◆ HalpMadtAddInterruptOverride()

static VOID HalpMadtAddInterruptOverride ( _In_ ACPI_MADT_INTERRUPT_OVERRIDE *  Override)
static

Records the routing of an interrupt source override entry.

Parameters
[in]OverrideThe interrupt source override entry.

Definition at line 121 of file madt.c.

123{
124 /* Overrides only exist for ISA IRQs */
125 if ((Override->Bus != 0) || (Override->SourceIrq >= RTL_NUMBER_OF(HalpPicVectorRedirect)))
126 {
128 return;
129 }
130
131 HalpPicVectorRedirect[Override->SourceIrq] = Override->GlobalIrq;
132}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
ULONG HalpPicVectorRedirect[16]
Definition: halacpi.c:40
static ULONG HalpMadtIgnoredEntries
Definition: madt.c:29

Referenced by HalpMadtParseEntries().

◆ HalpMadtAddIoApic()

static VOID HalpMadtAddIoApic ( _In_ ACPI_MADT_IO_APIC *  IoApic)
static

Records the I/O APIC of an I/O APIC entry.

Parameters
[in]IoApicThe I/O APIC entry.

Definition at line 94 of file madt.c.

96{
99
100 /* Keep the first unit when an ID is duplicated, because apparently this happens on Dell PowerEdge's sometimes. */
101 if ((IoApic->Address == 0) || (HalpApicInfoTable.IoApicPA[IoApic->Id] != 0))
102 {
104 return;
105 }
106
107 HalpApicInfoTable.IoApicPA[IoApic->Id] = IoApic->Address;
108 HalpApicInfoTable.IoApicIrqBase[IoApic->Id] = IoApic->GlobalIrqBase;
110}
DWORD Id
#define C_ASSERT(e)
Definition: intsafe.h:73
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
HALP_APIC_INFO_TABLE HalpApicInfoTable
Definition: madt.c:22
#define RTL_NUMBER_OF_FIELD(type, field)
Definition: ntbasedef.h:715
ULONG IoApicPA[HALP_APIC_INFO_TABLE_IOAPIC_NUMBER]
Definition: smp.h:31
ULONG IOAPICCount
Definition: smp.h:28
ULONG IoApicIrqBase[HALP_APIC_INFO_TABLE_IOAPIC_NUMBER]
Definition: smp.h:32

Referenced by HalpMadtParseEntries().

◆ HalpMadtAddProcessor()

static VOID HalpMadtAddProcessor ( _In_ ULONG  ApicId,
_In_ ULONG  ProcessorId,
_In_ ULONG  Flags 
)
static

Adds the processor of a local APIC or local x2APIC entry.

Parameters
[in]ApicIdLocal APIC ID of the processor.
[in]ProcessorIdACPI processor ID of the processor.
[in]FlagsLocal APIC flags of the entry.

Definition at line 49 of file madt.c.

53{
55
56 if (!(Flags & ACPI_MADT_ENABLED))
57 return;
58
59 /* TODO: LapicId holds 8 bits, and 0xFF is the broadcast ID, we eventually want to support x2APIC however. */
60 if (ApicId >= 0xFF)
61 {
63 return;
64 }
65
66 /* Firmware can describe a processor with both a local APIC and a local x2APIC entry */
68 {
69 if (HalpProcessorIdentity[Index].LapicId == ApicId)
70 return;
71 }
72
74 {
76 return;
77 }
78
79 /* FIXME: Only extend tracking when we get x2APIC support */
83}
#define ACPI_MADT_ENABLED
Definition: actbl2.h:1455
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
PROCESSOR_IDENTITY HalpProcessorIdentity[MAXIMUM_PROCESSORS]
Definition: madt.c:24
ULONG ProcessorCount
Definition: smp.h:27
ULONG ProcessorId
Definition: smp.h:13
ULONG LapicId
Definition: smp.h:14
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ typedef _In_ ULONG ApicId
Definition: iotypes.h:1105

Referenced by HalpMadtParseEntries().

◆ HalpMadtParseEntries()

static VOID HalpMadtParseEntries ( _In_ ACPI_TABLE_MADT *  MadtTable)
static

Walks the interrupt controller entries of the MADT.

Parameters
[in]MadtTableThe MADT, with a header already validated.

Definition at line 143 of file madt.c.

145{
147 ULONG_PTR TableEnd;
148
149 TableEnd = (ULONG_PTR)MadtTable + MadtTable->Header.Length;
150 Entry = (ACPI_SUBTABLE_HEADER *)(MadtTable + 1);
151
152 while ((ULONG_PTR)Entry < TableEnd)
153 {
154 if (((ULONG_PTR)(Entry + 1) > TableEnd) ||
155 (Entry->Length < sizeof(*Entry)) ||
156 ((ULONG_PTR)Entry + Entry->Length > TableEnd))
157 {
159 return;
160 }
161
162 switch (Entry->Type)
163 {
165 {
167
168 if (Entry->Length < sizeof(*LocalApic))
169 {
171 break;
172 }
173
174 HalpMadtAddProcessor(LocalApic->Id,
175 LocalApic->ProcessorId,
176 LocalApic->LapicFlags);
177 break;
178 }
179
181 {
183
184 if (Entry->Length < sizeof(*LocalX2Apic))
185 {
187 break;
188 }
189
191 LocalX2Apic->Uid,
192 LocalX2Apic->LapicFlags);
193 break;
194 }
195
197 {
198 if (Entry->Length < sizeof(ACPI_MADT_IO_APIC))
199 {
201 break;
202 }
203
205 break;
206 }
207
209 {
210 if (Entry->Length < sizeof(ACPI_MADT_INTERRUPT_OVERRIDE))
211 {
213 break;
214 }
215
217 break;
218 }
219
220 /* Other types, including reserved and OEM ones, are skipped */
221 default:
222 break;
223 }
224
226 }
227}
@ ACPI_MADT_TYPE_IO_APIC
Definition: actbl2.h:1006
@ ACPI_MADT_TYPE_LOCAL_X2APIC
Definition: actbl2.h:1014
@ ACPI_MADT_TYPE_INTERRUPT_OVERRIDE
Definition: actbl2.h:1007
@ ACPI_MADT_TYPE_LOCAL_APIC
Definition: actbl2.h:1005
#define TRUE
Definition: types.h:120
#define ULONG_PTR
Definition: config.h:101
static VOID HalpMadtAddIoApic(_In_ ACPI_MADT_IO_APIC *IoApic)
Records the I/O APIC of an I/O APIC entry.
Definition: madt.c:94
static VOID HalpMadtAddProcessor(_In_ ULONG ApicId, _In_ ULONG ProcessorId, _In_ ULONG Flags)
Adds the processor of a local APIC or local x2APIC entry.
Definition: madt.c:49
static BOOLEAN HalpMadtTruncated
Definition: madt.c:30
static VOID HalpMadtAddInterruptOverride(_In_ ACPI_MADT_INTERRUPT_OVERRIDE *Override)
Records the routing of an interrupt source override entry.
Definition: madt.c:121
Entry
Definition: section.c:5216
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by HalpParseApicTables().

◆ HalpMadtPlaceBootProcessor()

static VOID HalpMadtPlaceBootProcessor ( VOID  )
static

Moves the boot processor to the first entry, since NT processor numbers follow the entry order.

Remarks
When the MADT does not describe the boot processor, only the boot processor is kept so that no other processor is started.

Definition at line 240 of file madt.c.

241{
242 PROCESSOR_IDENTITY BootProcessor;
243 ULONG Index;
244 UCHAR BootApicId;
245
246 /* The kernel fills this from CPUID before initializing the processor with the HAL */
247 BootApicId = (UCHAR)KeGetCurrentPrcb()->InitialApicId;
248
250 {
251 if (HalpProcessorIdentity[Index].LapicId == BootApicId)
252 break;
253 }
254
256 {
257 /* The MADT is missing the boot processor, so we can't trust it and only run the boot processor */
258 RtlZeroMemory(&BootProcessor, sizeof(BootProcessor));
259 BootProcessor.LapicId = BootApicId;
261 }
262 else
263 {
264 /* A conforming MADT lists the boot processor first, so this only moves entries on non-conforming ones */
265 BootProcessor = HalpProcessorIdentity[Index];
268 Index * sizeof(BootProcessor));
269 }
270
271 BootProcessor.BSPCheck = TRUE;
272 HalpProcessorIdentity[0] = BootProcessor;
273}
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1197
BOOLEAN BSPCheck
Definition: smp.h:16
unsigned char UCHAR
Definition: typedefs.h:53
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by HalpParseApicTables().

◆ HalpParseApicTables()

VOID HalpParseApicTables ( _In_ PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 276 of file madt.c.

278{
279 ACPI_TABLE_MADT *MadtTable;
280
281 MadtTable = HalAcpiGetTable(LoaderBlock, APIC_SIGNATURE);
282 if (MadtTable && (MadtTable->Header.Length >= sizeof(*MadtTable)))
283 {
285 HalpMadtParseEntries(MadtTable);
286 }
287 else
288 {
290 }
291
293}
PVOID NTAPI HalAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN ULONG Signature)
Definition: halacpi.c:446
static VOID HalpMadtParseEntries(_In_ ACPI_TABLE_MADT *MadtTable)
Walks the interrupt controller entries of the MADT.
Definition: madt.c:143
static VOID HalpMadtPlaceBootProcessor(VOID)
Moves the boot processor to the first entry, since NT processor numbers follow the entry order.
Definition: madt.c:240
#define APIC_SIGNATURE
Definition: acpi.h:33
ULONG LocalApicPA
Definition: smp.h:29
UINT32 Length
Definition: actbl.h:109
ACPI_TABLE_HEADER Header
Definition: actbl2.h:985
UINT32 Address
Definition: actbl2.h:986

Referenced by HalpInitProcessor().

◆ HalpPrintApicTables()

VOID HalpPrintApicTables ( VOID  )

Definition at line 296 of file madt.c.

297{
298#if DBG
299 ULONG i;
300
301 DPRINT1("Physical processor count: %lu\n", HalpApicInfoTable.ProcessorCount);
302 for (i = 0; i < HalpApicInfoTable.ProcessorCount; i++)
303 {
304 DPRINT1(" Processor %lu: ProcessorId %u, LapicId %u, ProcessorStarted %u, BSPCheck %u, ProcessorPrcb %p\n",
305 i,
306 HalpProcessorIdentity[i].ProcessorId,
307 HalpProcessorIdentity[i].LapicId,
308 HalpProcessorIdentity[i].ProcessorStarted,
309 HalpProcessorIdentity[i].BSPCheck,
310 HalpProcessorIdentity[i].ProcessorPrcb);
311 }
312
314 {
315 if (HalpApicInfoTable.IoApicPA[i] != 0)
316 {
317 DPRINT1(" I/O APIC %lu: Address 0x%08lx, GlobalIrqBase %lu\n",
318 i,
321 }
322 }
323
325 {
326 DPRINT1("MADT missing or malformed: %u, entries ignored: %lu\n",
329 }
330#endif
331}
#define DPRINT1
Definition: precomp.h:8
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 HALP_APIC_INFO_TABLE_IOAPIC_NUMBER
Definition: smp.h:23

Referenced by HalpInitPhase0().

Variable Documentation

◆ HalpApicInfoTable

◆ HalpMadtIgnoredEntries

ULONG HalpMadtIgnoredEntries
static

◆ HalpMadtTruncated

BOOLEAN HalpMadtTruncated
static

Definition at line 30 of file madt.c.

Referenced by HalpMadtParseEntries(), HalpParseApicTables(), and HalpPrintApicTables().

◆ HalpPicVectorRedirect

ULONG HalpPicVectorRedirect[16]
extern

Definition at line 40 of file halacpi.c.

Referenced by HalpBuildAcpiResourceList(), and HalpMadtAddInterruptOverride().

◆ HalpProcessorIdentity