mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 11:13:53 +01:00 
			
		
		
		
	Check if XsdtAddress pointer has been successfully updated before it is used for further table parsing. Signed-off-by: Krzysztof Koch <krzysztof.koch@arm.com>
		
			
				
	
	
		
			165 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   RSDP table parser
 | |
| 
 | |
|   Copyright (c) 2016 - 2019, 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] 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 VOID*  Context
 | |
|   )
 | |
| {
 | |
| #if defined(MDE_CPU_ARM) || 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] 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 VOID*  Context
 | |
|   )
 | |
| {
 | |
| #if defined(MDE_CPU_ARM) || 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));
 | |
| }
 |