RsdpParser.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /** @file
  2. RSDP table parser
  3. Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. @par Reference(s):
  6. - ACPI 6.2 Specification - Errata A, September 2017
  7. **/
  8. #include <Library/UefiLib.h>
  9. #include "AcpiParser.h"
  10. #include "AcpiTableParser.h"
  11. // Local Variables
  12. STATIC CONST UINT64 *XsdtAddress;
  13. /**
  14. This function validates the RSDT Address.
  15. @param [in] Ptr Pointer to the start of the field data.
  16. @param [in] Context Pointer to context specific information e.g. this
  17. could be a pointer to the ACPI table header.
  18. **/
  19. STATIC
  20. VOID
  21. EFIAPI
  22. ValidateRsdtAddress (
  23. IN UINT8 *Ptr,
  24. IN VOID *Context
  25. )
  26. {
  27. #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
  28. // Reference: Server Base Boot Requirements System Software on ARM Platforms
  29. // Section: 4.2.1.1 RSDP
  30. // Root System Description Pointer (RSDP), ACPI ? 5.2.5.
  31. // - Within the RSDP, the RsdtAddress field must be null (zero) and the
  32. // XsdtAddresss MUST be a valid, non-null, 64-bit value.
  33. UINT32 RsdtAddr;
  34. RsdtAddr = *(UINT32 *)Ptr;
  35. if (RsdtAddr != 0) {
  36. IncrementErrorCount ();
  37. Print (
  38. L"\nERROR: Rsdt Address = 0x%p. This must be NULL on ARM Platforms.",
  39. RsdtAddr
  40. );
  41. }
  42. #endif
  43. }
  44. /**
  45. This function validates the XSDT Address.
  46. @param [in] Ptr Pointer to the start of the field data.
  47. @param [in] Context Pointer to context specific information e.g. this
  48. could be a pointer to the ACPI table header.
  49. **/
  50. STATIC
  51. VOID
  52. EFIAPI
  53. ValidateXsdtAddress (
  54. IN UINT8 *Ptr,
  55. IN VOID *Context
  56. )
  57. {
  58. #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
  59. // Reference: Server Base Boot Requirements System Software on ARM Platforms
  60. // Section: 4.2.1.1 RSDP
  61. // Root System Description Pointer (RSDP), ACPI ? 5.2.5.
  62. // - Within the RSDP, the RsdtAddress field must be null (zero) and the
  63. // XsdtAddresss MUST be a valid, non-null, 64-bit value.
  64. UINT64 XsdtAddr;
  65. XsdtAddr = *(UINT64 *)Ptr;
  66. if (XsdtAddr == 0) {
  67. IncrementErrorCount ();
  68. Print (
  69. L"\nERROR: Xsdt Address = 0x%p. This must not be NULL on ARM Platforms.",
  70. XsdtAddr
  71. );
  72. }
  73. #endif
  74. }
  75. /**
  76. An array describing the ACPI RSDP Table.
  77. **/
  78. STATIC CONST ACPI_PARSER RsdpParser[] = {
  79. { L"Signature", 8, 0, NULL, Dump8Chars, NULL, NULL, NULL },
  80. { L"Checksum", 1, 8, L"0x%x", NULL, NULL, NULL, NULL },
  81. { L"Oem ID", 6, 9, NULL, Dump6Chars, NULL, NULL, NULL },
  82. { L"Revision", 1, 15, L"%d", NULL, NULL, NULL, NULL },
  83. { L"RSDT Address", 4, 16, L"0x%x", NULL, NULL, ValidateRsdtAddress, NULL },
  84. { L"Length", 4, 20, L"%d", NULL, NULL, NULL, NULL },
  85. { L"XSDT Address", 8, 24, L"0x%lx", NULL, (VOID **)&XsdtAddress,
  86. ValidateXsdtAddress, NULL },
  87. { L"Extended Checksum", 1, 32, L"0x%x", NULL, NULL, NULL, NULL },
  88. { L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }
  89. };
  90. /**
  91. This function parses the ACPI RSDP table.
  92. This function invokes the parser for the XSDT table.
  93. * Note - This function does not support parsing of RSDT table.
  94. This function also performs a RAW dump of the ACPI table and
  95. validates the checksum.
  96. @param [in] Trace If TRUE, trace the ACPI fields.
  97. @param [in] Ptr Pointer to the start of the buffer.
  98. @param [in] AcpiTableLength Length of the ACPI table.
  99. @param [in] AcpiTableRevision Revision of the ACPI table.
  100. **/
  101. VOID
  102. EFIAPI
  103. ParseAcpiRsdp (
  104. IN BOOLEAN Trace,
  105. IN UINT8 *Ptr,
  106. IN UINT32 AcpiTableLength,
  107. IN UINT8 AcpiTableRevision
  108. )
  109. {
  110. if (Trace) {
  111. DumpRaw (Ptr, AcpiTableLength);
  112. VerifyChecksum (TRUE, Ptr, AcpiTableLength);
  113. }
  114. ParseAcpi (
  115. Trace,
  116. 0,
  117. "RSDP",
  118. Ptr,
  119. AcpiTableLength,
  120. PARSER_PARAMS (RsdpParser)
  121. );
  122. // Check if the values used to control the parsing logic have been
  123. // successfully read.
  124. if (XsdtAddress == NULL) {
  125. IncrementErrorCount ();
  126. Print (
  127. L"ERROR: Insufficient table length. AcpiTableLength = %d." \
  128. L"RSDP parsing aborted.\n",
  129. AcpiTableLength
  130. );
  131. return;
  132. }
  133. // This code currently supports parsing of XSDT table only
  134. // and does not parse the RSDT table. Platforms provide the
  135. // RSDT to enable compatibility with ACPI 1.0 operating systems.
  136. // Therefore the RSDT should not be used on ARM platforms.
  137. if ((*XsdtAddress) == 0) {
  138. IncrementErrorCount ();
  139. Print (L"ERROR: XSDT Pointer is not set. RSDP parsing aborted.\n");
  140. return;
  141. }
  142. ProcessAcpiTable ((UINT8 *)(UINTN)(*XsdtAddress));
  143. }