X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ShellPkg%2FLibrary%2FUefiShellAcpiViewCommandLib%2FParsers%2FGtdt%2FGtdtParser.c;fp=ShellPkg%2FLibrary%2FUefiShellAcpiViewCommandLib%2FParsers%2FGtdt%2FGtdtParser.c;h=ce96604ee6f800adfbd861691ffa7093b9bd8239;hp=0000000000000000000000000000000000000000;hb=ee4dc24f57c32a445e7c747396c9bfbd8b221568;hpb=8b5c80e0296c7050348a6a89f2cef66190c6141d diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c new file mode 100644 index 0000000000..ce96604ee6 --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c @@ -0,0 +1,293 @@ +/** + GTDT table parser + + Copyright (c) 2016 - 2018, ARM Limited. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Reference(s): + - ACPI 6.2 Specification - Errata A, September 2017 + **/ + +#include +#include +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local variables +STATIC CONST UINT32* GtdtPlatformTimerCount; +STATIC CONST UINT32* GtdtPlatformTimerOffset; +STATIC CONST UINT8* PlatformTimerType; +STATIC CONST UINT16* PlatformTimerLength; +STATIC CONST UINT32* GtBlockTimerCount; +STATIC CONST UINT32* GtBlockTimerOffset; +STATIC CONST UINT16* GtBlockLength; +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** This function validates the GT Block timer count. + + @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 +ValidateGtBlockTimerCount ( + IN UINT8* Ptr, + IN VOID* Context + ); + +/** An ACPI_PARSER array describing the ACPI GTDT Table. +*/ +STATIC CONST ACPI_PARSER GtdtParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + {L"CntControlBase Physical Address", 8, 36, L"0x%lx", NULL, NULL, + NULL, NULL}, + {L"Reserved", 4, 44, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Secure EL1 timer GSIV", 4, 48, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Secure EL1 timer FLAGS", 4, 52, L"0x%x", NULL, NULL, NULL, NULL}, + + {L"Non-Secure EL1 timer GSIV", 4, 56, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Non-Secure EL1 timer FLAGS", 4, 60, L"0x%x", NULL, NULL, NULL, NULL}, + + {L"Virtual timer GSIV", 4, 64, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Virtual timer FLAGS", 4, 68, L"0x%x", NULL, NULL, NULL, NULL}, + + {L"Non-Secure EL2 timer GSIV", 4, 72, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Non-Secure EL2 timer FLAGS", 4, 76, L"0x%x", NULL, NULL, NULL, NULL}, + + {L"CntReadBase Physical address", 8, 80, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Platform Timer Count", 4, 88, L"%d", NULL, + (VOID**)&GtdtPlatformTimerCount, NULL, NULL}, + {L"Platform Timer Offset", 4, 92, L"0x%x", NULL, + (VOID**)&GtdtPlatformTimerOffset, NULL, NULL} +}; + +/** An ACPI_PARSER array describing the Platform timer header. +*/ +STATIC CONST ACPI_PARSER GtPlatformTimerHeaderParser[] = { + {L"Type", 1, 0, NULL, NULL, (VOID**)&PlatformTimerType, NULL, NULL}, + {L"Length", 2, 1, NULL, NULL, (VOID**)&PlatformTimerLength, NULL, NULL}, + {L"Reserved", 1, 3, NULL, NULL, NULL, NULL, NULL} +}; + +/** An ACPI_PARSER array describing the Platform GT Block. +*/ +STATIC CONST ACPI_PARSER GtBlockParser[] = { + {L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL}, + {L"Length", 2, 1, L"%d", NULL, (VOID**)&GtBlockLength, NULL, NULL}, + {L"Reserved", 1, 3, L"%x", NULL, NULL, NULL, NULL}, + {L"Physical address (CntCtlBase)", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Timer Count", 4, 12, L"%d", NULL, (VOID**)&GtBlockTimerCount, + ValidateGtBlockTimerCount, NULL}, + {L"Timer Offset", 4, 16, L"%d", NULL, (VOID**)&GtBlockTimerOffset, NULL, + NULL} +}; + +/** An ACPI_PARSER array describing the GT Block timer. +*/ +STATIC CONST ACPI_PARSER GtBlockTimerParser[] = { + {L"Frame Number", 1, 0, L"%d", NULL, NULL, NULL, NULL}, + {L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}, + {L"Physical address (CntBaseX)", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Physical address (CntEL0BaseX)", 8, 12, L"0x%lx", NULL, NULL, NULL, + NULL}, + {L"Physical Timer GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Physical Timer Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Virtual Timer GSIV", 4, 28, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Virtual Timer Flags", 4, 32, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Common Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** An ACPI_PARSER array describing the Platform Watchdog. +*/ +STATIC CONST ACPI_PARSER SBSAGenericWatchdogParser[] = { + {L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL}, + {L"Length", 2, 1, L"%d", NULL, NULL, NULL, NULL}, + {L"Reserved", 1, 3, L"%x", NULL, NULL, NULL, NULL}, + {L"RefreshFrame Physical address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"ControlFrame Physical address", 8, 12, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Watchdog Timer GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Watchdog Timer Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** This function validates the GT Block timer count. + + @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 +ValidateGtBlockTimerCount ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + UINT32 BlockTimerCount = *(UINT32*)Ptr; + if (BlockTimerCount > 8) { + IncrementErrorCount (); + Print ( + L"\nERROR: Timer Count = %d. Max Timer Count is 8.", + BlockTimerCount + ); + } +} + +/** This function parses the Platform GT Block. + + @param [in] Ptr Pointer to the start of the GT Block data. + @param [in] Length Length of the GT Block structure. +*/ +STATIC +VOID +DumpGTBlock ( + IN UINT8* Ptr, + IN UINT16 Length + ) +{ + UINT32 Index; + UINT32 Offset; + UINT16 GTBlockTimerLength; + + Offset = ParseAcpi ( + TRUE, + 2, + "GT Block", + Ptr, + Length, + PARSER_PARAMS (GtBlockParser) + ); + GTBlockTimerLength = (*GtBlockLength - Offset) / (*GtBlockTimerCount); + Length -= Offset; + + if (*GtBlockTimerCount != 0) { + Ptr += (*GtBlockTimerOffset); + Index = 0; + while ((Index < (*GtBlockTimerCount)) && (Length >= GTBlockTimerLength)) { + Offset = ParseAcpi ( + TRUE, + 2, + "GT Block Timer", + Ptr, + GTBlockTimerLength, + PARSER_PARAMS (GtBlockTimerParser) + ); + // Increment by GT Block Timer structure size + Ptr += Offset; + Length -= Offset; + Index++; + } + + if (Length != 0) { + IncrementErrorCount (); + Print ( + L"ERROR:GT Block Timer length mismatch. Unparsed %d bytes.\n", + Length + ); + } + } +} + +/** This function parses the Platform Watchdog timer. + + @param [in] Ptr Pointer to the start of the watchdog timer data. + @param [in] Length Length of the watchdog timer structure. +*/ +STATIC +VOID +DumpWatchdogTimer ( + IN UINT8* Ptr, + IN UINT16 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "SBSA Generic Watchdog", + Ptr, + Length, + PARSER_PARAMS (SBSAGenericWatchdogParser) + ); +} + +/** This function parses the ACPI GTDT table. + When trace is enabled this function parses the GTDT table and + traces the ACPI table fields. + + This function also parses the following platform timer structures: + - GT Block timer + - Watchdog timer + + 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 +ParseAcpiGtdt ( + IN BOOLEAN Trace, + IN UINT8* Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Index; + UINT8* TimerPtr; + + if (!Trace) { + return; + } + + ParseAcpi ( + TRUE, + 0, + "GTDT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (GtdtParser) + ); + + if (*GtdtPlatformTimerCount != 0) { + TimerPtr = Ptr + (*GtdtPlatformTimerOffset); + Index = 0; + do { + // Parse the Platform Timer Header + ParseAcpi ( + FALSE, + 0, + NULL, + TimerPtr, + 4, // GT Platform Timer structure header length. + PARSER_PARAMS (GtPlatformTimerHeaderParser) + ); + switch (*PlatformTimerType) { + case EFI_ACPI_6_2_GTDT_GT_BLOCK: + DumpGTBlock (TimerPtr, *PlatformTimerLength); + break; + case EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG: + DumpWatchdogTimer (TimerPtr, *PlatformTimerLength); + break; + default: + IncrementErrorCount (); + Print ( + L"ERROR: INVALID Platform Timer Type = %d\n", + *PlatformTimerType + ); + break; + } // switch + TimerPtr += (*PlatformTimerLength); + Index++; + } while (Index < *GtdtPlatformTimerCount); + } +}