mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-04 05:25:45 +01:00 
			
		
		
		
	As of now, the print-formatter implemented by the FNPTR_PRINT_FORMATTER function pointer takes two parameters, the format string and the pointer to the field. For cases where the print-formatter has to have access to the length of the field, there is no clean way to currently do it. In order to resolve this, update the print-formatter's prototype to take the length of the field as a third parameter. This change should improve the overall robustness and flexibility of AcpiView. Signed-off-by: Rohit Mathew <Rohit.Mathew@arm.com> Cc: James Morse <james.Morse@arm.com> Cc: Sami Mujawar <sami.mujawar@arm.com> Cc: Thomas Abraham <thomas.abraham@arm.com> Cc: Zhichao Gao <zhichao.gao@intel.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
		
			
				
	
	
		
			289 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			289 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  ERST table parser
 | 
						|
 | 
						|
  Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
 | 
						|
  Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
  @par Reference(s):
 | 
						|
    - ACPI 6.5 Specification - August 2022
 | 
						|
**/
 | 
						|
 | 
						|
#include <IndustryStandard/Acpi.h>
 | 
						|
#include <Library/UefiLib.h>
 | 
						|
#include "AcpiParser.h"
 | 
						|
#include "AcpiTableParser.h"
 | 
						|
 | 
						|
// Local variables
 | 
						|
STATIC ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;
 | 
						|
STATIC UINT32                        *InstructionEntryCount;
 | 
						|
 | 
						|
/**
 | 
						|
  An array of strings describing the Erst actions
 | 
						|
**/
 | 
						|
