Parse Type 0 or Local APIC structure. Also parse the Local APIC Flags as bitfields. Cc: Ray Ni <ray.ni@intel.com> Cc: Zhichao Gao <zhichao.gao@intel.com> Signed-off-by: Abdul Lateef Attar <abdattar@amd.com> Reviewed-by: Zhichao Gao <zhichao.gao@intel.com>
		
			
				
	
	
		
			547 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			547 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   MADT table parser
 | |
| 
 | |
|   Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
 | |
|   Copyright (c) 2022, AMD Incorporated. All rights reserved.
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
|   @par Reference(s):
 | |
|     - ACPI 6.3 Specification - January 2019
 | |
|     - Arm Generic Interrupt Controller Architecture Specification,
 | |
|       GIC architecture version 3 and version 4, issue E
 | |
|     - Arm Server Base System Architecture 5.0
 | |
| **/
 | |
| 
 | |
| #include <IndustryStandard/Acpi.h>
 | |
| #include <Library/UefiLib.h>
 | |
| #include "AcpiParser.h"
 | |
| #include "AcpiTableParser.h"
 | |
| #include "AcpiViewConfig.h"
 | |
| #include "MadtParser.h"
 | |
| 
 | |
| // Local Variables
 | |
| STATIC CONST UINT8                   *MadtInterruptControllerType;
 | |
| STATIC CONST UINT8                   *MadtInterruptControllerLength;
 | |
| STATIC ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;
 | |
| 
 | |
