123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- /** @file
- GTDT table parser
- Copyright (c) 2016 - 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- @par Reference(s):
- - ACPI 6.4 Specification - January 2021
- **/
- #include <IndustryStandard/Acpi.h>
- #include <Library/UefiLib.h>
- #include "AcpiParser.h"
- #include "AcpiTableParser.h"
- #include "AcpiViewConfig.h"
- // "The number of GT Block Timers must be less than or equal to 8"
- #define GT_BLOCK_TIMER_COUNT_MAX 8
- // 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 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
- )
- {
- UINT32 BlockTimerCount;
- BlockTimerCount = *(UINT32 *)Ptr;
- if (BlockTimerCount > GT_BLOCK_TIMER_COUNT_MAX) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Timer Count = %d. Max Timer Count is %d.",
- BlockTimerCount,
- GT_BLOCK_TIMER_COUNT_MAX
- );
- }
- }
- /**
- This function validates the GT Frame Number.
- @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
- ValidateGtFrameNumber (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
- {
- UINT8 FrameNumber;
- FrameNumber = *(UINT8 *)Ptr;
- if (FrameNumber >= GT_BLOCK_TIMER_COUNT_MAX) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: GT Frame Number = %d. GT Frame Number must be in range 0-%d.",
- FrameNumber,
- GT_BLOCK_TIMER_COUNT_MAX - 1
- );
- }
- }
- /**
- 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 },
- { L"Virtual EL2 Timer GSIV", 4, 96, L"0x%x", NULL, NULL,NULL, NULL },
- { L"Virtual EL2 Timer Flags", 4, 100, L"0x%x", NULL, NULL,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, NULL, 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, ValidateGtFrameNumber, 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 ArmGenericWatchdogParser[] = {
- { 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 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;
- ParseAcpi (
- TRUE,
- 2,
- "GT Block",
- Ptr,
- Length,
- PARSER_PARAMS (GtBlockParser)
- );
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((GtBlockTimerCount == NULL) ||
- (GtBlockTimerOffset == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient GT Block Structure length. Length = %d.\n",
- Length
- );
- return;
- }
- Offset = *GtBlockTimerOffset;
- Index = 0;
- // Parse the specified number of GT Block Timer Structures or the GT Block
- // Structure buffer length. Whichever is minimum.
- while ((Index++ < *GtBlockTimerCount) &&
- (Offset < Length))
- {
- Offset += ParseAcpi (
- TRUE,
- 2,
- "GT Block Timer",
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (GtBlockTimerParser)
- );
- }
- }
- /**
- 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,
- "Arm Generic Watchdog",
- Ptr,
- Length,
- PARSER_PARAMS (ArmGenericWatchdogParser)
- );
- }
- /**
- 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;
- UINT32 Offset;
- UINT8 *TimerPtr;
- if (!Trace) {
- return;
- }
- ParseAcpi (
- TRUE,
- 0,
- "GTDT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (GtdtParser)
- );
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((GtdtPlatformTimerCount == NULL) ||
- (GtdtPlatformTimerOffset == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient table length. AcpiTableLength = %d.\n",
- AcpiTableLength
- );
- return;
- }
- TimerPtr = Ptr + *GtdtPlatformTimerOffset;
- Offset = *GtdtPlatformTimerOffset;
- Index = 0;
- // Parse the specified number of Platform Timer Structures or the GTDT
- // buffer length. Whichever is minimum.
- while ((Index++ < *GtdtPlatformTimerCount) &&
- (Offset < AcpiTableLength))
- {
- // Parse the Platform Timer Header to obtain Length and Type
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- TimerPtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (GtPlatformTimerHeaderParser)
- );
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((PlatformTimerType == NULL) ||
- (PlatformTimerLength == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"Platform Timer Structure header. Length = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
- // Validate Platform Timer Structure length
- if ((*PlatformTimerLength == 0) ||
- ((Offset + (*PlatformTimerLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Platform Timer Structure length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *PlatformTimerLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
- switch (*PlatformTimerType) {
- case EFI_ACPI_6_4_GTDT_GT_BLOCK:
- DumpGTBlock (TimerPtr, *PlatformTimerLength);
- break;
- case EFI_ACPI_6_4_GTDT_ARM_GENERIC_WATCHDOG:
- DumpWatchdogTimer (TimerPtr, *PlatformTimerLength);
- break;
- default:
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Platform Timer Type = %d\n",
- *PlatformTimerType
- );
- break;
- } // switch
- TimerPtr += *PlatformTimerLength;
- Offset += *PlatformTimerLength;
- } // while
- }
|