Correct some linux building issue and wrong file header
[people/mcb30/edk2.git] / edk2 / Tools / CCode / Source / GenAcpiTable / GenAcpiTable.c
index f1efa3c..5638c3f 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c)  2004-2006 Intel Corporation. All rights reserved\r
+Copyright (c) 2004 - 2007 Intel Corporation. All rights reserved\r
 This program and the accompanying materials are licensed and made available \r
 under the terms and conditions of the BSD License which accompanies this \r
 distribution.  The full text of the license may be found at\r
@@ -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
@@ -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