| /**
 | |
|   This function validates the System Vector Base in the GICD.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidateGICDSystemVectorBase (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   if (*(UINT32 *)Ptr != 0) {
 | |
|     IncrementErrorCount ();
 | |
|     Print (
 | |
|       L"\nERROR: System Vector Base must be zero."
 | |
|       );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function validates the SPE Overflow Interrupt in the GICC.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidateSpeOverflowInterrupt (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   UINT16  SpeOverflowInterrupt;
 | |
| 
 | |
|   SpeOverflowInterrupt = *(UINT16 *)Ptr;
 | |
| 
 | |
|   // SPE not supported by this processor
 | |
|   if (SpeOverflowInterrupt == 0) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((SpeOverflowInterrupt < ARM_PPI_ID_MIN) ||
 | |
|       ((SpeOverflowInterrupt > ARM_PPI_ID_MAX) &&
 | |
|        (SpeOverflowInterrupt < ARM_PPI_ID_EXTENDED_MIN)) ||
 | |
|       (SpeOverflowInterrupt > ARM_PPI_ID_EXTENDED_MAX))
 | |
|   {
 | |
|     IncrementErrorCount ();
 | |
|     Print (
 | |
|       L"\nERROR: SPE Overflow Interrupt ID of %d is not in the allowed PPI ID "
 | |
|       L"ranges of %d-%d or %d-%d (for GICv3.1 or later).",
 | |
|       SpeOverflowInterrupt,
 | |
|       ARM_PPI_ID_MIN,
 | |
|       ARM_PPI_ID_MAX,
 | |
|       ARM_PPI_ID_EXTENDED_MIN,
 | |
|       ARM_PPI_ID_EXTENDED_MAX
 | |
|       );
 | |
|   } else if (SpeOverflowInterrupt != ARM_PPI_ID_PMBIRQ) {
 | |
|     IncrementWarningCount ();
 | |
|     Print (
 | |
|       L"\nWARNING: SPE Overflow Interrupt ID of %d is not compliant with SBSA "
 | |
|       L"Level 3 PPI ID assignment: %d.",
 | |
|       SpeOverflowInterrupt,
 | |
|       ARM_PPI_ID_PMBIRQ
 | |
|       );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the GICC Interrupt Controller Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  GicCParser[] = {
 | |
|   { L"Type",                             1, 0,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Length",                           1, 1,  L"%d",    NULL, NULL, NULL, NULL },
 | |
|   { L"Reserved",                         2, 2,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
| 
 | |
|   { L"CPU Interface Number",             4, 4,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"ACPI Processor UID",               4, 8,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Flags",                            4, 12, L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Parking Protocol Version",         4, 16, L"0x%x",  NULL, NULL, NULL, NULL },
 | |
| 
 | |
|   { L"Performance Interrupt GSIV",       4, 20, L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Parked Address",                   8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
 | |
|   { L"Physical Base Address",            8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
 | |
|   { L"GICV",                             8, 40, L"0x%lx", NULL, NULL, NULL, NULL },
 | |
|   { L"GICH",                             8, 48, L"0x%lx", NULL, NULL, NULL, NULL },
 | |
|   { L"VGIC Maintenance interrupt",       4, 56, L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"GICR Base Address",                8, 60, L"0x%lx", NULL, NULL, NULL, NULL },
 | |
|   { L"MPIDR",                            8, 68, L"0x%lx", NULL, NULL, NULL, NULL },
 | |
|   { L"Processor Power Efficiency Class", 1, 76, L"0x%x",  NULL, NULL, NULL,
 | |
|     NULL },
 | |
|   { L"Reserved",                         1, 77, L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"SPE overflow Interrupt",           2, 78, L"0x%x",  NULL, NULL,
 | |
|     ValidateSpeOverflowInterrupt, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the GICD Interrupt Controller Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  GicDParser[] = {
 | |
|   { L"Type",                  1, 0,  L"0x%x",     NULL,       NULL, NULL, NULL },
 | |
|   { L"Length",                1, 1,  L"%d",       NULL,       NULL, NULL, NULL },
 | |
|   { L"Reserved",              2, 2,  L"0x%x",     NULL,       NULL, NULL, NULL },
 | |
| 
 | |
|   { L"GIC ID",                4, 4,  L"0x%x",     NULL,       NULL, NULL, NULL },
 | |
|   { L"Physical Base Address", 8, 8,  L"0x%lx",    NULL,       NULL, NULL, NULL },
 | |
|   { L"System Vector Base",    4, 16, L"0x%x",     NULL,       NULL,
 | |
|     ValidateGICDSystemVectorBase, NULL },
 | |
|   { L"GIC Version",           1, 20, L"%d",       NULL,       NULL, NULL, NULL },
 | |
|   { L"Reserved",              3, 21, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the MSI Frame Interrupt Controller Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  GicMSIFrameParser[] = {
 | |
|   { L"Type",                  1, 0,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Length",                1, 1,  L"%d",    NULL, NULL, NULL, NULL },
 | |
|   { L"Reserved",              2, 2,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
| 
 | |
|   { L"MSI Frame ID",          4, 4,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Physical Base Address", 8, 8,  L"0x%lx", NULL, NULL, NULL, NULL },
 | |
|   { L"Flags",                 4, 16, L"0x%x",  NULL, NULL, NULL, NULL },
 | |
| 
 | |
|   { L"SPI Count",             2, 20, L"%d",    NULL, NULL, NULL, NULL },
 | |
|   { L"SPI Base",              2, 22, L"0x%x",  NULL, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the GICR Interrupt Controller Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  GicRParser[] = {
 | |
|   { L"Type",                         1, 0,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Length",                       1, 1,  L"%d",    NULL, NULL, NULL, NULL },
 | |
|   { L"Reserved",                     2, 2,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
| 
 | |
|   { L"Discovery Range Base Address", 8, 4,  L"0x%lx", NULL, NULL, NULL,
 | |
|     NULL },
 | |
|   { L"Discovery Range Length",       4, 12, L"0x%x",  NULL, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the GIC ITS Interrupt Controller Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  GicITSParser[] = {
 | |
|   { L"Type",                  1, 0,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Length",                1, 1,  L"%d",    NULL, NULL, NULL, NULL },
 | |
|   { L"Reserved",              2, 2,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
| 
 | |
|   { L"GIC ITS ID",            4, 4,  L"0x%x",  NULL, NULL, NULL, NULL },
 | |
|   { L"Physical Base Address", 8, 8,  L"0x%lx", NULL, NULL, NULL, NULL },
 | |
|   { L"Reserved",              4, 16, L"0x%x",  NULL, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the IO APIC Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  IoApic[] = {
 | |
|   { L"Type",                         1, 0, L"0x%x", NULL, NULL, NULL, NULL },
 | |
|   { L"Length",                       1, 1, L"%d",   NULL, NULL, NULL, NULL },
 | |
|   { L"I/O APIC ID",                  1, 2, L"0x%x", NULL, NULL, NULL, NULL },
 | |
|   { L"Reserved",                     1, 3, L"0x%x", NULL, NULL, NULL, NULL },
 | |
|   { L"I/O APIC Address",             4, 4, L"0x%x", NULL, NULL, NULL, NULL },
 | |
|   { L"Global System Interrupt Base", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the Interrupt Source Override Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  InterruptSourceOverride[] = {
 | |
|   { L"Type",                    1, 0, L"0x%x", NULL, NULL, NULL, NULL },
 | |
|   { L"Length",                  1, 1, L"%d",   NULL, NULL, NULL, NULL },
 | |
|   { L"Bus",                     1, 2, L"0x%x", NULL, NULL, NULL, NULL },
 | |
|   { L"Source",                  1, 3, L"0x%x", NULL, NULL, NULL, NULL },
 | |
|   { L"Global System Interrupt", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
 | |
|   { L"Flags",                   2, 8, L"0x%x", NULL, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| STATIC CONST ACPI_PARSER  LocalApicFlags[] = {
 | |
|   { L"Enabled",        1,  0, L"%d", NULL, NULL, NULL, NULL },
 | |
|   { L"Online Capable", 1,  1, L"%d", NULL, NULL, NULL, NULL },
 | |
|   { L"Reserved",       30, 2, L"%d", NULL, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   This function traces Bit Flags fields.
 | |
|   If no format string is specified the Format must be NULL.
 | |
| 
 | |
|   @param [in] Format  Optional format string for tracing the data.
 | |
|   @param [in] Ptr     Pointer to the start of the buffer.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| DumpLocalApicBitFlags (
 | |
|   IN CONST CHAR16  *Format OPTIONAL,
 | |
|   IN UINT8         *Ptr
 | |
|   )
 | |
| {
 | |
|   if (Format != NULL) {
 | |
|     Print (Format, *(UINT32 *)Ptr);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   Print (L"0x%X\n", *(UINT32 *)Ptr);
 | |
|   ParseAcpiBitFields (
 | |
|     TRUE,
 | |
|     2,
 | |
|     NULL,
 | |
|     Ptr,
 | |
|     4,
 | |
|     PARSER_PARAMS (LocalApicFlags)
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|    An ACPI_PARSER array describing the Processor Local APIC Structure.
 | |
|  **/
 | |
