| /** @file | |
| RSDP table parser | |
| Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| @par Reference(s): | |
| - ACPI 6.2 Specification - Errata A, September 2017 | |
| **/ | |
| #include <Library/UefiLib.h> | |
| #include "AcpiParser.h" | |
| #include "AcpiTableParser.h" | |
| // Local Variables | |
| STATIC CONST UINT64 *XsdtAddress; | |
| /** | |
| This function validates the RSDT Address. | |
| @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 | |
| ValidateRsdtAddress ( | |
| IN UINT8 *Ptr, | |
| IN UINT32 Length, | |
| IN VOID *Context | |
| ) | |
| { | |
| #if defined (MDE_CPU_AARCH64) | |
| // Reference: Server Base Boot Requirements System Software on ARM Platforms | |
| // Section: 4.2.1.1 RSDP | |
| // Root System Description Pointer (RSDP), ACPI ? 5.2.5. | |
| // - Within the RSDP, the RsdtAddress field must be null (zero) and the | |
| // XsdtAddresss MUST be a valid, non-null, 64-bit value. | |
| UINT32 RsdtAddr; | |
| RsdtAddr = *(UINT32 *)Ptr; | |
| if (RsdtAddr != 0) { | |
| IncrementErrorCount (); | |
| Print ( | |
| L"\nERROR: Rsdt Address = 0x%p. This must be NULL on ARM Platforms.", | |
| RsdtAddr | |
| ); | |
| } | |
| #endif | |
| } | |
| /** | |
| This function validates the XSDT Address. | |
| @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 | |
| ValidateXsdtAddress ( | |
| IN UINT8 *Ptr, | |
| IN UINT32 Length, | |
| IN VOID *Context | |
| ) | |
| { | |
| #if defined (MDE_CPU_AARCH64) | |
| // Reference: Server Base Boot Requirements System Software on ARM Platforms | |
| // Section: 4.2.1.1 RSDP | |
| // Root System Description Pointer (RSDP), ACPI ? 5.2.5. | |
| // - Within the RSDP, the RsdtAddress field must be null (zero) and the | |
| // XsdtAddresss MUST be a valid, non-null, 64-bit value. | |
| UINT64 XsdtAddr; | |
| XsdtAddr = *(UINT64 *)Ptr; | |
| if (XsdtAddr == 0) { | |
| IncrementErrorCount (); | |
| Print ( | |
| L"\nERROR: Xsdt Address = 0x%p. This must not be NULL on ARM Platforms.", | |
| XsdtAddr | |
| ); | |
| } | |
| #endif | |
| } | |
| /** | |
| An array describing the ACPI RSDP Table. | |
| **/ | |
| STATIC CONST ACPI_PARSER RsdpParser[] = { | |
| { L"Signature", 8, 0, NULL, Dump8Chars, NULL, NULL, NULL }, | |
| { L"Checksum", 1, 8, L"0x%x", NULL, NULL, NULL, NULL }, | |
| { L"Oem ID", 6, 9, NULL, Dump6Chars, NULL, NULL, NULL }, | |
| { L"Revision", 1, 15, L"%d", NULL, NULL, NULL, NULL }, | |
| { L"RSDT Address", 4, 16, L"0x%x", NULL, NULL, ValidateRsdtAddress, NULL }, | |
| { L"Length", 4, 20, L"%d", NULL, NULL, NULL, NULL }, | |
| { L"XSDT Address", 8, 24, L"0x%lx", NULL, (VOID **)&XsdtAddress, | |
| ValidateXsdtAddress, NULL }, | |
| { L"Extended Checksum", 1, 32, L"0x%x", NULL, NULL, NULL, NULL }, | |
| { L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL } | |
| }; | |
| /** | |
| This function parses the ACPI RSDP table. | |
| This function invokes the parser for the XSDT table. | |
| * Note - This function does not support parsing of RSDT table. | |
| This function also performs a RAW dump of the ACPI table and | |
| validates the checksum. | |
| @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 | |
| ParseAcpiRsdp ( | |
| IN BOOLEAN Trace, | |
| IN UINT8 *Ptr, | |
| IN UINT32 AcpiTableLength, | |
| IN UINT8 AcpiTableRevision | |
| ) | |
| { | |
| if (Trace) { | |
| DumpRaw (Ptr, AcpiTableLength); | |
| VerifyChecksum (TRUE, Ptr, AcpiTableLength); | |
| } | |
| ParseAcpi ( | |
| Trace, | |
| 0, | |
| "RSDP", | |
| Ptr, | |
| AcpiTableLength, | |
| PARSER_PARAMS (RsdpParser) | |
| ); | |
| // Check if the values used to control the parsing logic have been | |
| // successfully read. | |
| if (XsdtAddress == NULL) { | |
| IncrementErrorCount (); | |
| Print ( | |
| L"ERROR: Insufficient table length. AcpiTableLength = %d." \ | |
| L"RSDP parsing aborted.\n", | |
| AcpiTableLength | |
| ); | |
| return; | |
| } | |
| // This code currently supports parsing of XSDT table only | |
| // and does not parse the RSDT table. Platforms provide the | |
| // RSDT to enable compatibility with ACPI 1.0 operating systems. | |
| // Therefore the RSDT should not be used on ARM platforms. | |
| if ((*XsdtAddress) == 0) { | |
| IncrementErrorCount (); | |
| Print (L"ERROR: XSDT Pointer is not set. RSDP parsing aborted.\n"); | |
| return; | |
| } | |
| ProcessAcpiTable ((UINT8 *)(UINTN)(*XsdtAddress)); | |
| } |