summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c')
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c1520
1 files changed, 760 insertions, 760 deletions
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c
index 48f71484fb..7cf82103f7 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c
@@ -1,760 +1,760 @@
-/** @file
- AEST table parser
-
- Copyright (c) 2020, Arm Limited.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document,
- dated 28 September 2020.
- (https://developer.arm.com/documentation/den0085/0101/)
-**/
-
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include <IndustryStandard/ArmErrorSourceTable.h>
-#include "AcpiParser.h"
-#include "AcpiView.h"
-#include "AcpiViewConfig.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-STATIC UINT8 *AestNodeType;
-STATIC UINT16 *AestNodeLength;
-STATIC UINT32 *NodeDataOffset;
-STATIC UINT32 *NodeInterfaceOffset;
-STATIC UINT32 *NodeInterruptArrayOffset;
-STATIC UINT32 *NodeInterruptCount;
-STATIC UINT32 *ProcessorId;
-STATIC UINT8 *ProcessorFlags;
-STATIC UINT8 *ProcessorResourceType;
-
-/**
- Validate Processor Flags.
-
- @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
-ValidateProcessorFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- // If the global or shared node flag is set then the ACPI Processor ID
- // field must be set to 0 and ignored.
- if (((*Ptr & 0x3) != 0) && (*ProcessorId != 0)) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: 'ACPI Processor ID' field must be set to 0 for global"
- L" or shared nodes."
- );
- }
-}
-
-/**
- Validate GIC Interface Type.
-
- @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
-ValidateGicInterfaceType (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT32 GicInterfaceType;
-
- GicInterfaceType = *(UINT32 *)Ptr;
- if (GicInterfaceType > 3) {
- IncrementErrorCount ();
- Print (L"\nError: Invalid GIC Interface type %d", GicInterfaceType);
- }
-}
-
-/**
- Validate Interface Type.
-
- @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
-ValidateInterfaceType (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*Ptr > 1) {
- IncrementErrorCount ();
- Print (L"\nError: Interface type should be 0 or 1");
- }
-}
-
-/**
- Validate Interrupt Type.
-
- @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
-ValidateInterruptType (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*Ptr > 1) {
- IncrementErrorCount ();
- Print (L"\nError: Interrupt type should be 0 or 1");
- }
-}
-
-/**
- Validate interrupt flags.
-
- @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
-ValidateInterruptFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if ((*Ptr & 0xfe) != 0) {
- IncrementErrorCount ();
- Print (L"\nError: Reserved Flag bits not set to 0");
- }
-}
-
-/**
- Dumps 16 bytes of data.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-DumpVendorSpecificData (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- Print (
- L"%02X %02X %02X %02X %02X %02X %02X %02X\n",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3],
- Ptr[4],
- Ptr[5],
- Ptr[6],
- Ptr[7]
- );
-
- Print (
- L"%*a %02X %02X %02X %02X %02X %02X %02X %02X",
- OUTPUT_FIELD_COLUMN_WIDTH,
- "",
- Ptr[8],
- Ptr[9],
- Ptr[10],
- Ptr[11],
- Ptr[12],
- Ptr[13],
- Ptr[14],
- Ptr[15]
- );
-}
-
-/**
- An ACPI_PARSER array describing the ACPI AEST Table.
-**/
-STATIC CONST ACPI_PARSER AestParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo)
-};
-
-/**
- An ACPI_PARSER array describing the AEST Node Header.
-**/
-STATIC CONST ACPI_PARSER AestNodeHeaderParser[] = {
- { L"Type", 1, 0, L"%d", NULL, (VOID **)&AestNodeType, NULL, NULL },
- { L"Length", 2, 1, L"%d", NULL, (VOID **)&AestNodeLength, NULL, NULL },
- { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Node Data Offset", 4, 4, L"%d", NULL, (VOID **)&NodeDataOffset, NULL, NULL },
- { L"Node Interface Offset", 4, 8, L"%d", NULL,
- (VOID **)&NodeInterfaceOffset, NULL, NULL },
- { L"Node Interrupt Array Offset", 4, 12, L"%d", NULL,
- (VOID **)&NodeInterruptArrayOffset, NULL, NULL },
- { L"Node Interrupt Count", 4, 16, L"%d", NULL,
- (VOID **)&NodeInterruptCount, NULL, NULL },
- { L"Timestamp Rate", 8, 20, L"%ld", NULL, NULL, NULL, NULL },
- { L"Reserved1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Error Injection Countdown Rate", 8, 36, L"%ld", NULL, NULL, NULL, NULL }
- // Node specific data...
- // Node interface...
- // Node interrupt array...
-};
-
-/**
- An ACPI_PARSER array describing the Processor error node specific data.
-**/
-STATIC CONST ACPI_PARSER AestProcessorStructure[] = {
- { L"ACPI Processor ID", 4, 0, L"0x%x", NULL, (VOID **)&ProcessorId, NULL, NULL },
- { L"Resource Type", 1, 4, L"%d", NULL, (VOID **)&ProcessorResourceType, NULL,
- NULL },
- { L"Reserved", 1, 5, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Flags", 1, 6, L"0x%x", NULL, (VOID **)&ProcessorFlags,
- ValidateProcessorFlags, NULL },
- { L"Revision", 1, 7, L"%d", NULL, NULL, NULL, NULL },
- { L"Processor Affinity Level Indicator", 8, 8, L"0x%lx", NULL, NULL, NULL,
- NULL },
- // Resource specific data...
-};
-
-/**
- An ACPI_PARSER array describing the processor cache resource substructure.
-**/
-STATIC CONST ACPI_PARSER AestProcessorCacheResourceSubstructure[] = {
- { L"Cache reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the processor TLB resource substructure.
-**/
-STATIC CONST ACPI_PARSER AestProcessorTlbResourceSubstructure[] = {
- { L"TLB reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the processor generic resource substructure.
-**/
-STATIC CONST ACPI_PARSER AestProcessorGenericResourceSubstructure[] = {
- { L"Vendor-defined data", 4, 0, L"%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the memory controller structure.
-**/
-STATIC CONST ACPI_PARSER AestMemoryControllerStructure[] = {
- { L"Proximity Domain", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the SMMU structure.
-**/
-STATIC CONST ACPI_PARSER AestSmmuStructure[] = {
- { L"IORT Node reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"SubComponent reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the vendor-defined structure.
-**/
-STATIC CONST ACPI_PARSER AestVendorDefinedStructure[] = {
- { L"Hardware ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Unique ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Vendor-specific data", 16, 8, NULL, DumpVendorSpecificData, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the GIC structure.
-**/
-STATIC CONST ACPI_PARSER AestGicStructure[] = {
- { L"GIC Interface Type", 4, 0, L"0x%x", NULL, NULL, ValidateGicInterfaceType,
- NULL },
- { L"GIC Interface reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}
-};
-
-/**
- An ACPI_PARSER array describing the node interface.
-**/
-STATIC CONST ACPI_PARSER AestNodeInterface[] = {
- { L"Interface Type", 1, 0, L"%d", NULL, NULL, ValidateInterfaceType, NULL },
- { L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL },
- { L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Start Error Record Index", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Number of Error Records", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Error Records Implemented", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Error Records Support", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Addressing mode", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the node interrupts.
-**/
-STATIC CONST ACPI_PARSER AestNodeInterrupt[] = {
- { L"Interrupt Type", 1, 0, L"%d", NULL, NULL, ValidateInterruptType, NULL },
- { L"Reserved", 2, 1, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Interrupt Flags", 1, 3, L"0x%x", NULL, NULL, ValidateInterruptFlags, NULL },
- { L"Interrupt GSIV", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"ID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved1", 3, 9, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }
-};
-
-/**
- Parses the Processor Error Node structure along with its resource
- specific data.
-
- @param [in] Ptr Pointer to the start of the Processor node.
- @param [in] Length Maximum length of the Processor node.
-**/
-STATIC
-VOID
-DumpProcessorNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- UINT32 Offset;
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "Processor",
- Ptr,
- Length,
- PARSER_PARAMS (AestProcessorStructure)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((ProcessorId == NULL) ||
- (ProcessorResourceType == NULL) ||
- (ProcessorFlags == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient Processor Error Node length. Length = %d.\n",
- Length
- );
- return;
- }
-
- switch (*ProcessorResourceType) {
- case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE:
- ParseAcpi (
- TRUE,
- 2,
- "Cache Resource",
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (AestProcessorCacheResourceSubstructure)
- );
- break;
- case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB:
- ParseAcpi (
- TRUE,
- 2,
- "TLB Resource",
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (AestProcessorTlbResourceSubstructure)
- );
- break;
- case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC:
- ParseAcpi (
- TRUE,
- 2,
- "Generic Resource",
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (AestProcessorGenericResourceSubstructure)
- );
- break;
- default:
- IncrementErrorCount ();
- Print (L"ERROR: Invalid Processor Resource Type.");
- return;
- } // switch
-}
-
-/**
- Parses the Memory Controller node.
-
- @param [in] Ptr Pointer to the start of the Memory Controller node.
- @param [in] Length Maximum length of the Memory Controller node.
-**/
-STATIC
-VOID
-DumpMemoryControllerNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Memory Controller",
- Ptr,
- Length,
- PARSER_PARAMS (AestMemoryControllerStructure)
- );
-}
-
-/**
- Parses the SMMU node.
-
- @param [in] Ptr Pointer to the start of the SMMU node.
- @param [in] Length Maximum length of the SMMU node.
-**/
-STATIC
-VOID
-DumpSmmuNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "SMMU",
- Ptr,
- Length,
- PARSER_PARAMS (AestSmmuStructure)
- );
-}
-
-/**
- Parses the Vendor-defined structure.
-
- @param [in] Ptr Pointer to the start of the Vendor-defined node.
- @param [in] Length Maximum length of the Vendor-defined node.
-**/
-STATIC
-VOID
-DumpVendorDefinedNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Vendor-defined",
- Ptr,
- Length,
- PARSER_PARAMS (AestVendorDefinedStructure)
- );
-}
-
-/**
- Parses the GIC node.
-
- @param [in] Ptr Pointer to the start of the GIC node.
- @param [in] Length Maximum length of the GIC node.
-**/
-STATIC
-VOID
-DumpGicNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "GIC",
- Ptr,
- Length,
- PARSER_PARAMS (AestGicStructure)
- );
-}
-
-/**
- Parses the Node Interface structure.
-
- @param [in] Ptr Pointer to the start of the Node Interface Structure.
- @param [in] Length Maximum length of the Node Interface Structure.
-**/
-STATIC
-VOID
-DumpNodeInterface (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Node Interface",
- Ptr,
- Length,
- PARSER_PARAMS (AestNodeInterface)
- );
-}
-
-/**
- Parses the Node Interrupts Structure.
-
- @param [in] Ptr Pointer to the start of the Node Interrupt array.
- @param [in] Length Maximum length of the Node Interrupt array.
- @param [in] InterruptCount Number if interrupts in the Node Interrupts array.
-**/
-STATIC
-VOID
-DumpNodeInterrupts (
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN UINT32 InterruptCount
- )
-{
- UINT32 Offset;
- UINT32 Index;
- CHAR8 Buffer[64];
-
- if (Length < (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT))) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Node not long enough for Interrupt Array.\n" \
- L" Length left = %d, Required = %d, Interrupt Count = %d\n",
- Length,
- (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT)),
- InterruptCount
- );
- return;
- }
-
- Offset = 0;
- for (Index = 0; Index < InterruptCount; Index++) {
- AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "Node Interrupt [%d]",
- Index
- );
-
- Offset += ParseAcpi (
- TRUE,
- 4,
- Buffer,
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (AestNodeInterrupt)
- );
- } // for
-}
-
-/**
- Parses a single AEST Node Structure.
-
- @param [in] Ptr Pointer to the start of the Node.
- @param [in] Length Maximum length of the Node.
- @param [in] NodeType AEST node type.
- @param [in] DataOffset Offset to the node data.
- @param [in] InterfaceOffset Offset to the node interface data.
- @param [in] InterruptArrayOffset Offset to the node interrupt array.
- @param [in] InterruptCount Number of interrupts.
-**/
-STATIC
-VOID
-DumpAestNodeStructure (
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN UINT8 NodeType,
- IN UINT32 DataOffset,
- IN UINT32 InterfaceOffset,
- IN UINT32 InterruptArrayOffset,
- IN UINT32 InterruptCount
- )
-{
- UINT32 Offset;
- UINT32 RemainingLength;
- UINT8 *NodeDataPtr;
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "Node Structure",
- Ptr,
- Length,
- PARSER_PARAMS (AestNodeHeaderParser)
- );
-
- if ((Offset > DataOffset) || (DataOffset > Length)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Node Data Offset: %d.\n" \
- L" It should be between %d and %d.\n",
- DataOffset,
- Offset,
- Length
- );
- }
-
- if ((Offset > InterfaceOffset) || (InterfaceOffset > Length)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Node Interface Offset: %d.\n" \
- L" It should be between %d and %d.\n",
- InterfaceOffset,
- Offset,
- Length
- );
- }
-
- if ((Offset > InterruptArrayOffset) || (InterruptArrayOffset > Length)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Node Interrupt Array Offset: %d.\n" \
- L" It should be between %d and %d.\n",
- InterruptArrayOffset,
- Offset,
- Length
- );
- }
-
- // Parse Node Data Field.
- NodeDataPtr = Ptr + DataOffset;
- RemainingLength = Length - DataOffset;
- switch (NodeType) {
- case EFI_ACPI_AEST_NODE_TYPE_PROCESSOR:
- DumpProcessorNode (NodeDataPtr, RemainingLength);
- break;
- case EFI_ACPI_AEST_NODE_TYPE_MEMORY:
- DumpMemoryControllerNode (NodeDataPtr, RemainingLength);
- break;
- case EFI_ACPI_AEST_NODE_TYPE_SMMU:
- DumpSmmuNode (NodeDataPtr, RemainingLength);
- break;
- case EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED:
- DumpVendorDefinedNode (NodeDataPtr, RemainingLength);
- break;
- case EFI_ACPI_AEST_NODE_TYPE_GIC:
- DumpGicNode (NodeDataPtr, RemainingLength);
- break;
- default:
- IncrementErrorCount ();
- Print (L"ERROR: Invalid Error Node Type.\n");
- return;
- } // switch
-
- // Parse the Interface Field.
- DumpNodeInterface (
- Ptr + InterfaceOffset,
- Length - InterfaceOffset
- );
-
- // Parse the Node Interrupt Array.
- DumpNodeInterrupts (
- Ptr + InterruptArrayOffset,
- Length - InterruptArrayOffset,
- InterruptCount
- );
-
- return;
-}
-
-/**
- This function parses the ACPI AEST table.
- When trace is enabled this function parses the AEST table and
- traces the ACPI table fields.
-
- 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
-ParseAcpiAest (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
- UINT8 *NodePtr;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- TRUE,
- 0,
- "AEST",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (AestParser)
- );
-
- while (Offset < AcpiTableLength) {
- NodePtr = Ptr + Offset;
-
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- NodePtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (AestNodeHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((AestNodeType == NULL) ||
- (AestNodeLength == NULL) ||
- (NodeDataOffset == NULL) ||
- (NodeInterfaceOffset == NULL) ||
- (NodeInterruptArrayOffset == NULL) ||
- (NodeInterruptCount == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient length left for Node Structure.\n" \
- L" Length left = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate AEST Node length
- if ((*AestNodeLength == 0) ||
- ((Offset + (*AestNodeLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid AEST Node length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *AestNodeLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- DumpAestNodeStructure (
- NodePtr,
- *AestNodeLength,
- *AestNodeType,
- *NodeDataOffset,
- *NodeInterfaceOffset,
- *NodeInterruptArrayOffset,
- *NodeInterruptCount
- );
-
- Offset += *AestNodeLength;
- } // while
-}
+/** @file
+ AEST table parser
+
+ Copyright (c) 2020, Arm Limited.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document,
+ dated 28 September 2020.
+ (https://developer.arm.com/documentation/den0085/0101/)
+**/
+
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <IndustryStandard/ArmErrorSourceTable.h>
+#include "AcpiParser.h"
+#include "AcpiView.h"
+#include "AcpiViewConfig.h"
+
+// Local variables
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+STATIC UINT8 *AestNodeType;
+STATIC UINT16 *AestNodeLength;
+STATIC UINT32 *NodeDataOffset;
+STATIC UINT32 *NodeInterfaceOffset;
+STATIC UINT32 *NodeInterruptArrayOffset;
+STATIC UINT32 *NodeInterruptCount;
+STATIC UINT32 *ProcessorId;
+STATIC UINT8 *ProcessorFlags;
+STATIC UINT8 *ProcessorResourceType;
+
+/**
+ Validate Processor Flags.
+
+ @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
+ValidateProcessorFlags (
+ IN UINT8 *Ptr,
+ IN VOID *Context
+ )
+{
+ // If the global or shared node flag is set then the ACPI Processor ID
+ // field must be set to 0 and ignored.
+ if (((*Ptr & 0x3) != 0) && (*ProcessorId != 0)) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: 'ACPI Processor ID' field must be set to 0 for global"
+ L" or shared nodes."
+ );
+ }
+}
+
+/**
+ Validate GIC Interface Type.
+
+ @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
+ValidateGicInterfaceType (
+ IN UINT8 *Ptr,
+ IN VOID *Context
+ )
+{
+ UINT32 GicInterfaceType;
+
+ GicInterfaceType = *(UINT32 *)Ptr;
+ if (GicInterfaceType > 3) {
+ IncrementErrorCount ();
+ Print (L"\nError: Invalid GIC Interface type %d", GicInterfaceType);
+ }
+}
+
+/**
+ Validate Interface Type.
+
+ @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
+ValidateInterfaceType (
+ IN UINT8 *Ptr,
+ IN VOID *Context
+ )
+{
+ if (*Ptr > 1) {
+ IncrementErrorCount ();
+ Print (L"\nError: Interface type should be 0 or 1");
+ }
+}
+
+/**
+ Validate Interrupt Type.
+
+ @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
+ValidateInterruptType (
+ IN UINT8 *Ptr,
+ IN VOID *Context
+ )
+{
+ if (*Ptr > 1) {
+ IncrementErrorCount ();
+ Print (L"\nError: Interrupt type should be 0 or 1");
+ }
+}
+
+/**
+ Validate interrupt flags.
+
+ @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
+ValidateInterruptFlags (
+ IN UINT8 *Ptr,
+ IN VOID *Context
+ )
+{
+ if ((*Ptr & 0xfe) != 0) {
+ IncrementErrorCount ();
+ Print (L"\nError: Reserved Flag bits not set to 0");
+ }
+}
+
+/**
+ Dumps 16 bytes of data.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+**/
+VOID
+EFIAPI
+DumpVendorSpecificData (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr
+ )
+{
+ Print (
+ L"%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ Ptr[0],
+ Ptr[1],
+ Ptr[2],
+ Ptr[3],
+ Ptr[4],
+ Ptr[5],
+ Ptr[6],
+ Ptr[7]
+ );
+
+ Print (
+ L"%*a %02X %02X %02X %02X %02X %02X %02X %02X",
+ OUTPUT_FIELD_COLUMN_WIDTH,
+ "",
+ Ptr[8],
+ Ptr[9],
+ Ptr[10],
+ Ptr[11],
+ Ptr[12],
+ Ptr[13],
+ Ptr[14],
+ Ptr[15]
+ );
+}
+
+/**
+ An ACPI_PARSER array describing the ACPI AEST Table.
+**/
+STATIC CONST ACPI_PARSER AestParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo)
+};
+
+/**
+ An ACPI_PARSER array describing the AEST Node Header.
+**/
+STATIC CONST ACPI_PARSER AestNodeHeaderParser[] = {
+ { L"Type", 1, 0, L"%d", NULL, (VOID **)&AestNodeType, NULL, NULL },
+ { L"Length", 2, 1, L"%d", NULL, (VOID **)&AestNodeLength, NULL, NULL },
+ { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Node Data Offset", 4, 4, L"%d", NULL, (VOID **)&NodeDataOffset, NULL, NULL },
+ { L"Node Interface Offset", 4, 8, L"%d", NULL,
+ (VOID **)&NodeInterfaceOffset, NULL, NULL },
+ { L"Node Interrupt Array Offset", 4, 12, L"%d", NULL,
+ (VOID **)&NodeInterruptArrayOffset, NULL, NULL },
+ { L"Node Interrupt Count", 4, 16, L"%d", NULL,
+ (VOID **)&NodeInterruptCount, NULL, NULL },
+ { L"Timestamp Rate", 8, 20, L"%ld", NULL, NULL, NULL, NULL },
+ { L"Reserved1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Error Injection Countdown Rate", 8, 36, L"%ld", NULL, NULL, NULL, NULL }
+ // Node specific data...
+ // Node interface...
+ // Node interrupt array...
+};
+
+/**
+ An ACPI_PARSER array describing the Processor error node specific data.
+**/
+STATIC CONST ACPI_PARSER AestProcessorStructure[] = {
+ { L"ACPI Processor ID", 4, 0, L"0x%x", NULL, (VOID **)&ProcessorId, NULL, NULL },
+ { L"Resource Type", 1, 4, L"%d", NULL, (VOID **)&ProcessorResourceType, NULL,
+ NULL },
+ { L"Reserved", 1, 5, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Flags", 1, 6, L"0x%x", NULL, (VOID **)&ProcessorFlags,
+ ValidateProcessorFlags, NULL },
+ { L"Revision", 1, 7, L"%d", NULL, NULL, NULL, NULL },
+ { L"Processor Affinity Level Indicator", 8, 8, L"0x%lx", NULL, NULL, NULL,
+ NULL },
+ // Resource specific data...
+};
+
+/**
+ An ACPI_PARSER array describing the processor cache resource substructure.
+**/
+STATIC CONST ACPI_PARSER AestProcessorCacheResourceSubstructure[] = {
+ { L"Cache reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the processor TLB resource substructure.
+**/
+STATIC CONST ACPI_PARSER AestProcessorTlbResourceSubstructure[] = {
+ { L"TLB reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the processor generic resource substructure.
+**/
+STATIC CONST ACPI_PARSER AestProcessorGenericResourceSubstructure[] = {
+ { L"Vendor-defined data", 4, 0, L"%x", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the memory controller structure.
+**/
+STATIC CONST ACPI_PARSER AestMemoryControllerStructure[] = {
+ { L"Proximity Domain", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the SMMU structure.
+**/
+STATIC CONST ACPI_PARSER AestSmmuStructure[] = {
+ { L"IORT Node reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"SubComponent reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the vendor-defined structure.
+**/
+STATIC CONST ACPI_PARSER AestVendorDefinedStructure[] = {
+ { L"Hardware ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Unique ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Vendor-specific data", 16, 8, NULL, DumpVendorSpecificData, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the GIC structure.
+**/
+STATIC CONST ACPI_PARSER AestGicStructure[] = {
+ { L"GIC Interface Type", 4, 0, L"0x%x", NULL, NULL, ValidateGicInterfaceType,
+ NULL },
+ { L"GIC Interface reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/**
+ An ACPI_PARSER array describing the node interface.
+**/
+STATIC CONST ACPI_PARSER AestNodeInterface[] = {
+ { L"Interface Type", 1, 0, L"%d", NULL, NULL, ValidateInterfaceType, NULL },
+ { L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL },
+ { L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Start Error Record Index", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Number of Error Records", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Error Records Implemented", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Error Records Support", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Addressing mode", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the node interrupts.
+**/
+STATIC CONST ACPI_PARSER AestNodeInterrupt[] = {
+ { L"Interrupt Type", 1, 0, L"%d", NULL, NULL, ValidateInterruptType, NULL },
+ { L"Reserved", 2, 1, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Interrupt Flags", 1, 3, L"0x%x", NULL, NULL, ValidateInterruptFlags, NULL },
+ { L"Interrupt GSIV", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"ID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Reserved1", 3, 9, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }
+};
+
+/**
+ Parses the Processor Error Node structure along with its resource
+ specific data.
+
+ @param [in] Ptr Pointer to the start of the Processor node.
+ @param [in] Length Maximum length of the Processor node.
+**/
+STATIC
+VOID
+DumpProcessorNode (
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ UINT32 Offset;
+
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ "Processor",
+ Ptr,
+ Length,
+ PARSER_PARAMS (AestProcessorStructure)
+ );
+
+ // Check if the values used to control the parsing logic have been
+ // successfully read.
+ if ((ProcessorId == NULL) ||
+ (ProcessorResourceType == NULL) ||
+ (ProcessorFlags == NULL))
+ {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient Processor Error Node length. Length = %d.\n",
+ Length
+ );
+ return;
+ }
+
+ switch (*ProcessorResourceType) {
+ case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Cache Resource",
+ Ptr + Offset,
+ Length - Offset,
+ PARSER_PARAMS (AestProcessorCacheResourceSubstructure)
+ );
+ break;
+ case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "TLB Resource",
+ Ptr + Offset,
+ Length - Offset,
+ PARSER_PARAMS (AestProcessorTlbResourceSubstructure)
+ );
+ break;
+ case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Generic Resource",
+ Ptr + Offset,
+ Length - Offset,
+ PARSER_PARAMS (AestProcessorGenericResourceSubstructure)
+ );
+ break;
+ default:
+ IncrementErrorCount ();
+ Print (L"ERROR: Invalid Processor Resource Type.");
+ return;
+ } // switch
+}
+
+/**
+ Parses the Memory Controller node.
+
+ @param [in] Ptr Pointer to the start of the Memory Controller node.
+ @param [in] Length Maximum length of the Memory Controller node.
+**/
+STATIC
+VOID
+DumpMemoryControllerNode (
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Memory Controller",
+ Ptr,
+ Length,
+ PARSER_PARAMS (AestMemoryControllerStructure)
+ );
+}
+
+/**
+ Parses the SMMU node.
+
+ @param [in] Ptr Pointer to the start of the SMMU node.
+ @param [in] Length Maximum length of the SMMU node.
+**/
+STATIC
+VOID
+DumpSmmuNode (
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "SMMU",
+ Ptr,
+ Length,
+ PARSER_PARAMS (AestSmmuStructure)
+ );
+}
+
+/**
+ Parses the Vendor-defined structure.
+
+ @param [in] Ptr Pointer to the start of the Vendor-defined node.
+ @param [in] Length Maximum length of the Vendor-defined node.
+**/
+STATIC
+VOID
+DumpVendorDefinedNode (
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Vendor-defined",
+ Ptr,
+ Length,
+ PARSER_PARAMS (AestVendorDefinedStructure)
+ );
+}
+
+/**
+ Parses the GIC node.
+
+ @param [in] Ptr Pointer to the start of the GIC node.
+ @param [in] Length Maximum length of the GIC node.
+**/
+STATIC
+VOID
+DumpGicNode (
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "GIC",
+ Ptr,
+ Length,
+ PARSER_PARAMS (AestGicStructure)
+ );
+}
+
+/**
+ Parses the Node Interface structure.
+
+ @param [in] Ptr Pointer to the start of the Node Interface Structure.
+ @param [in] Length Maximum length of the Node Interface Structure.
+**/
+STATIC
+VOID
+DumpNodeInterface (
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Node Interface",
+ Ptr,
+ Length,
+ PARSER_PARAMS (AestNodeInterface)
+ );
+}
+
+/**
+ Parses the Node Interrupts Structure.
+
+ @param [in] Ptr Pointer to the start of the Node Interrupt array.
+ @param [in] Length Maximum length of the Node Interrupt array.
+ @param [in] InterruptCount Number if interrupts in the Node Interrupts array.
+**/
+STATIC
+VOID
+DumpNodeInterrupts (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN UINT32 InterruptCount
+ )
+{
+ UINT32 Offset;
+ UINT32 Index;
+ CHAR8 Buffer[64];
+
+ if (Length < (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT))) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Node not long enough for Interrupt Array.\n" \
+ L" Length left = %d, Required = %d, Interrupt Count = %d\n",
+ Length,
+ (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT)),
+ InterruptCount
+ );
+ return;
+ }
+
+ Offset = 0;
+ for (Index = 0; Index < InterruptCount; Index++) {
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "Node Interrupt [%d]",
+ Index
+ );
+
+ Offset += ParseAcpi (
+ TRUE,
+ 4,
+ Buffer,
+ Ptr + Offset,
+ Length - Offset,
+ PARSER_PARAMS (AestNodeInterrupt)
+ );
+ } // for
+}
+
+/**
+ Parses a single AEST Node Structure.
+
+ @param [in] Ptr Pointer to the start of the Node.
+ @param [in] Length Maximum length of the Node.
+ @param [in] NodeType AEST node type.
+ @param [in] DataOffset Offset to the node data.
+ @param [in] InterfaceOffset Offset to the node interface data.
+ @param [in] InterruptArrayOffset Offset to the node interrupt array.
+ @param [in] InterruptCount Number of interrupts.
+**/
+STATIC
+VOID
+DumpAestNodeStructure (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN UINT8 NodeType,
+ IN UINT32 DataOffset,
+ IN UINT32 InterfaceOffset,
+ IN UINT32 InterruptArrayOffset,
+ IN UINT32 InterruptCount
+ )
+{
+ UINT32 Offset;
+ UINT32 RemainingLength;
+ UINT8 *NodeDataPtr;
+
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ "Node Structure",
+ Ptr,
+ Length,
+ PARSER_PARAMS (AestNodeHeaderParser)
+ );
+
+ if ((Offset > DataOffset) || (DataOffset > Length)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid Node Data Offset: %d.\n" \
+ L" It should be between %d and %d.\n",
+ DataOffset,
+ Offset,
+ Length
+ );
+ }
+
+ if ((Offset > InterfaceOffset) || (InterfaceOffset > Length)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid Node Interface Offset: %d.\n" \
+ L" It should be between %d and %d.\n",
+ InterfaceOffset,
+ Offset,
+ Length
+ );
+ }
+
+ if ((Offset > InterruptArrayOffset) || (InterruptArrayOffset > Length)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid Node Interrupt Array Offset: %d.\n" \
+ L" It should be between %d and %d.\n",
+ InterruptArrayOffset,
+ Offset,
+ Length
+ );
+ }
+
+ // Parse Node Data Field.
+ NodeDataPtr = Ptr + DataOffset;
+ RemainingLength = Length - DataOffset;
+ switch (NodeType) {
+ case EFI_ACPI_AEST_NODE_TYPE_PROCESSOR:
+ DumpProcessorNode (NodeDataPtr, RemainingLength);
+ break;
+ case EFI_ACPI_AEST_NODE_TYPE_MEMORY:
+ DumpMemoryControllerNode (NodeDataPtr, RemainingLength);
+ break;
+ case EFI_ACPI_AEST_NODE_TYPE_SMMU:
+ DumpSmmuNode (NodeDataPtr, RemainingLength);
+ break;
+ case EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED:
+ DumpVendorDefinedNode (NodeDataPtr, RemainingLength);
+ break;
+ case EFI_ACPI_AEST_NODE_TYPE_GIC:
+ DumpGicNode (NodeDataPtr, RemainingLength);
+ break;
+ default:
+ IncrementErrorCount ();
+ Print (L"ERROR: Invalid Error Node Type.\n");
+ return;
+ } // switch
+
+ // Parse the Interface Field.
+ DumpNodeInterface (
+ Ptr + InterfaceOffset,
+ Length - InterfaceOffset
+ );
+
+ // Parse the Node Interrupt Array.
+ DumpNodeInterrupts (
+ Ptr + InterruptArrayOffset,
+ Length - InterruptArrayOffset,
+ InterruptCount
+ );
+
+ return;
+}
+
+/**
+ This function parses the ACPI AEST table.
+ When trace is enabled this function parses the AEST table and
+ traces the ACPI table fields.
+
+ 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
+ParseAcpiAest (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT8 *NodePtr;
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "AEST",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (AestParser)
+ );
+
+ while (Offset < AcpiTableLength) {
+ NodePtr = Ptr + Offset;
+
+ ParseAcpi (
+ FALSE,
+ 0,
+ NULL,
+ NodePtr,
+ AcpiTableLength - Offset,
+ PARSER_PARAMS (AestNodeHeaderParser)
+ );
+
+ // Check if the values used to control the parsing logic have been
+ // successfully read.
+ if ((AestNodeType == NULL) ||
+ (AestNodeLength == NULL) ||
+ (NodeDataOffset == NULL) ||
+ (NodeInterfaceOffset == NULL) ||
+ (NodeInterruptArrayOffset == NULL) ||
+ (NodeInterruptCount == NULL))
+ {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient length left for Node Structure.\n" \
+ L" Length left = %d.\n",
+ AcpiTableLength - Offset
+ );
+ return;
+ }
+
+ // Validate AEST Node length
+ if ((*AestNodeLength == 0) ||
+ ((Offset + (*AestNodeLength)) > AcpiTableLength))
+ {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid AEST Node length. " \
+ L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
+ *AestNodeLength,
+ Offset,
+ AcpiTableLength
+ );
+ return;
+ }
+
+ DumpAestNodeStructure (
+ NodePtr,
+ *AestNodeLength,
+ *AestNodeType,
+ *NodeDataOffset,
+ *NodeInterfaceOffset,
+ *NodeInterruptArrayOffset,
+ *NodeInterruptCount
+ );
+
+ Offset += *AestNodeLength;
+ } // while
+}