| STATIC CONST ACPI_PARSER  ProcessorLocalApic[] = {
 | |
|   { L"Type",               1, 0, L"0x%x", NULL,                  NULL, NULL, NULL },
 | |
|   { L"Length",             1, 1, L"%d",   NULL,                  NULL, NULL, NULL },
 | |
| 
 | |
|   { L"ACPI Processor UID", 1, 2, L"0x%x", NULL,                  NULL, NULL, NULL },
 | |
|   { L"APIC ID",            1, 3, L"0x%x", NULL,                  NULL, NULL, NULL },
 | |
|   { L"Flags",              4, 4, NULL,    DumpLocalApicBitFlags, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the Processor Local x2APIC Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  ProcessorLocalX2Apic[] = {
 | |
|   { L"Type",               1, 0,  L"0x%x", NULL,                  NULL, NULL, NULL },
 | |
|   { L"Length",             1, 1,  L"%d",   NULL,                  NULL, NULL, NULL },
 | |
|   { L"Reserved",           2, 2,  L"0x%x", NULL,                  NULL, NULL, NULL },
 | |
| 
 | |
|   { L"X2APIC ID",          4, 4,  L"0x%x", NULL,                  NULL, NULL, NULL },
 | |
|   { L"Flags",              4, 8,  NULL,    DumpLocalApicBitFlags, NULL, NULL, NULL },
 | |
|   { L"ACPI Processor UID", 4, 12, L"0x%x", NULL,                  NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the Local x2APIC NMI Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  LocalX2ApicNmi[] = {
 | |
|   { L"Type",               1, 0, L"0x%x",     NULL,       NULL, NULL, NULL },
 | |
|   { L"Length",             1, 1, L"%d",       NULL,       NULL, NULL, NULL },
 | |
|   { L"Flags",              2, 2, L"0x%x",     NULL,       NULL, NULL, NULL },
 | |
| 
 | |
|   { L"ACPI Processor UID", 4, 4, L"0x%x",     NULL,       NULL, NULL, NULL },
 | |
|   { L"Local x2APIC LINT#", 1, 8, L"0x%x",     NULL,       NULL, NULL, NULL },
 | |
|   { L"Reserved",           3, 9, L"0x%x%x%x", Dump3Chars, NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the ACPI MADT Table.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  MadtParser[] = {
 | |
|   PARSE_ACPI_HEADER (&AcpiHdrInfo),
 | |
|   { L"Local Interrupt Controller Address",4,         36, L"0x%x", NULL, NULL, NULL,
 | |
|     NULL },
 | |
|   { L"Flags",                      4,         40, L"0x%x", NULL, NULL, NULL,NULL}
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the MADT Interrupt Controller Structure Header Structure.
 | |
| **/
 | |
| STATIC CONST ACPI_PARSER  MadtInterruptControllerHeaderParser[] = {
 | |
|   { NULL,        1, 0, NULL, NULL, (VOID **)&MadtInterruptControllerType,   NULL, NULL },
 | |
|   { L"Length",   1, 1, NULL, NULL, (VOID **)&MadtInterruptControllerLength, NULL,
 | |
|     NULL },
 | |
|   { L"Reserved", 2, 2, NULL, NULL, NULL,                                    NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   This function parses the ACPI MADT table.
 | |
|   When trace is enabled this function parses the MADT table and
 | |
|   traces the ACPI table fields.
 | |
| 
 | |
|   This function currently parses the following Interrupt Controller
 | |
|   Structures:
 | |
|     - GICC
 | |
|     - GICD
 | |
|     - GIC MSI Frame
 | |
|     - GICR
 | |
|     - GIC ITS
 | |
| 
 | |
|   This function also performs validation of the ACPI table fields.
 | |
| 
 | |
|   @param [in] Trace              If TRUE, trace the ACPI fields.
 | |
|   @param [in] Ptr                Pointer to the start of the buffer.
 | |
|   @param [in] AcpiTableLength    Length of the ACPI table.
 | |
|   @param [in] AcpiTableRevision  Revision of the ACPI table.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| ParseAcpiMadt (
 | |
|   IN BOOLEAN  Trace,
 | |
|   IN UINT8    *Ptr,
 | |
|   IN UINT32   AcpiTableLength,
 | |
|   IN UINT8    AcpiTableRevision
 | |
|   )
 | |
| {
 | |
|   UINT32  Offset;
 | |
|   UINT8   *InterruptContollerPtr;
 | |
|   UINT32  GICDCount;
 | |
| 
 | |
|   GICDCount = 0;
 | |
| 
 | |
|   if (!Trace) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   Offset = ParseAcpi (
 | |
|              TRUE,
 | |
|              0,
 | |
|              "MADT",
 | |
|              Ptr,
 | |
|              AcpiTableLength,
 | |
|              PARSER_PARAMS (MadtParser)
 | |
|              );
 | |
|   InterruptContollerPtr = Ptr + Offset;
 | |
| 
 | |
|   while (Offset < AcpiTableLength) {
 | |
|     // Parse Interrupt Controller Structure to obtain Length.
 | |
|     ParseAcpi (
 | |
|       FALSE,
 | |
|       0,
 | |
|       NULL,
 | |
|       InterruptContollerPtr,
 | |
|       AcpiTableLength - Offset,
 | |
|       PARSER_PARAMS (MadtInterruptControllerHeaderParser)
 | |
|       );
 | |
| 
 | |
|     // Check if the values used to control the parsing logic have been
 | |
|     // successfully read.
 | |
|     if ((MadtInterruptControllerType == NULL) ||
 | |
|         (MadtInterruptControllerLength == NULL))
 | |
|     {
 | |
|       IncrementErrorCount ();
 | |
|       Print (
 | |
|         L"ERROR: Insufficient remaining table buffer length to read the " \
 | |
|         L"Interrupt Controller Structure header. Length = %d.\n",
 | |
|         AcpiTableLength - Offset
 | |
|         );
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     // Validate Interrupt Controller Structure length
 | |
|     if ((*MadtInterruptControllerLength == 0) ||
 | |
|         ((Offset + (*MadtInterruptControllerLength)) > AcpiTableLength))
 | |
|     {
 | |
|       IncrementErrorCount ();
 | |
|       Print (
 | |
|         L"ERROR: Invalid Interrupt Controller Structure length. " \
 | |
|         L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
 | |
|         *MadtInterruptControllerLength,
 | |
|         Offset,
 | |
|         AcpiTableLength
 | |
|         );
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (*MadtInterruptControllerType) {
 | |
|       case EFI_ACPI_6_3_GIC:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "GICC",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (GicCParser)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case EFI_ACPI_6_3_GICD:
 | |
|       {
 | |
|         if (++GICDCount > 1) {
 | |
|           IncrementErrorCount ();
 | |
|           Print (
 | |
|             L"ERROR: Only one GICD must be present,"
 | |
|             L" GICDCount = %d\n",
 | |
|             GICDCount
 | |
|             );
 | |
|         }
 | |
| 
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "GICD",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (GicDParser)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case EFI_ACPI_6_3_GIC_MSI_FRAME:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "GIC MSI Frame",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (GicMSIFrameParser)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case EFI_ACPI_6_3_GICR:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "GICR",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (GicRParser)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case EFI_ACPI_6_3_GIC_ITS:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "GIC ITS",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (GicITSParser)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case EFI_ACPI_6_3_IO_APIC:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "IO APIC",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (IoApic)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case EFI_ACPI_6_3_INTERRUPT_SOURCE_OVERRIDE:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "INTERRUPT SOURCE OVERRIDE",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (InterruptSourceOverride)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
|       case EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "PROCESSOR LOCAL APIC",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (ProcessorLocalApic)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
|       case EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "PROCESSOR LOCAL X2APIC",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (ProcessorLocalX2Apic)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case EFI_ACPI_6_3_LOCAL_X2APIC_NMI:
 | |
|       {
 | |
|         ParseAcpi (
 | |
|           TRUE,
 | |
|           2,
 | |
|           "LOCAL x2APIC NMI",
 | |
|           InterruptContollerPtr,
 | |
|           *MadtInterruptControllerLength,
 | |
|           PARSER_PARAMS (LocalX2ApicNmi)
 | |
|           );
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       default:
 | |
|       {
 | |
|         IncrementErrorCount ();
 | |
|         Print (
 | |
|           L"ERROR: Unknown Interrupt Controller Structure,"
 | |
|           L" Type = %d, Length = %d\n",
 | |
|           *MadtInterruptControllerType,
 | |
|           *MadtInterruptControllerLength
 | |
|           );
 | |
|       }
 | |
|     } // switch
 | |
| 
 | |
|     InterruptContollerPtr += *MadtInterruptControllerLength;
 | |
|     Offset                += *MadtInterruptControllerLength;
 | |
|   } // while
 | |
| }
 |