}\r
\r
\r
+/**\r
+ Check if an array of bytes starts with an RSD PTR structure.\r
+\r
+ Checksum is ignored.\r
+\r
+ @param[in] Buffer The array to check.\r
+\r
+ @param[in] Size Number of bytes in Buffer.\r
+\r
+ @param[out] RsdpSize If the function returns EFI_SUCCESS, this parameter\r
+ contains the size of the detected RSD PTR structure.\r
+\r
+ @retval EFI_SUCCESS RSD PTR structure detected at the beginning of\r
+ Buffer, and its advertised size does not exceed\r
+ Size.\r
+\r
+ @retval EFI_PROTOCOL_ERROR RSD PTR structure detected at the beginning of\r
+ Buffer, but it has inconsistent size.\r
+\r
+ @retval EFI_NOT_FOUND RSD PTR structure not found.\r
+\r
+**/\r
+\r
+STATIC\r
+EFI_STATUS\r
+CheckRsdp (\r
+ IN CONST VOID *Buffer,\r
+ IN UINTN Size,\r
+ OUT UINTN *RsdpSize\r
+ )\r
+{\r
+ CONST UINT64 *Signature;\r
+ CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp1;\r
+ CONST EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp2;\r
+\r
+ if (Size < sizeof *Signature) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ Signature = Buffer;\r
+\r
+ if (*Signature != EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Signature found -- from this point on we can only report\r
+ // EFI_PROTOCOL_ERROR or EFI_SUCCESS.\r
+ //\r
+ if (Size < sizeof *Rsdp1) {\r
+ return EFI_PROTOCOL_ERROR;\r
+ }\r
+ Rsdp1 = Buffer;\r
+\r
+ if (Rsdp1->Reserved == 0) {\r
+ //\r
+ // ACPI 1.0 doesn't include the Length field\r
+ //\r
+ *RsdpSize = sizeof *Rsdp1;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (Size < sizeof *Rsdp2) {\r
+ return EFI_PROTOCOL_ERROR;\r
+ }\r
+ Rsdp2 = Buffer;\r
+\r
+ if (Size < Rsdp2->Length || Rsdp2->Length < sizeof *Rsdp2) {\r
+ return EFI_PROTOCOL_ERROR;\r
+ }\r
+\r
+ *RsdpSize = Rsdp2->Length;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
//\r
// We'll be saving the keys of installed tables so that we can roll them back\r
// in case of failure. 128 tables should be enough for anyone (TM).\r
Processed = 0;\r
while (Processed < TablesFileSize) {\r
UINTN Remaining;\r
+ UINTN RsdpSize;\r
EFI_ACPI_DESCRIPTION_HEADER *Probe;\r
\r
Remaining = TablesFileSize - Processed;\r
+\r
+ //\r
+ // See if we're looking at an RSD PTR structure.\r
+ //\r
+ RsdpSize = 0;\r
+ Status = CheckRsdp (Tables + Processed, Remaining, &RsdpSize);\r
+ if (Status == EFI_PROTOCOL_ERROR) {\r
+ //\r
+ // RSD PTR found but its size is inconsistent; abort processing. (Note\r
+ // that "RSD PTR found" excludes the NUL-padding case by definition.)\r
+ //\r
+ break;\r
+ }\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Consistent RSD PTR found, skip it.\r
+ //\r
+ DEBUG ((EFI_D_VERBOSE, "%a: \"%a\" offset 0x%016Lx: RSD PTR "\r
+ "Length=0x%08x\n", __FUNCTION__, FwCfgFile, (UINT64)Processed,\r
+ (UINT32)RsdpSize));\r
+ Processed += RsdpSize;\r
+ continue;\r
+ }\r
+ ASSERT (Status == EFI_NOT_FOUND);\r
+\r
+ //\r
+ // What we're looking at is not an RSD PTR structure; attempt to parse it\r
+ // as an ACPI table.\r
+ //\r
if (Remaining < sizeof *Probe) {\r
Status = EFI_PROTOCOL_ERROR;\r
break;\r