ReactOS 0.4.17-dev-1190-g4c812f4
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 and polarity 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 [HALP_ISA_IRQ_COUNT]
 
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 and polarity of an interrupt source override entry.

Parameters
[in]OverrideThe interrupt source override entry.

Definition at line 122 of file madt.c.

124{
125 ULONG Irq = Override->SourceIrq;
126
127 /* Overrides only exist for ISA IRQs */
128 if ((Override->Bus != 0) || (Irq >= HALP_ISA_IRQ_COUNT))
129 {
131 return;
132 }
133
134 HalpPicVectorRedirect[Irq] = Override->GlobalIrq;
135 HalpApicInfoTable.IsaIrqGsi[Irq] = Override->GlobalIrq;
136
137 switch (Override->IntiFlags & ACPI_MADT_POLARITY_MASK)
138 {
141 break;
142
145 break;
146
147 default:
149 break;
150 }
151}
#define ACPI_MADT_POLARITY_ACTIVE_HIGH
Definition: actbl2.h:1466
#define ACPI_MADT_POLARITY_ACTIVE_LOW
Definition: actbl2.h:1468
#define ACPI_MADT_POLARITY_MASK
Definition: actbl2.h:1460
ULONG HalpPicVectorRedirect[HALP_ISA_IRQ_COUNT]
Definition: halacpi.c:40
static ULONG HalpMadtIgnoredEntries
Definition: madt.c:30
HALP_APIC_INFO_TABLE HalpApicInfoTable
Definition: misc.c:19
#define HALP_ISA_IRQ_COUNT
Definition: smp.h:24
ULONG IsaIrqGsi[HALP_ISA_IRQ_COUNT]
Definition: smp.h:34
KINTERRUPT_POLARITY IsaIrqPolarity[HALP_ISA_IRQ_COUNT]
Definition: smp.h:35
uint32_t ULONG
Definition: typedefs.h:59
@ InterruptActiveLow
Definition: ketypes.h:435
@ InterruptPolarityUnknown
Definition: ketypes.h:433
@ InterruptActiveHigh
Definition: ketypes.h:434

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 95 of file madt.c.

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

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 50 of file madt.c.

54{
56
57 if (!(Flags & ACPI_MADT_ENABLED))
58 return;
59
60 /* TODO: LapicId holds 8 bits, and 0xFF is the broadcast ID, we eventually want to support x2APIC however. */
61 if (ApicId >= 0xFF)
62 {
64 return;
65 }
66
67 /* Firmware can describe a processor with both a local APIC and a local x2APIC entry */
69 {
70 if (HalpProcessorIdentity[Index].LapicId == ApicId)
71 return;
72 }
73
75 {
77 return;
78 }
79
80 /* FIXME: Only extend tracking when we get x2APIC support */
84}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#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:25
ULONG ProcessorCount
Definition: smp.h:28
ULONG ProcessorId
Definition: smp.h:13
ULONG LapicId
Definition: smp.h:14
_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 162 of file madt.c.

164{
166 ULONG_PTR TableEnd;
167
168 TableEnd = (ULONG_PTR)MadtTable + MadtTable->Header.Length;
169 Entry = (ACPI_SUBTABLE_HEADER *)(MadtTable + 1);
170
171 while ((ULONG_PTR)Entry < TableEnd)
172 {
173 if (((ULONG_PTR)(Entry + 1) > TableEnd) ||
174 (Entry->Length < sizeof(*Entry)) ||
175 ((ULONG_PTR)Entry + Entry->Length > TableEnd))
176 {
178 return;
179 }
180
181 switch (Entry->Type)
182 {
184 {
186
187 if (Entry->Length < sizeof(*LocalApic))
188 {
190 break;
191 }
192
193 HalpMadtAddProcessor(LocalApic->Id,
194 LocalApic->ProcessorId,
195 LocalApic->LapicFlags);
196 break;
197 }
198
200 {
202
203 if (Entry->Length < sizeof(*LocalX2Apic))
204 {
206 break;
207 }
208
210 LocalX2Apic->Uid,
211 LocalX2Apic->LapicFlags);
212 break;
213 }
214
216 {
217 if (Entry->Length < sizeof(ACPI_MADT_IO_APIC))
218 {
220 break;
221 }
222
224 break;
225 }
226
228 {
229 if (Entry->Length < sizeof(ACPI_MADT_INTERRUPT_OVERRIDE))
230 {
232 break;
233 }
234
236 break;
237 }
238
239 /* Other types, including reserved and OEM ones, are skipped */
240 default:
241 break;
242 }
243
245 }
246}
@ 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:95
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:50
static BOOLEAN HalpMadtTruncated
Definition: madt.c:31
static VOID HalpMadtAddInterruptOverride(_In_ ACPI_MADT_INTERRUPT_OVERRIDE *Override)
Records the routing and polarity of an interrupt source override entry.
Definition: madt.c:122
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 259 of file madt.c.