STATIC CONST CHAR16  *ErstActionTable[] = {
 | 
						|
  L"BEGIN_WRITE_OPERATION",
 | 
						|
  L"BEGIN_READ_OPERATION",
 | 
						|
  L"BEGIN_CLEAR_OPERATION",
 | 
						|
  L"END_OPERATION",
 | 
						|
  L"SET_RECORD_OFFSET",
 | 
						|
  L"EXECUTE_OPERATION",
 | 
						|
  L"CHECK_BUSY_STATUS",
 | 
						|
  L"GET_COMMAND_STATUS",
 | 
						|
  L"GET_RECORD_IDENTIFIER",
 | 
						|
  L"SET_RECORD_IDENTIFIER",
 | 
						|
  L"GET_RECORD_COUNT",
 | 
						|
  L"BEGIN_DUMMY_WRITE_OPERATION",
 | 
						|
  L"RESERVED",
 | 
						|
  L"GET_ERROR_LOG_ADDRESS_RANGE",
 | 
						|
  L"GET_ERROR_LOG_ADDRESS_RANGE_LENGTH",
 | 
						|
  L"GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES",
 | 
						|
  L"GET_EXECUTE_OPERATION_TIMINGS"
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  An array of strings describing the Erst instructions
 | 
						|
**/
 | 
						|
STATIC CONST CHAR16  *ErstInstructionTable[] = {
 | 
						|
  L"READ_REGISTER",
 | 
						|
  L"READ_REGISTER_VALUE",
 | 
						|
  L"WRITE_REGISTER",
 | 
						|
  L"WRITE_REGISTER_VALUE",
 | 
						|
  L"NOOP",
 | 
						|
  L"LOAD_VAR1",
 | 
						|
  L"LOAD_VAR2",
 | 
						|
  L"STORE_VAR1",
 | 
						|
  L"ADD",
 | 
						|
  L"SUBTRACT",
 | 
						|
  L"ADD_VALUE",
 | 
						|
  L"SUBTRACT_VALUE",
 | 
						|
  L"STALL",
 | 
						|
  L"STALL_WHILE_TRUE",
 | 
						|
  L"SKIP_NEXT_INSTRUCTION_IF_TRUE",
 | 
						|
  L"GOTO",
 | 
						|
  L"SET_SRC_ADDRESS_BASE",
 | 
						|
  L"SET_DST_ADDRESS_BASE",
 | 
						|
  L"MOVE_DATA"
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Validate Erst action.
 | 
						|
 | 
						|
  @param [in] Ptr       Pointer to the start of the field data.
 | 
						|
  @param [in] Length    Length of the field.
 | 
						|
  @param [in] Context   Pointer to context specific information e.g. this
 | 
						|
                        could be a pointer to the ACPI table header.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
ValidateErstAction (
 | 
						|
  IN UINT8   *Ptr,
 | 
						|
  IN UINT32  Length,
 | 
						|
  IN VOID    *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (*Ptr > EFI_ACPI_6_4_ERST_GET_EXECUTE_OPERATION_TIMINGS) {
 | 
						|
    IncrementErrorCount ();
 | 
						|
    Print (L"\nError: 0x%02x is not a valid action encoding", *Ptr);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Validate Erst instruction.
 | 
						|
 | 
						|
  @param [in] Ptr       Pointer to the start of the field data.
 | 
						|
  @param [in] Length    Length of the field.
 | 
						|
  @param [in] Context   Pointer to context specific information e.g. this
 | 
						|
                        could be a pointer to the ACPI table header.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
ValidateErstInstruction (
 | 
						|
  IN UINT8   *Ptr,
 | 
						|
  IN UINT32  Length,
 | 
						|
  IN VOID    *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (*Ptr > EFI_ACPI_6_4_ERST_MOVE_DATA) {
 | 
						|
    IncrementErrorCount ();
 | 
						|
    Print (L"\nError: 0x%02x is not a valid instruction encoding", *Ptr);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Validate Erst flags.
 | 
						|
 | 
						|
  @param [in] Ptr       Pointer to the start of the field data.
 | 
						|
  @param [in] Length    Length of the field.
 | 
						|
  @param [in] Context   Pointer to context specific information e.g. this
 | 
						|
                        could be a pointer to the ACPI table header.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
ValidateErstFlags (
 | 
						|
  IN UINT8   *Ptr,
 | 
						|
  IN UINT32  Length,
 | 
						|
  IN VOID    *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((*Ptr & 0xfe) != 0) {
 | 
						|
    IncrementErrorCount ();
 | 
						|
    Print (L"\nError: Reserved Flag bits not set to 0");
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Looks up and prints the string corresponding to the index.
 | 
						|
 | 
						|
  @param [in] Table      Lookup table.
 | 
						|
  @param [in] Index      Entry to print.
 | 
						|
  @param [in] NumEntries Number of valid entries in the table.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
FormatByte (
 | 
						|
  IN CONST CHAR16  *Table[],
 | 
						|
  IN UINT8         Index,
 | 
						|
  IN UINT8         NumEntries
 | 
						|
  )
 | 
						|
{
 | 
						|
  CONST CHAR16  *String;
 | 
						|
 | 
						|
  if (Index < NumEntries) {
 | 
						|
    String = Table[Index];
 | 
						|
  } else {
 | 
						|
    String = L"**INVALID**";
 | 
						|
  }
 | 
						|
 | 
						|
  Print (
 | 
						|
    L"0x%02x (%s)",
 | 
						|
    Index,
 | 
						|
    String
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Prints the Erst Action.
 | 
						|
 | 
						|
  @param [in] Format  Optional format string for tracing the data.
 | 
						|
  @param [in] Ptr     Pointer to the Action byte.
 | 
						|
  @param [in] Length  Length of the field.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
DumpErstAction (
 | 
						|
  IN CONST CHAR16  *Format OPTIONAL,
 | 
						|
  IN UINT8         *Ptr,
 | 
						|
  IN UINT32        Length
 | 
						|
  )
 | 
						|
{
 | 
						|
  FormatByte (ErstActionTable, *Ptr, ARRAY_SIZE (ErstActionTable));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Prints the Erst Instruction.
 | 
						|
 | 
						|
  @param [in] Format  Optional format string for tracing the data.
 | 
						|
  @param [in] Ptr     Pointer to the Instruction byte.
 | 
						|
  @param [in] Length  Length of the field.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
DumpErstInstruction (
 | 
						|
  IN CONST CHAR16  *Format OPTIONAL,
 | 
						|
  IN UINT8         *Ptr,
 | 
						|
  IN UINT32        Length
 | 
						|
  )
 | 
						|
{
 | 
						|
  FormatByte (ErstInstructionTable, *Ptr, ARRAY_SIZE (ErstInstructionTable));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  An ACPI_PARSER array describing the ACPI ERST Table.
 | 
						|
**/
 | 
						|
STATIC CONST ACPI_PARSER  ErstParser[] = {
 | 
						|
  PARSE_ACPI_HEADER (&AcpiHdrInfo),
 | 
						|
  { L"Serialization Header Size",  4,  36, L"0x%x", NULL, NULL,                            NULL, NULL },
 | 
						|
  { L"Reserved",                   4,  40, L"0x%x", NULL, NULL,                            NULL, NULL },
 | 
						|
  { L"Instruction Entry Count",    4,  44, L"0x%x", NULL, (VOID **)&InstructionEntryCount, NULL, NULL }
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  An ACPI_PARSER array describing the Serialization Instruction Entry structure.
 | 
						|
**/
 | 
						|
STATIC CONST ACPI_PARSER  SerializationInstructionEntryParser[] = {
 | 
						|
  { L"Serialization Action", 1,  0,  L"0x%x",   DumpErstAction,      NULL, ValidateErstAction,      NULL },
 | 
						|
  { L"Instruction",          1,  1,  L"0x%x",   DumpErstInstruction, NULL, ValidateErstInstruction, NULL },
 | 
						|
  { L"Flags",                1,  2,  L"0x%x",   NULL,                NULL, ValidateErstFlags,       NULL },
 | 
						|
  { L"Reserved",             1,  3,  L"0x%x",   NULL,                NULL, NULL,                    NULL },
 | 
						|
  { L"Register Region",      12, 4,  NULL,      DumpGas,             NULL, NULL,                    NULL },
 | 
						|
  { L"Value",                8,  16, L"0x%llx", NULL,                NULL, NULL,                    NULL },
 | 
						|
  { L"Mask",                 8,  24, L"0x%llx", NULL,                NULL, NULL,                    NULL }
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  This function parses the ACPI ERST table.
 | 
						|
  When trace is enabled this function parses the ERST 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
 | 
						|
ParseAcpiErst (
 | 
						|
  IN BOOLEAN  Trace,
 | 
						|
  IN UINT8    *Ptr,
 | 
						|
  IN UINT32   AcpiTableLength,
 | 
						|
  IN UINT8    AcpiTableRevision
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32  Offset;
 | 
						|
 | 
						|
  if (!Trace) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  Offset = ParseAcpi (
 | 
						|
             Trace,
 | 
						|
             0,
 | 
						|
             "ERST",
 | 
						|
             Ptr,
 | 
						|
             AcpiTableLength,
 | 
						|
             PARSER_PARAMS (ErstParser)
 | 
						|
             );
 | 
						|
 | 
						|
  if (sizeof (EFI_ACPI_6_4_ERST_SERIALIZATION_INSTRUCTION_ENTRY)*(*InstructionEntryCount) != (AcpiTableLength - Offset)) {
 | 
						|
    IncrementErrorCount ();
 | 
						|
    Print (
 | 
						|
      L"ERROR: Invalid InstructionEntryCount. " \
 | 
						|
      L"Count = %d. Offset = %d. AcpiTableLength = %d.\n",
 | 
						|
      *InstructionEntryCount,
 | 
						|
      Offset,
 | 
						|
      AcpiTableLength
 | 
						|
      );
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  while (Offset < AcpiTableLength) {
 | 
						|
    Offset += ParseAcpi (
 | 
						|
                Trace,
 | 
						|
                2,
 | 
						|
                "Serialization Action",
 | 
						|
                Ptr + Offset,
 | 
						|
                (AcpiTableLength - Offset),
 | 
						|
                PARSER_PARAMS (SerializationInstructionEntryParser)
 | 
						|
                );
 | 
						|
  }
 | 
						|
}
 |