| /** @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; | |
| } |