260{
261 PROCESSOR_IDENTITY BootProcessor;
262 ULONG Index;
263 UCHAR BootApicId;
264
265 /* The kernel fills this from CPUID before initializing the processor with the HAL */
266 BootApicId = (UCHAR)KeGetCurrentPrcb()->InitialApicId;
267
269 {
270 if (HalpProcessorIdentity[Index].LapicId == BootApicId)
271 break;
272 }
273
275 {
276 /* The MADT is missing the boot processor, so we can't trust it and only run the boot processor */
277 RtlZeroMemory(&BootProcessor, sizeof(BootProcessor));
278 BootProcessor.LapicId = BootApicId;
280 }
281 else
282 {
283 /* A conforming MADT lists the boot processor first, so this only moves entries on non-conforming ones */
284 BootProcessor = HalpProcessorIdentity[Index];
287 Index * sizeof(BootProcessor));
288 }
289
290 BootProcessor.BSPCheck = TRUE;
291 HalpProcessorIdentity[0] = BootProcessor;
292}
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 295 of file madt.c.

297{
298 ACPI_TABLE_MADT *MadtTable;
299
300 MadtTable = HalAcpiGetTable(LoaderBlock, APIC_SIGNATURE);
301 if (MadtTable && (MadtTable->Header.Length >= sizeof(*MadtTable)))
302 {
304 HalpMadtParseEntries(MadtTable);
305 }
306 else
307 {
309 }
310
312}
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:162
static VOID HalpMadtPlaceBootProcessor(VOID)
Moves the boot processor to the first entry, since NT processor numbers follow the entry order.
Definition: madt.c:259
#define APIC_SIGNATURE
Definition: acpi.h:33
ULONG LocalApicPA
Definition: smp.h:30
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 315 of file madt.c.

316{
317#if DBG
318 ULONG i;
319
320 DPRINT1("Physical processor count: %lu\n", HalpApicInfoTable.ProcessorCount);
321 for (i = 0; i < HalpApicInfoTable.ProcessorCount; i++)
322 {
323 DPRINT1(" Processor %lu: ProcessorId %u, LapicId %u, ProcessorStarted %u, BSPCheck %u, ProcessorPrcb %p\n",
324 i,
325 HalpProcessorIdentity[i].ProcessorId,
326 HalpProcessorIdentity[i].LapicId,
327 HalpProcessorIdentity[i].ProcessorStarted,
328 HalpProcessorIdentity[i].BSPCheck,
329 HalpProcessorIdentity[i].ProcessorPrcb);
330 }
331
333 {
334 if (HalpApicInfoTable.IoApicPA[i] != 0)
335 {
336 DPRINT1(" I/O APIC %lu: Address 0x%08lx, GlobalIrqBase %lu\n",
337 i,
340 }
341 }
342
344 {
345 DPRINT1("MADT missing or malformed: %u, entries ignored: %lu\n",
348 }
349#endif
350}
#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 31 of file madt.c.

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

◆ HalpPicVectorRedirect

ULONG HalpPicVectorRedirect[HALP_ISA_IRQ_COUNT]
extern

Definition at line 40 of file halacpi.c.

Referenced by HalpBuildAcpiResourceList(), and HalpMadtAddInterruptOverride().

◆ HalpProcessorIdentity