--- /dev/null
+/** @file\r
+ FACS table parser\r
+\r
+ Copyright (c) 2019, ARM Limited. All rights reserved.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+ @par Reference(s):\r
+ - ACPI 6.3 Specification - January 2019\r
+**/\r
+\r
+#include <IndustryStandard/Acpi.h>\r
+#include <Library/UefiLib.h>\r
+#include "AcpiParser.h"\r
+#include "AcpiTableParser.h"\r
+\r
+/**\r
+ An ACPI_PARSER array describing the ACPI FACS Table.\r
+**/\r
+STATIC CONST ACPI_PARSER FacsParser[] = {\r
+ {L"Signature", 4, 0, L"%c%c%c%c", Dump4Chars, NULL, NULL, NULL},\r
+ {L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL},\r
+ {L"Hardware Signature", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
+ {L"Firmware Waking Vector", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},\r
+ {L"Global Lock", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},\r
+ {L"Flags", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},\r
+ {L"X Firmware Walking Vector", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL},\r
+ {L"Version", 1, 32, L"%d", NULL, NULL, NULL, NULL},\r
+ {L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL},\r
+ {L"OSPM Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL},\r
+ {L"Reserved", 8, 40, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL,\r
+ NULL},\r
+ {L"Reserved", 8, 48, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL,\r
+ NULL},\r
+ {L"Reserved", 8, 56, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL,\r
+ NULL}\r
+};\r
+\r
+/**\r
+ This function parses the ACPI FACS table.\r
+ When trace is enabled this function parses the FACS table and\r
+ traces the ACPI table fields.\r
+\r
+ This function also performs validation of the ACPI table fields.\r
+\r
+ @param [in] Trace If TRUE, trace the ACPI fields.\r
+ @param [in] Ptr Pointer to the start of the buffer.\r
+ @param [in] AcpiTableLength Length of the ACPI table.\r
+ @param [in] AcpiTableRevision Revision of the ACPI table.\r
+**/\r
+VOID\r
+EFIAPI\r
+ParseAcpiFacs (\r
+ IN BOOLEAN Trace,\r
+ IN UINT8* Ptr,\r
+ IN UINT32 AcpiTableLength,\r
+ IN UINT8 AcpiTableRevision\r
+ )\r
+{\r
+ if (!Trace) {\r
+ return;\r
+ }\r
+\r
+ ParseAcpi (\r
+ Trace,\r
+ 0,\r
+ "FACS",\r
+ Ptr,\r
+ AcpiTableLength,\r
+ PARSER_PARAMS (FacsParser)\r
+ );\r
+}\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
@par Reference(s):\r
- - ACPI 6.2 Specification - Errata A, September 2017\r
+ - ACPI 6.3 Specification - January 2019\r
**/\r
\r
#include <IndustryStandard/Acpi.h>\r
#include <Library/UefiLib.h>\r
#include "AcpiParser.h"\r
#include "AcpiTableParser.h"\r
+#include "AcpiView.h"\r
\r
// Local variables\r
STATIC CONST UINT32* DsdtAddress;\r
STATIC CONST UINT64* X_DsdtAddress;\r
+STATIC CONST UINT32* Flags;\r
+STATIC CONST UINT32* FirmwareCtrl;\r
+STATIC CONST UINT64* X_FirmwareCtrl;\r
STATIC CONST UINT8* FadtMinorRevision;\r
STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
\r
**/\r
#define HW_REDUCED_ACPI BIT20\r
\r
+/**\r
+ Offset to the FACS signature from the start of the FACS.\r
+**/\r
+#define FACS_SIGNATURE_OFFSET 0\r
+\r
+/**\r
+ Offset to the FACS revision from the start of the FACS.\r
+**/\r
+#define FACS_VERSION_OFFSET 32\r
+\r
+/**\r
+ Offset to the FACS length from the start of the FACS.\r
+**/\r
+#define FACS_LENGTH_OFFSET 4\r
+\r
/**\r
Get the ACPI XSDT header info.\r
**/\r
**/\r
STATIC CONST ACPI_PARSER FadtParser[] = {\r
PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
- {L"FIRMWARE_CTRL", 4, 36, L"0x%x", NULL, NULL, ValidateFirmwareCtrl, NULL},\r
+ {L"FIRMWARE_CTRL", 4, 36, L"0x%x", NULL, (VOID**)&FirmwareCtrl,\r
+ ValidateFirmwareCtrl, NULL},\r
{L"DSDT", 4, 40, L"0x%x", NULL, (VOID**)&DsdtAddress, NULL, NULL},\r
{L"Reserved", 1, 44, L"%x", NULL, NULL, NULL, NULL},\r
{L"Preferred_PM_Profile", 1, 45, L"0x%x", NULL, NULL, NULL, NULL},\r
{L"CENTURY", 1, 108, L"0x%x", NULL, NULL, NULL, NULL},\r
{L"IAPC_BOOT_ARCH", 2, 109, L"0x%x", NULL, NULL, NULL, NULL},\r
{L"Reserved", 1, 111, L"0x%x", NULL, NULL, NULL, NULL},\r
- {L"Flags", 4, 112, L"0x%x", NULL, NULL, ValidateFlags, NULL},\r
+ {L"Flags", 4, 112, L"0x%x", NULL, (VOID**)&Flags, ValidateFlags, NULL},\r
{L"RESET_REG", 12, 116, NULL, DumpGas, NULL, NULL, NULL},\r
{L"RESET_VALUE", 1, 128, L"0x%x", NULL, NULL, NULL, NULL},\r
{L"ARM_BOOT_ARCH", 2, 129, L"0x%x", NULL, NULL, NULL, NULL},\r
{L"FADT Minor Version", 1, 131, L"0x%x", NULL, (VOID**)&FadtMinorRevision,\r
NULL, NULL},\r
- {L"X_FIRMWARE_CTRL", 8, 132, L"0x%lx", NULL, NULL,\r
+ {L"X_FIRMWARE_CTRL", 8, 132, L"0x%lx", NULL, (VOID**)&X_FirmwareCtrl,\r
ValidateXFirmwareCtrl, NULL},\r
{L"X_DSDT", 8, 140, L"0x%lx", NULL, (VOID**)&X_DsdtAddress, NULL, NULL},\r
{L"X_PM1a_EVT_BLK", 12, 148, NULL, DumpGas, NULL, NULL, NULL},\r
IN UINT8 AcpiTableRevision\r
)\r
{\r
- UINT8* DsdtPtr;\r
+ EFI_STATUS Status;\r
+ UINT8* DsdtPtr;\r
+ UINT8* FirmwareCtrlPtr;\r
+ UINT32 FacsSignature;\r
+ UINT32 FacsLength;\r
+ UINT8 FacsRevision;\r
+ PARSE_ACPI_TABLE_PROC FacsParserProc;\r
\r
ParseAcpi (\r
Trace,\r
}\r
}\r
\r
+ // If X_FIRMWARE_CTRL is not zero then use X_FIRMWARE_CTRL and ignore\r
+ // FIRMWARE_CTRL, else use FIRMWARE_CTRL.\r
+ if ((X_FirmwareCtrl != NULL) && (*X_FirmwareCtrl != 0)) {\r
+ FirmwareCtrlPtr = (UINT8*)(UINTN)(*X_FirmwareCtrl);\r
+ } else if ((FirmwareCtrl != NULL) && (*FirmwareCtrl != 0)) {\r
+ FirmwareCtrlPtr = (UINT8*)(UINTN)(*FirmwareCtrl);\r
+ } else {\r
+ FirmwareCtrlPtr = NULL;\r
+ // if HW_REDUCED_ACPI flag is not set, both FIRMWARE_CTRL and\r
+ // X_FIRMWARE_CTRL cannot be zero, and the FACS Table must be\r
+ // present.\r
+ if ((Trace) &&\r
+ (Flags != NULL) &&\r
+ ((*Flags & EFI_ACPI_6_3_HW_REDUCED_ACPI) != 0)) {\r
+ IncrementErrorCount ();\r
+ Print (L"ERROR: No FACS table found, "\r
+ L"both X_FIRMWARE_CTRL and FIRMWARE_CTRL are zero.\n");\r
+ }\r
+ }\r
+\r
+ if (FirmwareCtrlPtr != NULL) {\r
+ // The FACS table does not have a standard ACPI table header. Therefore,\r
+ // the signature, length and version needs to be initially parsed.\r
+ // The FACS signature is 4 bytes starting at offset 0.\r
+ FacsSignature = *(UINT32*)(FirmwareCtrlPtr + FACS_SIGNATURE_OFFSET);\r
+\r
+ // The FACS length is 4 bytes starting at offset 4.\r
+ FacsLength = *(UINT32*)(FirmwareCtrlPtr + FACS_LENGTH_OFFSET);\r
+\r
+ // The FACS version is 1 byte starting at offset 32.\r
+ FacsRevision = *(UINT8*)(FirmwareCtrlPtr + FACS_VERSION_OFFSET);\r
+\r
+ Trace = ProcessTableReportOptions (\r
+ FacsSignature,\r
+ FirmwareCtrlPtr,\r
+ FacsLength\r
+ );\r
+\r
+ Status = GetParser (FacsSignature, &FacsParserProc);\r
+ if (EFI_ERROR (Status)) {\r
+ Print (\r
+ L"ERROR: No registered parser found for FACS.\n"\r
+ );\r
+ return;\r
+ }\r
+\r
+ FacsParserProc (\r
+ Trace,\r
+ FirmwareCtrlPtr,\r
+ FacsLength,\r
+ FacsRevision\r
+ );\r
+ }\r
+\r
// If X_DSDT is not zero then use X_DSDT and ignore DSDT,\r
// else use DSDT.\r
if (*X_DsdtAddress != 0) {\r