]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/CCode/Source/GenAcpiTable/GenAcpiTable.c
Add checking code for GenAcpiTable tools.
[mirror_edk2.git] / Tools / CCode / Source / GenAcpiTable / GenAcpiTable.c
index 7a413eacb0b1cc1248e4c4e7b3f91e90b17d2507..ec866d3370aa474afca138dd03533071b6141a94 100644 (file)
@@ -29,11 +29,21 @@ Abstract:
 #include "CommonLib.h"\r
 #include "EfiUtilityMsgs.h"\r
 \r
+//\r
+// Acpi Table definition\r
+//\r
+#include "Acpi.h"\r
+#include "Acpi1_0.h"\r
+#include "Acpi2_0.h"\r
+#include "Acpi3_0.h"\r
+#include "MemoryMappedConfigurationSpaceAccessTable.h"\r
+\r
 //\r
 // Version of this utility\r
 //\r
-#define UTILITY_NAME    "GenAcpiTable"\r
-#define UTILITY_VERSION "v0.11"\r
+#define UTILITY_NAME  "GenAcpiTable"\r
+#define UTILITY_MAJOR_VERSION 0\r
+#define UTILITY_MINOR_VERSION 11\r
 \r
 //\r
 // Define the max length of a filename\r
@@ -81,6 +91,12 @@ static STRING_LOOKUP  mSubsystemTypes[] = {
 //\r
 //  Function prototypes\r
 //\r
+static\r
+void\r
+Version (\r
+  VOID\r
+  );\r
+\r
 static\r
 void\r
 Usage (\r
@@ -94,6 +110,13 @@ ParseCommandLine (
   char      *Argv[]\r
   );\r
 \r
+static\r
+STATUS\r
+CheckAcpiTable (\r
+  VOID      *AcpiTable,\r
+  UINT32    Length\r
+  );\r
+\r
 static\r
 STATUS\r
 CheckPE32File (\r
@@ -281,7 +304,7 @@ Returns:
       goto Finish;\r
     }\r
 \r
-    if (strcmp (SectionHeader.Name, ".data") == 0) {\r
+    if (strcmp (SectionHeader.Name, ".data") == 0 || strcmp (SectionHeader.Name, ".sdata") == 0) {\r
       if (fseek (InFptr, SectionHeader.PointerToRawData, SEEK_SET) != 0) {\r
         Error (NULL, 0, 0, InFileName, "failed to seek to .data section");\r
         goto Finish;\r
@@ -296,6 +319,15 @@ Returns:
         Error (NULL, 0, 0, InFileName, "failed to .data section");\r
         goto Finish;\r
       }\r
+\r
+      //\r
+      // Check Acpi Table\r
+      //\r
+      if (CheckAcpiTable (Buffer, SectionHeader.Misc.VirtualSize) != STATUS_SUCCESS) {\r
+        Error (NULL, 0, 0, InFileName, "failed to check ACPI table");\r
+        goto Finish;\r
+      }\r
+\r
       //\r
       // Now open our output file\r
       //\r
@@ -341,6 +373,147 @@ Finish:
   return Status;\r
 }\r
 \r
+static\r
+STATUS\r
+CheckAcpiTable (\r
+  VOID      *AcpiTable,\r
+  UINT32    Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Check Acpi Table \r
+\r
+Arguments:\r
+\r
+  AcpiTable     Buffer for AcpiSection\r
+  Length        AcpiSection Length\r
+\r
+Returns:\r
+\r
+  0             success\r
+  non-zero      otherwise\r
+\r
+--*/\r
+{\r
+  EFI_ACPI_DESCRIPTION_HEADER                   *AcpiHeader;\r
+  EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *Facs;\r
+  UINT32                                        ExpectedLength;\r
+\r
+  AcpiHeader = (EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable;\r
+\r
+  //\r
+  // Generic check for AcpiTable length.\r
+  //\r
+  if (AcpiHeader->Length > Length) {\r
+    Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass AcpiTable Length check");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // Currently, we only check must-have tables: FADT, FACS, DSDT,\r
+  // and some important tables: MADT, MCFG.\r
+  //\r
+  switch (AcpiHeader->Signature) {\r
+\r
+  //\r
+  // "FACP" Fixed ACPI Description Table\r
+  //\r
+  case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:\r
+    switch (AcpiHeader->Revision) {\r
+    case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:\r
+      ExpectedLength = sizeof(EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE);\r
+      break;\r
+    case EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:\r
+      ExpectedLength = sizeof(EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE);\r
+      break;\r
+    case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:\r
+      ExpectedLength = sizeof(EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE);\r
+      break;\r
+    default:\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass FACP revision check");\r
+      return STATUS_ERROR;\r
+    }\r
+    if (ExpectedLength != AcpiHeader->Length) {\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass FACP Length check");\r
+      return STATUS_ERROR;\r
+    }\r
+    break;\r
+\r
+  //\r
+  // "FACS" Firmware ACPI Control Structure\r
+  //\r
+  case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:\r
+    Facs = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)AcpiTable;\r
+    if ((Facs->Version != 0) &&\r
+        (Facs->Version != EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
+        (Facs->Version != EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION)){\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass FACS version check");\r
+      return STATUS_ERROR;\r
+    }\r
+    if ((Facs->Length != sizeof(EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) &&\r
+        (Facs->Length != sizeof(EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) &&\r
+        (Facs->Length != sizeof(EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE))) {\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass FACS Length check");\r
+      return STATUS_ERROR;\r
+    }\r
+    break;\r
+\r
+  //\r
+  // "DSDT" Differentiated System Description Table\r
+  //\r
+  case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
+    if (AcpiHeader->Revision > EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION) {\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass DSDT revision check");\r
+      return STATUS_ERROR;\r
+    }\r
+    if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER)) {\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass DSDT Length check");\r
+      return STATUS_ERROR;\r
+    }\r
+    break;\r
+\r
+  //\r
+  // "APIC" Multiple APIC Description Table\r
+  //\r
+  case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:\r
+    if ((AcpiHeader->Revision != EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) &&\r
+        (AcpiHeader->Revision != EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) &&\r
+        (AcpiHeader->Revision != EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION)) {\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass APIC revision check");\r
+      return STATUS_ERROR;\r
+    }\r
+    if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT32) + sizeof(UINT32)) {\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass APIC Length check");\r
+      return STATUS_ERROR;\r
+    }\r
+    break;\r
+\r
+  //\r
+  // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table\r
+  //\r
+  case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:\r
+    if (AcpiHeader->Revision != EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) {\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass MCFG revision check");\r
+      return STATUS_ERROR;\r
+    }\r
+    if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT64)) {\r
+      Error (NULL, 0, 0, "CheckAcpiTable", "failed to pass MCFG Length check");\r
+      return STATUS_ERROR;\r
+    }\r
+    break;\r
+\r
+  //\r
+  // Other table pass check\r
+  //\r
+  default:\r
+    break;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
 static\r
 STATUS\r
 CheckPE32File (\r
@@ -489,6 +662,22 @@ Returns:
   Argc--;\r
   Argv++;\r
 \r
+  if (Argc < 1) {\r
+    Usage();\r
+    return STATUS_ERROR;\r
+  }\r
+  \r
+  if ((strcmp(Argv[0], "-h") == 0) || (strcmp(Argv[0], "--help") == 0) ||\r
+      (strcmp(Argv[0], "-?") == 0) || (strcmp(Argv[0], "/?") == 0)) {\r
+    Usage();\r
+    return STATUS_ERROR;\r
+  }\r
+  \r
+  if ((strcmp(Argv[0], "-V") == 0) || (strcmp(Argv[0], "--version") == 0)) {\r
+    Version();\r
+    return STATUS_ERROR;\r
+  }\r
+\r
   if (Argc != 2) {\r
     Usage ();\r
     return STATUS_ERROR;\r
@@ -506,6 +695,17 @@ Returns:
   return STATUS_SUCCESS;\r
 }\r
 \r
+static\r
+void\r
+Version (\r
+  VOID\r
+  )\r
+{\r
+  printf ("%s v%d.%d -EDK Utility for generating ACPI Table image from an EFI PE32 image.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+  printf ("Copyright (c) 1999-2006 Intel Corporation. All rights reserved.\n");\r
+}\r
+\r
+\r
 static\r
 void\r
 Usage (\r
@@ -529,15 +729,14 @@ Returns:
 {\r
   int               Index;\r
   static const char *Msg[] = {\r
-    UTILITY_NAME " version "UTILITY_VERSION " - Generate ACPI Table image utility",\r
-    "  Generate an ACPI Table image from an EFI PE32 image",\r
-    "  Usage: "UTILITY_NAME " InFileName OutFileName",\r
-    "    where:",\r
-    "      InFileName     - name of the input PE32 file",\r
-    "      OutFileName    - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,\r
-    "",\r
+    "\nUsage: "UTILITY_NAME " {-h|--help|-?|/?|-V|--version} InFileName OutFileName",\r
+    "  where:",\r
+    "    InFileName  - name of the input PE32 file",\r
+    "    OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,\r
     NULL\r
   };\r
+  \r
+  Version();\r
   for (Index = 0; Msg[Index] != NULL; Index++) {\r
     fprintf (stdout, "%s\n", Msg[Index]);\r
   }\r