]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
ShellPkg: acpiview: Add -r parameter for table requirements validation
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / AcpiParser.c
index 318f386fda165146bad49f9edbc111d4e218db98..3f12a33050a4e4ab3be2187c90ef8dcf0882283d 100644 (file)
@@ -1,14 +1,8 @@
-/**\r
+/** @file\r
   ACPI parser\r
 \r
-  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 **/\r
 \r
 #include <Uefi.h>\r
@@ -21,8 +15,18 @@ STATIC UINT32   gIndent;
 STATIC UINT32   mTableErrorCount;\r
 STATIC UINT32   mTableWarningCount;\r
 \r
-/** This function resets the ACPI table error counter to Zero.\r
-*/\r
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
+\r
+/**\r
+  An ACPI_PARSER array describing the ACPI header.\r
+**/\r
+STATIC CONST ACPI_PARSER AcpiHeaderParser[] = {\r
+  PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
+};\r
+\r
+/**\r
+  This function resets the ACPI table error counter to Zero.\r
+**/\r
 VOID\r
 ResetErrorCount (\r
   VOID\r
@@ -31,10 +35,11 @@ ResetErrorCount (
   mTableErrorCount = 0;\r
 }\r
 \r
-/** This function returns the ACPI table error count.\r
+/**\r
+  This function returns the ACPI table error count.\r
 \r
   @retval Returns the count of errors detected in the ACPI tables.\r
-*/\r
+**/\r
 UINT32\r
 GetErrorCount (\r
   VOID\r
@@ -43,8 +48,9 @@ GetErrorCount (
   return mTableErrorCount;\r
 }\r
 \r
-/** This function resets the ACPI table warning counter to Zero.\r
-*/\r
+/**\r
+  This function resets the ACPI table warning counter to Zero.\r
+**/\r
 VOID\r
 ResetWarningCount (\r
   VOID\r
@@ -53,10 +59,11 @@ ResetWarningCount (
   mTableWarningCount = 0;\r
 }\r
 \r
-/** This function returns the ACPI table warning count.\r
+/**\r
+  This function returns the ACPI table warning count.\r
 \r
   @retval Returns the count of warning detected in the ACPI tables.\r
-*/\r
+**/\r
 UINT32\r
 GetWarningCount (\r
   VOID\r
@@ -65,8 +72,9 @@ GetWarningCount (
   return mTableWarningCount;\r
 }\r
 \r
-/** This function increments the ACPI table error counter.\r
-*/\r
+/**\r
+  This function increments the ACPI table error counter.\r
+**/\r
 VOID\r
 EFIAPI\r
 IncrementErrorCount (\r
@@ -76,8 +84,9 @@ IncrementErrorCount (
   mTableErrorCount++;\r
 }\r
 \r
-/** This function increments the ACPI table warning counter.\r
-*/\r
+/**\r
+  This function increments the ACPI table warning counter.\r
+**/\r
 VOID\r
 EFIAPI\r
 IncrementWarningCount (\r
@@ -87,7 +96,8 @@ IncrementWarningCount (
   mTableWarningCount++;\r
 }\r
 \r
-/** This function verifies the ACPI table checksum.\r
+/**\r
+  This function verifies the ACPI table checksum.\r
 \r
   This function verifies the checksum for the ACPI table and optionally\r
   prints the status.\r
@@ -98,7 +108,7 @@ IncrementWarningCount (
 \r
   @retval TRUE        The checksum is OK.\r
   @retval FALSE       The checksum failed.\r
-*/\r
+**/\r
 BOOLEAN\r
 EFIAPI\r
 VerifyChecksum (\r
@@ -107,10 +117,17 @@ VerifyChecksum (
   IN UINT32  Length\r
   )\r
 {\r
-  UINTN ByteCount = 0;\r
-  UINT8 Checksum = 0;\r
+  UINTN ByteCount;\r
+  UINT8 Checksum;\r
   UINTN OriginalAttribute;\r
 \r
+  //\r
+  // set local variables to suppress incorrect compiler/analyzer warnings\r
+  //\r
+  OriginalAttribute = 0;\r
+  ByteCount = 0;\r
+  Checksum = 0;\r
+\r
   while (ByteCount < Length) {\r
     Checksum += *(Ptr++);\r
     ByteCount++;\r
@@ -126,7 +143,7 @@ VerifyChecksum (
                          ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
                        );\r
       }\r
-      Print (L"\n\nTable Checksum : OK\n\n");\r
+      Print (L"Table Checksum : OK\n\n");\r
     } else {\r
       IncrementErrorCount ();\r
       if (GetColourHighlighting ()) {\r
@@ -136,7 +153,7 @@ VerifyChecksum (
                          ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
                        );\r
       }\r
-      Print (L"\n\nTable Checksum : FAILED (0x%X)\n\n", Checksum);\r
+      Print (L"Table Checksum : FAILED (0x%X)\n\n", Checksum);\r
     }\r
     if (GetColourHighlighting ()) {\r
       gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);\r
@@ -146,11 +163,12 @@ VerifyChecksum (
   return (Checksum == 0);\r
 }\r
 \r
-/** This function performs a raw data dump of the ACPI table.\r
+/**\r
+  This function performs a raw data dump of the ACPI table.\r
 \r
   @param [in] Ptr     Pointer to the start of the table buffer.\r
   @param [in] Length  The length of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 DumpRaw (\r
@@ -158,11 +176,14 @@ DumpRaw (
   IN UINT32 Length\r
   )\r
 {\r
-  UINTN ByteCount = 0;\r
+  UINTN ByteCount;\r
   UINTN PartLineChars;\r
-  UINTN AsciiBufferIndex = 0;\r
+  UINTN AsciiBufferIndex;\r
   CHAR8 AsciiBuffer[17];\r
 \r
+  ByteCount = 0;\r
+  AsciiBufferIndex = 0;\r
+\r
   Print (L"Address  : 0x%p\n", Ptr);\r
   Print (L"Length   : %d\n", Length);\r
 \r
@@ -202,15 +223,15 @@ DumpRaw (
 \r
   // Print ASCII data for the final line.\r
   AsciiBuffer[AsciiBufferIndex] = '\0';\r
-  Print (L"  %a", AsciiBuffer);\r
+  Print (L"  %a\n\n", AsciiBuffer);\r
 }\r
 \r
-/** This function traces 1 byte of data as specified in the\r
-    format string.\r
+/**\r
+  This function traces 1 byte of data as specified in the format string.\r
 \r
   @param [in] Format  The format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 DumpUint8 (\r
@@ -221,12 +242,12 @@ DumpUint8 (
   Print (Format, *Ptr);\r
 }\r
 \r
-/** This function traces 2 bytes of data as specified in the\r
-    format string.\r
+/**\r
+  This function traces 2 bytes of data as specified in the format string.\r
 \r
   @param [in] Format  The format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 DumpUint16 (\r
@@ -237,12 +258,12 @@ DumpUint16 (
   Print (Format, *(UINT16*)Ptr);\r
 }\r
 \r
-/** This function traces 4 bytes of data as specified in the\r
-    format string.\r
+/**\r
+  This function traces 4 bytes of data as specified in the format string.\r
 \r
   @param [in] Format  The format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 DumpUint32 (\r
@@ -253,12 +274,12 @@ DumpUint32 (
   Print (Format, *(UINT32*)Ptr);\r
 }\r
 \r
-/** This function traces 8 bytes of data as specified by the\r
-    format string.\r
+/**\r
+  This function traces 8 bytes of data as specified by the format string.\r
 \r
   @param [in] Format  The format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 DumpUint64 (\r
@@ -269,21 +290,25 @@ DumpUint64 (
   // Some fields are not aligned and this causes alignment faults\r
   // on ARM platforms if the compiler generates LDRD instructions.\r
   // Perform word access so that LDRD instructions are not generated.\r
-  UINT64 Val = *(UINT32*)(Ptr + sizeof (UINT32));\r
-  Val <<= 32;\r
-  Val |= *(UINT32*)Ptr;\r
+  UINT64 Val;\r
+\r
+  Val = *(UINT32*)(Ptr + sizeof (UINT32));\r
+\r
+  Val = LShiftU64(Val,32);\r
+  Val |= (UINT64)*(UINT32*)Ptr;\r
 \r
   Print (Format, Val);\r
 }\r
 \r
-/** This function traces 3 characters which can be optionally\r
-   formated using the format string if specified.\r
+/**\r
+  This function traces 3 characters which can be optionally\r
+  formated using the format string if specified.\r
 \r
   If no format string is specified the Format must be NULL.\r
 \r
   @param [in] Format  Optional format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 Dump3Chars (\r
@@ -299,14 +324,15 @@ Dump3Chars (
     );\r
 }\r
 \r
-/** This function traces 4 characters which can be optionally\r
-   formated using the format string if specified.\r
+/**\r
+  This function traces 4 characters which can be optionally\r
+  formated using the format string if specified.\r
 \r
   If no format string is specified the Format must be NULL.\r
 \r
   @param [in] Format  Optional format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 Dump4Chars (\r
@@ -323,14 +349,15 @@ Dump4Chars (
     );\r
 }\r
 \r
-/** This function traces 6 characters which can be optionally\r
-   formated using the format string if specified.\r
+/**\r
+  This function traces 6 characters which can be optionally\r
+  formated using the format string if specified.\r
 \r
   If no format string is specified the Format must be NULL.\r
 \r
   @param [in] Format  Optional format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 Dump6Chars (\r
@@ -349,14 +376,15 @@ Dump6Chars (
     );\r
 }\r
 \r
-/** This function traces 8 characters which can be optionally\r
-   formated using the format string if specified.\r
+/**\r
+  This function traces 8 characters which can be optionally\r
+  formated using the format string if specified.\r
 \r
   If no format string is specified the Format must be NULL.\r
 \r
   @param [in] Format  Optional format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 Dump8Chars (\r
@@ -377,7 +405,41 @@ Dump8Chars (
     );\r
 }\r
 \r
-/** This function indents and prints the ACPI table Field Name.\r
+/**\r
+  This function traces 12 characters which can be optionally\r
+  formated using the format string if specified.\r
+\r
+  If no format string is specified the Format must be NULL.\r
+\r
+  @param [in] Format  Optional format string for tracing the data.\r
+  @param [in] Ptr     Pointer to the start of the buffer.\r
+**/\r
+VOID\r
+EFIAPI\r
+Dump12Chars (\r
+  IN CONST CHAR16* Format OPTIONAL,\r
+  IN       UINT8*  Ptr\r
+  )\r
+{\r
+  Print (\r
+    (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c",\r
+    Ptr[0],\r
+    Ptr[1],\r
+    Ptr[2],\r
+    Ptr[3],\r
+    Ptr[4],\r
+    Ptr[5],\r
+    Ptr[6],\r
+    Ptr[7],\r
+    Ptr[8],\r
+    Ptr[9],\r
+    Ptr[10],\r
+    Ptr[11]\r
+    );\r
+}\r
+\r
+/**\r
+  This function indents and prints the ACPI table Field Name.\r
 \r
   @param [in] Indent      Number of spaces to add to the global table indent.\r
                           The global table indent is 0 by default; however\r
@@ -387,7 +449,7 @@ Dump8Chars (
                           Therefore the total indent in the output is\r
                           dependent on from where this function is called.\r
   @param [in] FieldName   Pointer to the Field Name.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 PrintFieldName (\r
@@ -404,7 +466,8 @@ PrintFieldName (
     );\r
 }\r
 \r
-/** This function is used to parse an ACPI table buffer.\r
+/**\r
+  This function is used to parse an ACPI table buffer.\r
 \r
   The ACPI table buffer is parsed using the ACPI table parser information\r
   specified by a pointer to an array of ACPI_PARSER elements. This parser\r
@@ -428,7 +491,7 @@ PrintFieldName (
   @param [in] ParserItems  Number of items in the ACPI_PARSER array.\r
 \r
   @retval Number of bytes parsed.\r
-*/\r
+**/\r
 UINT32\r
 EFIAPI\r
 ParseAcpi (\r
@@ -442,14 +505,21 @@ ParseAcpi (
 )\r
 {\r
   UINT32  Index;\r
-  UINT32  Offset = 0;\r
+  UINT32  Offset;\r
+  BOOLEAN HighLight;\r
+  UINTN   OriginalAttribute;\r
+\r
+  //\r
+  // set local variables to suppress incorrect compiler/analyzer warnings\r
+  //\r
+  OriginalAttribute = 0;\r
+  Offset = 0;\r
 \r
   // Increment the Indent\r
   gIndent += Indent;\r
 \r
   if (Trace && (AsciiName != NULL)){\r
-    BOOLEAN HighLight = GetColourHighlighting ();\r
-    UINTN   OriginalAttribute;\r
+    HighLight = GetColourHighlighting ();\r
 \r
     if (HighLight) {\r
       OriginalAttribute = gST->ConOut->Mode->Attribute;\r
@@ -473,15 +543,23 @@ ParseAcpi (
 \r
   for (Index = 0; Index < ParserItems; Index++) {\r
     if ((Offset + Parser[Index].Length) > Length) {\r
+\r
+      // For fields outside the buffer length provided, reset any pointers\r
+      // which were supposed to be updated by this function call\r
+      if (Parser[Index].ItemPtr != NULL) {\r
+        *Parser[Index].ItemPtr = NULL;\r
+      }\r
+\r
       // We don't parse past the end of the max length specified\r
-      break;\r
+      continue;\r
     }\r
 \r
-    if (Offset != Parser[Index].Offset) {\r
+    if (GetConsistencyChecking () &&\r
+        (Offset != Parser[Index].Offset)) {\r
       IncrementErrorCount ();\r
       Print (\r
         L"\nERROR: %a: Offset Mismatch for %s\n"\r
-          "CurrentOffset = %d FieldOffset = %d\n",\r
+          L"CurrentOffset = %d FieldOffset = %d\n",\r
         AsciiName,\r
         Parser[Index].NameStr,\r
         Offset,\r
@@ -520,7 +598,8 @@ ParseAcpi (
 \r
         // Validating only makes sense if we are tracing\r
         // the parsed table entries, to report by table name.\r
-        if (Parser[Index].FieldValidator != NULL) {\r
+        if (GetConsistencyChecking () &&\r
+            (Parser[Index].FieldValidator != NULL)) {\r
           Parser[Index].FieldValidator (Ptr, Parser[Index].Context);\r
         }\r
       }\r
@@ -540,10 +619,11 @@ ParseAcpi (
   return Offset;\r
 }\r
 \r
-/** An array describing the ACPI Generic Address Structure.\r
+/**\r
+  An array describing the ACPI Generic Address Structure.\r
   The GasParser array is used by the ParseAcpi function to parse and/or trace\r
   the GAS structure.\r
-*/\r
+**/\r
 STATIC CONST ACPI_PARSER GasParser[] = {\r
   {L"Address Space ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
   {L"Register Bit Width", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
@@ -552,35 +632,40 @@ STATIC CONST ACPI_PARSER GasParser[] = {
   {L"Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL}\r
 };\r
 \r
-/** This function indents and traces the GAS structure as described\r
-    by the GasParser.\r
+/**\r
+  This function indents and traces the GAS structure as described by the GasParser.\r
 \r
   @param [in] Ptr     Pointer to the start of the buffer.\r
   @param [in] Indent  Number of spaces to indent the output.\r
-*/\r
-VOID\r
+  @param [in] Length  Length of the GAS structure buffer.\r
+\r
+  @retval Number of bytes parsed.\r
+**/\r
+UINT32\r
 EFIAPI\r
 DumpGasStruct (\r
   IN UINT8*        Ptr,\r
-  IN UINT32        Indent\r
+  IN UINT32        Indent,\r
+  IN UINT32        Length\r
   )\r
 {\r
   Print (L"\n");\r
-  ParseAcpi (\r
-    TRUE,\r
-    Indent,\r
-    NULL,\r
-    Ptr,\r
-    GAS_LENGTH,\r
-    PARSER_PARAMS (GasParser)\r
-    );\r
+  return ParseAcpi (\r
+           TRUE,\r
+           Indent,\r
+           NULL,\r
+           Ptr,\r
+           Length,\r
+           PARSER_PARAMS (GasParser)\r
+           );\r
 }\r
 \r
-/** This function traces the GAS structure as described by the GasParser.\r
+/**\r
+  This function traces the GAS structure as described by the GasParser.\r
 \r
   @param [in] Format  Optional format string for tracing the data.\r
   @param [in] Ptr     Pointer to the start of the buffer.\r
-*/\r
+**/\r
 VOID\r
 EFIAPI\r
 DumpGas (\r
@@ -588,37 +673,34 @@ DumpGas (
   IN UINT8*        Ptr\r
   )\r
 {\r
-  DumpGasStruct (Ptr, 2);\r
+  DumpGasStruct (Ptr, 2, sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE));\r
 }\r
 \r
-/** This function traces the ACPI header as described by the AcpiHeaderParser.\r
+/**\r
+  This function traces the ACPI header as described by the AcpiHeaderParser.\r
 \r
   @param [in] Ptr          Pointer to the start of the buffer.\r
 \r
   @retval Number of bytes parsed.\r
-*/\r
+**/\r
 UINT32\r
 EFIAPI\r
 DumpAcpiHeader (\r
   IN UINT8* Ptr\r
   )\r
 {\r
-  ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
-  ACPI_PARSER AcpiHeaderParser[] = {\r
-    PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
-  };\r
-\r
   return ParseAcpi (\r
            TRUE,\r
            0,\r
            "ACPI Table Header",\r
            Ptr,\r
-           ACPI_DESCRIPTION_HEADER_LENGTH,\r
+           sizeof (EFI_ACPI_DESCRIPTION_HEADER),\r
            PARSER_PARAMS (AcpiHeaderParser)\r
            );\r
 }\r
 \r
-/** This function parses the ACPI header as described by the AcpiHeaderParser.\r
+/**\r
+  This function parses the ACPI header as described by the AcpiHeaderParser.\r
 \r
   This function optionally returns the signature, length and revision of the\r
   ACPI table.\r
@@ -629,7 +711,7 @@ DumpAcpiHeader (
   @param [out] Revision   Gets location of the revision of the ACPI table.\r
 \r
   @retval Number of bytes parsed.\r
-*/\r
+**/\r
 UINT32\r
 EFIAPI\r
 ParseAcpiHeader (\r
@@ -640,17 +722,13 @@ ParseAcpiHeader (
   )\r
 {\r
   UINT32                        BytesParsed;\r
-  ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;\r
-  ACPI_PARSER AcpiHeaderParser[] = {\r
-    PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
-  };\r
 \r
   BytesParsed = ParseAcpi (\r
                   FALSE,\r
                   0,\r
                   NULL,\r
                   Ptr,\r
-                  ACPI_DESCRIPTION_HEADER_LENGTH,\r
+                  sizeof (EFI_ACPI_DESCRIPTION_HEADER),\r
                   PARSER_PARAMS (AcpiHeaderParser)\r
                   );\r
 \r