blob: 9cdfcb3fae2aa85d3ed3835ae90f5230f685e0fa [file] [log] [blame]
/** @file
Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Glossary:
- Sbbr or SBBR - Server Base Boot Requirements
@par Reference(s):
- Arm Server Base Boot Requirements 1.2, September 2019
**/
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/ShellLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/AcpiViewCommandLib.h>
#include "AcpiParser.h"
#include "AcpiTableParser.h"
#include "AcpiView.h"
#include "AcpiViewConfig.h"
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
#include "Arm/SbbrValidator.h"
#endif
STATIC UINT32 mTableCount;
STATIC UINT32 mBinTableCount;
/**
This function dumps the ACPI table to a file.
@param [in] Ptr Pointer to the ACPI table data.
@param [in] Length The length of the ACPI table.
@retval TRUE Success.
@retval FALSE Failure.
**/
STATIC
BOOLEAN
DumpAcpiTableToFile (
IN CONST UINT8 *Ptr,
IN CONST UINTN Length
)
{
CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
UINTN TransferBytes;
SELECTED_ACPI_TABLE *SelectedTable;
GetSelectedAcpiTable (&SelectedTable);
UnicodeSPrint (
FileNameBuffer,
sizeof (FileNameBuffer),
L".\\%s%04d.bin",
SelectedTable->Name,
mBinTableCount++
);
Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer);
TransferBytes = ShellDumpBufferToFile (FileNameBuffer, Ptr, Length);
return (Length == TransferBytes);
}
/**
This function processes the table reporting options for the ACPI table.
@param [in] Signature The ACPI table Signature.
@param [in] TablePtr Pointer to the ACPI table data.
@param [in] Length The length fo the ACPI table.
@retval Returns TRUE if the ACPI table should be traced.
**/
BOOLEAN
ProcessTableReportOptions (
IN CONST UINT32 Signature,
IN CONST UINT8 *TablePtr,
IN CONST UINT32 Length
)
{
UINTN OriginalAttribute;
UINT8 *SignaturePtr;
BOOLEAN Log;
BOOLEAN HighLight;
SELECTED_ACPI_TABLE *SelectedTable;
//
// set local variables to suppress incorrect compiler/analyzer warnings
//
OriginalAttribute = 0;
SignaturePtr = (UINT8 *)(UINTN)&Signature;
Log = FALSE;
HighLight = GetColourHighlighting ();
GetSelectedAcpiTable (&SelectedTable);
switch (GetReportOption ()) {
case ReportAll:
Log = TRUE;
break;
case ReportSelected:
if (Signature == SelectedTable->Type) {
Log = TRUE;
SelectedTable->Found = TRUE;
}
break;
case ReportTableList:
if (mTableCount == 0) {
if (HighLight) {
OriginalAttribute = gST->ConOut->Mode->Attribute;
gST->ConOut->SetAttribute (
gST->ConOut,
EFI_TEXT_ATTR (
EFI_CYAN,
((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
)
);
}
Print (L"\nInstalled Table(s):\n");
if (HighLight) {
gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
}
}
Print (
L"\t%4d. %c%c%c%c\n",
++mTableCount,
SignaturePtr[0],
SignaturePtr[1],
SignaturePtr[2],
SignaturePtr[3]
);
break;
case ReportDumpBinFile:
if (Signature == SelectedTable->Type) {
SelectedTable->Found = TRUE;
DumpAcpiTableToFile (TablePtr, Length);
}
break;
case ReportMax:
// We should never be here.
// This case is only present to prevent compiler warning.
break;
} // switch
if (Log) {
if (HighLight) {
OriginalAttribute = gST->ConOut->Mode->Attribute;
gST->ConOut->SetAttribute (
gST->ConOut,
EFI_TEXT_ATTR (
EFI_LIGHTBLUE,
((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
)
);
}
Print (
L"\n\n --------------- %c%c%c%c Table --------------- \n\n",
SignaturePtr[0],
SignaturePtr[1],
SignaturePtr[2],
SignaturePtr[3]
);
if (HighLight) {
gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
}
}
return Log;
}
/**
This function iterates the configuration table entries in the
system table, retrieves the RSDP pointer and starts parsing the ACPI tables.
@param [in] SystemTable Pointer to the EFI system table.
@retval Returns EFI_NOT_FOUND if the RSDP pointer is not found.
Returns EFI_UNSUPPORTED if the RSDP version is less than 2.
Returns EFI_SUCCESS if successful.
**/
EFI_STATUS
EFIAPI
AcpiView (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINTN Index;
EFI_CONFIGURATION_TABLE *EfiConfigurationTable;
BOOLEAN FoundAcpiTable;
UINTN OriginalAttribute;
UINTN PrintAttribute;
EREPORT_OPTION ReportOption;
UINT8 *RsdpPtr;
UINT32 RsdpLength;
UINT8 RsdpRevision;
PARSE_ACPI_TABLE_PROC RsdpParserProc;
BOOLEAN Trace;
SELECTED_ACPI_TABLE *SelectedTable;
//
// set local variables to suppress incorrect compiler/analyzer warnings
//
EfiConfigurationTable = NULL;
OriginalAttribute = 0;
// Reset Table counts
mTableCount = 0;
mBinTableCount = 0;
// Reset The error/warning counters
ResetErrorCount ();
ResetWarningCount ();
// Retrieve the user selection of ACPI table to process
GetSelectedAcpiTable (&SelectedTable);
// Search the table for an entry that matches the ACPI Table Guid
FoundAcpiTable = FALSE;
for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
if (CompareGuid (
&gEfiAcpiTableGuid,
&(SystemTable->ConfigurationTable[Index].VendorGuid)
))
{
EfiConfigurationTable = &SystemTable->ConfigurationTable[Index];
FoundAcpiTable = TRUE;
break;
}
}
if (FoundAcpiTable) {
RsdpPtr = (UINT8 *)EfiConfigurationTable->VendorTable;
// The RSDP revision is 1 byte starting at offset 15
RsdpRevision = *(RsdpPtr + RSDP_REVISION_OFFSET);
if (RsdpRevision < 2) {
Print (
L"ERROR: RSDP version less than 2 is not supported.\n"
);
return EFI_UNSUPPORTED;
}
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
if (GetMandatoryTableValidate ()) {
ArmSbbrResetTableCounts ();
}
#endif
// The RSDP length is 4 bytes starting at offset 20
RsdpLength = *(UINT32 *)(RsdpPtr + RSDP_LENGTH_OFFSET);
Trace = ProcessTableReportOptions (RSDP_TABLE_INFO, RsdpPtr, RsdpLength);
Status = GetParser (RSDP_TABLE_INFO, &RsdpParserProc);
if (EFI_ERROR (Status)) {
Print (
L"ERROR: No registered parser found for RSDP.\n"
);
return Status;
}
RsdpParserProc (
Trace,
RsdpPtr,
RsdpLength,
RsdpRevision
);
} else {
IncrementErrorCount ();
Print (
L"ERROR: Failed to find ACPI Table Guid in System Configuration Table.\n"
);
return EFI_NOT_FOUND;
}
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
if (GetMandatoryTableValidate ()) {
ArmSbbrReqsValidate ((ARM_SBBR_VERSION)GetMandatoryTableSpec ());
}
#endif
ReportOption = GetReportOption ();
if (ReportTableList != ReportOption) {
if (((ReportSelected == ReportOption) ||
(ReportDumpBinFile == ReportOption)) &&
(!SelectedTable->Found))
{
Print (L"\nRequested ACPI Table not found.\n");
} else if (GetConsistencyChecking () &&
(ReportDumpBinFile != ReportOption))
{
OriginalAttribute = gST->ConOut->Mode->Attribute;
Print (L"\nTable Statistics:\n");
if (GetColourHighlighting ()) {
PrintAttribute = (GetErrorCount () > 0) ?
EFI_TEXT_ATTR (
EFI_RED,
((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
) :
OriginalAttribute;
gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
}
Print (L"\t%d Error(s)\n", GetErrorCount ());
if (GetColourHighlighting ()) {
PrintAttribute = (GetWarningCount () > 0) ?
EFI_TEXT_ATTR (
EFI_RED,
((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
) :
OriginalAttribute;
gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
}
Print (L"\t%d Warning(s)\n", GetWarningCount ());
if (GetColourHighlighting ()) {
gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
}
}
}
return EFI_SUCCESS;
}