]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
ShellPkg: Adds Local APIC parser to AcpiView
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Madt / MadtParser.c
CommitLineData
a6eaba4d 1/** @file\r
ee4dc24f
RN
2 MADT table parser\r
3\r
b8504826 4 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.\r
d5fd86f2 5 Copyright (c) 2022, AMD Incorporated. All rights reserved.\r
56ba3746 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
ee4dc24f
RN
7\r
8 @par Reference(s):\r
8a08dc54
KK
9 - ACPI 6.3 Specification - January 2019\r
10 - Arm Generic Interrupt Controller Architecture Specification,\r
11 GIC architecture version 3 and version 4, issue E\r
12 - Arm Server Base System Architecture 5.0\r
ee4dc24f
RN
13**/\r
14\r
15#include <IndustryStandard/Acpi.h>\r
16#include <Library/UefiLib.h>\r
17#include "AcpiParser.h"\r
18#include "AcpiTableParser.h"\r
e18ac66d 19#include "AcpiViewConfig.h"\r
8a08dc54 20#include "MadtParser.h"\r
ee4dc24f
RN
21\r
22// Local Variables\r
47d20b54
MK
23STATIC CONST UINT8 *MadtInterruptControllerType;\r
24STATIC CONST UINT8 *MadtInterruptControllerLength;\r
25STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
ee4dc24f 26\r
a6eaba4d
DB
27/**\r
28 This function validates the System Vector Base in the GICD.\r
29\r
30 @param [in] Ptr Pointer to the start of the field data.\r
31 @param [in] Context Pointer to context specific information e.g. this\r
32 could be a pointer to the ACPI table header.\r
33**/\r
ee4dc24f
RN
34STATIC\r
35VOID\r
36EFIAPI\r
37ValidateGICDSystemVectorBase (\r
47d20b54
MK
38 IN UINT8 *Ptr,\r
39 IN VOID *Context\r
40 )\r
9cb5bcce 41{\r
47d20b54 42 if (*(UINT32 *)Ptr != 0) {\r
9cb5bcce
KK
43 IncrementErrorCount ();\r
44 Print (\r
45 L"\nERROR: System Vector Base must be zero."\r
47d20b54 46 );\r
9cb5bcce
KK
47 }\r
48}\r
ee4dc24f 49\r
8a08dc54
KK
50/**\r
51 This function validates the SPE Overflow Interrupt in the GICC.\r
52\r
53 @param [in] Ptr Pointer to the start of the field data.\r
54 @param [in] Context Pointer to context specific information e.g. this\r
55 could be a pointer to the ACPI table header.\r
56**/\r
57STATIC\r
58VOID\r
59EFIAPI\r
60ValidateSpeOverflowInterrupt (\r
47d20b54
MK
61 IN UINT8 *Ptr,\r
62 IN VOID *Context\r
9cb5bcce
KK
63 )\r
64{\r
47d20b54 65 UINT16 SpeOverflowInterrupt;\r
9cb5bcce 66\r
47d20b54 67 SpeOverflowInterrupt = *(UINT16 *)Ptr;\r
9cb5bcce
KK
68\r
69 // SPE not supported by this processor\r
70 if (SpeOverflowInterrupt == 0) {\r
71 return;\r
72 }\r
73\r
74 if ((SpeOverflowInterrupt < ARM_PPI_ID_MIN) ||\r
75 ((SpeOverflowInterrupt > ARM_PPI_ID_MAX) &&\r
76 (SpeOverflowInterrupt < ARM_PPI_ID_EXTENDED_MIN)) ||\r
47d20b54
MK
77 (SpeOverflowInterrupt > ARM_PPI_ID_EXTENDED_MAX))\r
78 {\r
9cb5bcce
KK
79 IncrementErrorCount ();\r
80 Print (\r
81 L"\nERROR: SPE Overflow Interrupt ID of %d is not in the allowed PPI ID "\r
47d20b54 82 L"ranges of %d-%d or %d-%d (for GICv3.1 or later).",\r
9cb5bcce
KK
83 SpeOverflowInterrupt,\r
84 ARM_PPI_ID_MIN,\r
85 ARM_PPI_ID_MAX,\r
86 ARM_PPI_ID_EXTENDED_MIN,\r
87 ARM_PPI_ID_EXTENDED_MAX\r
47d20b54 88 );\r
9cb5bcce 89 } else if (SpeOverflowInterrupt != ARM_PPI_ID_PMBIRQ) {\r
47d20b54 90 IncrementWarningCount ();\r
9cb5bcce
KK
91 Print (\r
92 L"\nWARNING: SPE Overflow Interrupt ID of %d is not compliant with SBSA "\r
47d20b54 93 L"Level 3 PPI ID assignment: %d.",\r
9cb5bcce
KK
94 SpeOverflowInterrupt,\r
95 ARM_PPI_ID_PMBIRQ\r
47d20b54 96 );\r
9cb5bcce
KK
97 }\r
98}\r
8a08dc54 99\r
a6eaba4d
DB
100/**\r
101 An ACPI_PARSER array describing the GICC Interrupt Controller Structure.\r
102**/\r
47d20b54
MK
103STATIC CONST ACPI_PARSER GicCParser[] = {\r
104 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
105 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
106 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
107\r
108 { L"CPU Interface Number", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
109 { L"ACPI Processor UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },\r
110 { L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },\r
111 { L"Parking Protocol Version", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },\r
112\r
113 { L"Performance Interrupt GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },\r
114 { L"Parked Address", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },\r
115 { L"Physical Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },\r
116 { L"GICV", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL },\r
117 { L"GICH", 8, 48, L"0x%lx", NULL, NULL, NULL, NULL },\r
118 { L"VGIC Maintenance interrupt", 4, 56, L"0x%x", NULL, NULL, NULL, NULL },\r
119 { L"GICR Base Address", 8, 60, L"0x%lx", NULL, NULL, NULL, NULL },\r
120 { L"MPIDR", 8, 68, L"0x%lx", NULL, NULL, NULL, NULL },\r
121 { L"Processor Power Efficiency Class", 1, 76, L"0x%x", NULL, NULL, NULL,\r
122 NULL },\r
123 { L"Reserved", 1, 77, L"0x%x", NULL, NULL, NULL, NULL },\r
124 { L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL,\r
125 ValidateSpeOverflowInterrupt, NULL }\r
ee4dc24f
RN
126};\r
127\r
a6eaba4d
DB
128/**\r
129 An ACPI_PARSER array describing the GICD Interrupt Controller Structure.\r
130**/\r
47d20b54
MK
131STATIC CONST ACPI_PARSER GicDParser[] = {\r
132 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
133 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
134 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
135\r
136 { L"GIC ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
137 { L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },\r
138 { L"System Vector Base", 4, 16, L"0x%x", NULL, NULL,\r
139 ValidateGICDSystemVectorBase, NULL },\r
140 { L"GIC Version", 1, 20, L"%d", NULL, NULL, NULL, NULL },\r
141 { L"Reserved", 3, 21, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }\r
ee4dc24f
RN
142};\r
143\r
a6eaba4d
DB
144/**\r
145 An ACPI_PARSER array describing the MSI Frame Interrupt Controller Structure.\r
146**/\r
47d20b54
MK
147STATIC CONST ACPI_PARSER GicMSIFrameParser[] = {\r
148 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
149 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
150 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
ee4dc24f 151\r
47d20b54
MK
152 { L"MSI Frame ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
153 { L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },\r
154 { L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },\r
ee4dc24f 155\r
47d20b54
MK
156 { L"SPI Count", 2, 20, L"%d", NULL, NULL, NULL, NULL },\r
157 { L"SPI Base", 2, 22, L"0x%x", NULL, NULL, NULL, NULL }\r
ee4dc24f
RN
158};\r
159\r
a6eaba4d
DB
160/**\r
161 An ACPI_PARSER array describing the GICR Interrupt Controller Structure.\r
162**/\r
47d20b54
MK
163STATIC CONST ACPI_PARSER GicRParser[] = {\r
164 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
165 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
166 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
167\r
168 { L"Discovery Range Base Address", 8, 4, L"0x%lx", NULL, NULL, NULL,\r
169 NULL },\r
170 { L"Discovery Range Length", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }\r
ee4dc24f
RN
171};\r
172\r
a6eaba4d
DB
173/**\r
174 An ACPI_PARSER array describing the GIC ITS Interrupt Controller Structure.\r
175**/\r
47d20b54
MK
176STATIC CONST ACPI_PARSER GicITSParser[] = {\r
177 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
178 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
179 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
180\r
181 { L"GIC ITS ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
182 { L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },\r
183 { L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL }\r
ee4dc24f
RN
184};\r
185\r
2f286930
ALA
186/**\r
187 An ACPI_PARSER array describing the IO APIC Structure.\r
188**/\r
47d20b54
MK
189STATIC CONST ACPI_PARSER IoApic[] = {\r
190 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
191 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
192 { L"I/O APIC ID", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
193 { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },\r
194 { L"I/O APIC Address", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
195 { L"Global System Interrupt Base", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }\r
2f286930
ALA
196};\r
197\r
198/**\r
199 An ACPI_PARSER array describing the Interrupt Source Override Structure.\r
200**/\r
47d20b54
MK
201STATIC CONST ACPI_PARSER InterruptSourceOverride[] = {\r
202 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
203 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
204 { L"Bus", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
205 { L"Source", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },\r
206 { L"Global System Interrupt", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
207 { L"Flags", 2, 8, L"0x%x", NULL, NULL, NULL, NULL }\r
2f286930
ALA
208};\r
209\r
d5fd86f2
ALA
210STATIC CONST ACPI_PARSER LocalApicFlags[] = {\r
211 { L"Enabled", 1, 0, L"%d", NULL, NULL, NULL, NULL },\r
212 { L"Online Capable", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
213 { L"Reserved", 30, 2, L"%d", NULL, NULL, NULL, NULL }\r
214};\r
215\r
216/**\r
217 This function traces Bit Flags fields.\r
218 If no format string is specified the Format must be NULL.\r
219\r
220 @param [in] Format Optional format string for tracing the data.\r
221 @param [in] Ptr Pointer to the start of the buffer.\r
222**/\r
223VOID\r
224EFIAPI\r
225DumpLocalApicBitFlags (\r
226 IN CONST CHAR16 *Format OPTIONAL,\r
227 IN UINT8 *Ptr\r
228 )\r
229{\r
230 if (Format != NULL) {\r
231 Print (Format, *(UINT32 *)Ptr);\r
232 return;\r
233 }\r
234\r
235 Print (L"0x%X\n", *(UINT32 *)Ptr);\r
236 ParseAcpiBitFields (\r
237 TRUE,\r
238 2,\r
239 NULL,\r
240 Ptr,\r
241 4,\r
242 PARSER_PARAMS (LocalApicFlags)\r
243 );\r
244}\r
245\r
246/**\r
247 An ACPI_PARSER array describing the Processor Local APIC Structure.\r
248 **/\r
249STATIC CONST ACPI_PARSER ProcessorLocalApic[] = {\r
250 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
251 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
252\r
253 { L"ACPI Processor UID", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
254 { L"APIC ID", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },\r
255 { L"Flags", 4, 4, NULL, DumpLocalApicBitFlags, NULL, NULL, NULL }\r
256};\r
257\r
2f286930
ALA
258/**\r
259 An ACPI_PARSER array describing the Processor Local x2APIC Structure.\r
260**/\r
47d20b54 261STATIC CONST ACPI_PARSER ProcessorLocalX2Apic[] = {\r
d5fd86f2
ALA
262 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
263 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
264 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
47d20b54 265\r
d5fd86f2
ALA
266 { L"X2APIC ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
267 { L"Flags", 4, 8, NULL, DumpLocalApicBitFlags, NULL, NULL, NULL },\r
268 { L"ACPI Processor UID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }\r
2f286930
ALA
269};\r
270\r
271/**\r
272 An ACPI_PARSER array describing the Local x2APIC NMI Structure.\r
273**/\r
47d20b54
MK
274STATIC CONST ACPI_PARSER LocalX2ApicNmi[] = {\r
275 { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
276 { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },\r
277 { L"Flags", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
278\r
279 { L"ACPI Processor UID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
280 { L"Local x2APIC LINT#", 1, 8, L"0x%x", NULL, NULL, NULL, NULL },\r
281 { L"Reserved", 3, 9, L"0x%x%x%x", Dump3Chars, NULL, NULL, NULL }\r
2f286930
ALA
282};\r
283\r
a6eaba4d
DB
284/**\r
285 An ACPI_PARSER array describing the ACPI MADT Table.\r
286**/\r
47d20b54 287STATIC CONST ACPI_PARSER MadtParser[] = {\r
ee4dc24f 288 PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
47d20b54
MK
289 { L"Local Interrupt Controller Address",4, 36, L"0x%x", NULL, NULL, NULL,\r
290 NULL },\r
291 { L"Flags", 4, 40, L"0x%x", NULL, NULL, NULL,NULL}\r
ee4dc24f
RN
292};\r
293\r
a6eaba4d
DB
294/**\r
295 An ACPI_PARSER array describing the MADT Interrupt Controller Structure Header Structure.\r
296**/\r
47d20b54
MK
297STATIC CONST ACPI_PARSER MadtInterruptControllerHeaderParser[] = {\r
298 { NULL, 1, 0, NULL, NULL, (VOID **)&MadtInterruptControllerType, NULL, NULL },\r
299 { L"Length", 1, 1, NULL, NULL, (VOID **)&MadtInterruptControllerLength, NULL,\r
300 NULL },\r
301 { L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL }\r
ee4dc24f
RN
302};\r
303\r
a6eaba4d
DB
304/**\r
305 This function parses the ACPI MADT table.\r
ee4dc24f
RN
306 When trace is enabled this function parses the MADT table and\r
307 traces the ACPI table fields.\r
308\r
309 This function currently parses the following Interrupt Controller\r
310 Structures:\r
311 - GICC\r
312 - GICD\r
313 - GIC MSI Frame\r
314 - GICR\r
315 - GIC ITS\r
316\r
317 This function also performs validation of the ACPI table fields.\r
318\r
319 @param [in] Trace If TRUE, trace the ACPI fields.\r
320 @param [in] Ptr Pointer to the start of the buffer.\r
321 @param [in] AcpiTableLength Length of the ACPI table.\r
322 @param [in] AcpiTableRevision Revision of the ACPI table.\r
a6eaba4d 323**/\r
ee4dc24f
RN
324VOID\r
325EFIAPI\r
326ParseAcpiMadt (\r
47d20b54
MK
327 IN BOOLEAN Trace,\r
328 IN UINT8 *Ptr,\r
329 IN UINT32 AcpiTableLength,\r
330 IN UINT8 AcpiTableRevision\r
ee4dc24f
RN
331 )\r
332{\r
47d20b54
MK
333 UINT32 Offset;\r
334 UINT8 *InterruptContollerPtr;\r
335 UINT32 GICDCount;\r
f75c7478
DB
336\r
337 GICDCount = 0;\r
ee4dc24f
RN
338\r
339 if (!Trace) {\r
340 return;\r
341 }\r
342\r
343 Offset = ParseAcpi (\r
344 TRUE,\r
345 0,\r
346 "MADT",\r
347 Ptr,\r
348 AcpiTableLength,\r
349 PARSER_PARAMS (MadtParser)\r
350 );\r
351 InterruptContollerPtr = Ptr + Offset;\r
352\r
353 while (Offset < AcpiTableLength) {\r
354 // Parse Interrupt Controller Structure to obtain Length.\r
355 ParseAcpi (\r
356 FALSE,\r
357 0,\r
358 NULL,\r
359 InterruptContollerPtr,\r
05d40295 360 AcpiTableLength - Offset,\r
ee4dc24f
RN
361 PARSER_PARAMS (MadtInterruptControllerHeaderParser)\r
362 );\r
363\r
c4a53853
KK
364 // Check if the values used to control the parsing logic have been\r
365 // successfully read.\r
366 if ((MadtInterruptControllerType == NULL) ||\r
47d20b54
MK
367 (MadtInterruptControllerLength == NULL))\r
368 {\r
c4a53853
KK
369 IncrementErrorCount ();\r
370 Print (\r
371 L"ERROR: Insufficient remaining table buffer length to read the " \\r
47d20b54 372 L"Interrupt Controller Structure header. Length = %d.\n",\r
c4a53853
KK
373 AcpiTableLength - Offset\r
374 );\r
375 return;\r
376 }\r
377\r
b8504826
KK
378 // Validate Interrupt Controller Structure length\r
379 if ((*MadtInterruptControllerLength == 0) ||\r
47d20b54
MK
380 ((Offset + (*MadtInterruptControllerLength)) > AcpiTableLength))\r
381 {\r
ee4dc24f
RN
382 IncrementErrorCount ();\r
383 Print (\r
b8504826 384 L"ERROR: Invalid Interrupt Controller Structure length. " \\r
47d20b54 385 L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",\r
d23bf797 386 *MadtInterruptControllerLength,\r
b8504826
KK
387 Offset,\r
388 AcpiTableLength\r
d23bf797
KK
389 );\r
390 return;\r
ee4dc24f
RN
391 }\r
392\r
393 switch (*MadtInterruptControllerType) {\r
47d20b54
MK
394 case EFI_ACPI_6_3_GIC:\r
395 {\r
ee4dc24f
RN
396 ParseAcpi (\r
397 TRUE,\r
398 2,\r
399 "GICC",\r
400 InterruptContollerPtr,\r
401 *MadtInterruptControllerLength,\r
402 PARSER_PARAMS (GicCParser)\r
403 );\r
404 break;\r
405 }\r
406\r
47d20b54
MK
407 case EFI_ACPI_6_3_GICD:\r
408 {\r
ee4dc24f
RN
409 if (++GICDCount > 1) {\r
410 IncrementErrorCount ();\r
411 Print (\r
412 L"ERROR: Only one GICD must be present,"\r
47d20b54 413 L" GICDCount = %d\n",\r
ee4dc24f
RN
414 GICDCount\r
415 );\r
416 }\r
47d20b54 417\r
ee4dc24f
RN
418 ParseAcpi (\r
419 TRUE,\r
420 2,\r
421 "GICD",\r
422 InterruptContollerPtr,\r
423 *MadtInterruptControllerLength,\r
424 PARSER_PARAMS (GicDParser)\r
425 );\r
426 break;\r
427 }\r
428\r
47d20b54
MK
429 case EFI_ACPI_6_3_GIC_MSI_FRAME:\r
430 {\r
ee4dc24f
RN
431 ParseAcpi (\r
432 TRUE,\r
433 2,\r
434 "GIC MSI Frame",\r
435 InterruptContollerPtr,\r
436 *MadtInterruptControllerLength,\r
437 PARSER_PARAMS (GicMSIFrameParser)\r
438 );\r
439 break;\r
440 }\r
441\r
47d20b54
MK
442 case EFI_ACPI_6_3_GICR:\r
443 {\r
ee4dc24f
RN
444 ParseAcpi (\r
445 TRUE,\r
446 2,\r
447 "GICR",\r
448 InterruptContollerPtr,\r
449 *MadtInterruptControllerLength,\r
450 PARSER_PARAMS (GicRParser)\r
451 );\r
452 break;\r
453 }\r
454\r
47d20b54
MK
455 case EFI_ACPI_6_3_GIC_ITS:\r
456 {\r
ee4dc24f
RN
457 ParseAcpi (\r
458 TRUE,\r
459 2,\r
460 "GIC ITS",\r
461 InterruptContollerPtr,\r
462 *MadtInterruptControllerLength,\r
463 PARSER_PARAMS (GicITSParser)\r
464 );\r
465 break;\r
466 }\r
467\r
47d20b54
MK
468 case EFI_ACPI_6_3_IO_APIC:\r
469 {\r
2f286930
ALA
470 ParseAcpi (\r
471 TRUE,\r
472 2,\r
473 "IO APIC",\r
474 InterruptContollerPtr,\r
475 *MadtInterruptControllerLength,\r
476 PARSER_PARAMS (IoApic)\r
477 );\r
478 break;\r
479 }\r
480\r
47d20b54
MK
481 case EFI_ACPI_6_3_INTERRUPT_SOURCE_OVERRIDE:\r
482 {\r
2f286930
ALA
483 ParseAcpi (\r
484 TRUE,\r
485 2,\r
486 "INTERRUPT SOURCE OVERRIDE",\r
487 InterruptContollerPtr,\r
488 *MadtInterruptControllerLength,\r
489 PARSER_PARAMS (InterruptSourceOverride)\r
490 );\r
491 break;\r
492 }\r
d5fd86f2
ALA
493 case EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC:\r
494 {\r
495 ParseAcpi (\r
496 TRUE,\r
497 2,\r
498 "PROCESSOR LOCAL APIC",\r
499 InterruptContollerPtr,\r
500 *MadtInterruptControllerLength,\r
501 PARSER_PARAMS (ProcessorLocalApic)\r
502 );\r
503 break;\r
504 }\r
47d20b54
MK
505 case EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC:\r
506 {\r
2f286930
ALA
507 ParseAcpi (\r
508 TRUE,\r
509 2,\r
510 "PROCESSOR LOCAL X2APIC",\r
511 InterruptContollerPtr,\r
512 *MadtInterruptControllerLength,\r
513 PARSER_PARAMS (ProcessorLocalX2Apic)\r
514 );\r
515 break;\r
516 }\r
517\r
47d20b54
MK
518 case EFI_ACPI_6_3_LOCAL_X2APIC_NMI:\r
519 {\r
2f286930
ALA
520 ParseAcpi (\r
521 TRUE,\r
522 2,\r
523 "LOCAL x2APIC NMI",\r
524 InterruptContollerPtr,\r
525 *MadtInterruptControllerLength,\r
526 PARSER_PARAMS (LocalX2ApicNmi)\r
527 );\r
528 break;\r
529 }\r
530\r
47d20b54
MK
531 default:\r
532 {\r
ee4dc24f
RN
533 IncrementErrorCount ();\r
534 Print (\r
535 L"ERROR: Unknown Interrupt Controller Structure,"\r
47d20b54 536 L" Type = %d, Length = %d\n",\r
ee4dc24f
RN
537 *MadtInterruptControllerType,\r
538 *MadtInterruptControllerLength\r
539 );\r
540 }\r
541 } // switch\r
542\r
543 InterruptContollerPtr += *MadtInterruptControllerLength;\r
47d20b54 544 Offset += *MadtInterruptControllerLength;\r
ee4dc24f
RN
545 } // while\r
546}\r