/** @file RAS2 table parser Copyright (c) 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): - ACPI 6.5 Specification - August 2022 **/ #include #include #include #include "AcpiParser.h" #include "AcpiView.h" // Local variables STATIC CONST UINT16 *Ras2PccDescriptors; STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; /** An ACPI_PARSER array describing the ACPI RAS2 Table. */ STATIC CONST ACPI_PARSER Ras2Parser[] = { PARSE_ACPI_HEADER (&AcpiHdrInfo), { L"Reserved", 2, 36, L"0x%x", NULL, NULL, NULL, NULL }, { L"PCC Descriptors", 2, 38, L"%d", NULL, (VOID **)&Ras2PccDescriptors, NULL, NULL } }; /** An ACPI_PARSER array describing the RAS2 PCC ID Entry */ STATIC CONST ACPI_PARSER Ras2StructurePccDescriptor[] = { { L"PCC ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, { L"Reserved", 1, 1, L"0x%x", NULL, NULL, NULL, NULL }, { L"Reserved", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, { L"Feature Type", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, { L"Instance", 4, 4, L"0x%x", NULL, NULL, NULL, NULL } }; STATIC VOID DumpPccEntry ( IN UINT8 *Ptr, IN UINT32 Length ) { ParseAcpi ( TRUE, 2, "PCC Descriptor Entry", Ptr, Length, PARSER_PARAMS (Ras2StructurePccDescriptor) ); } /** This function parses the ACPI RAS2 table. When trace is enabled this function parses the RAS2 table and traces the ACPI table fields. This function parses the following RAS2 structures: - Pcc Instries - Entry Pcc ID - Entry Feature Type - Entry Pcc Instance 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 ParseAcpiRas2 ( IN BOOLEAN Trace, IN UINT8 *Ptr, IN UINT32 AcpiTableLength, IN UINT8 AcpiTableRevision ) { UINT32 Offset; UINT16 Count = 0; CONST CHAR16 *Message; if (!Trace) { return; } // Parse ACPI Header + RAS2 "fixed" fields Offset = ParseAcpi ( Trace, 0, "RAS2", Ptr, AcpiTableLength, PARSER_PARAMS (Ras2Parser) ); // Table is too small to contain data if (Offset >= AcpiTableLength) { return; } // Loop over rest of table for PCC Entries and dump them while (Offset <= (AcpiTableLength - sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR))) { DumpPccEntry ( Ptr + Offset, sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR) ); Offset += sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR); Count++; } // while // Check counts match and print error if not if (Count != *Ras2PccDescriptors) { Message = Count > *Ras2PccDescriptors ? L"many" : L"few"; IncrementWarningCount (); Print ( L"\nWARNING: Too %s descriptors provided (advertised %d, provided %d)", Message, *Ras2PccDescriptors, Count ); } }