99521cd67a714065c2eb9e4e5ec0f2e21f4c9da9
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Xsdt / XsdtParser.c
1 /** @file\r
2   XSDT table parser\r
3 \r
4   Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
5   This program and the accompanying materials\r
6   are licensed and made available under the terms and conditions of the BSD License\r
7   which accompanies this distribution.  The full text of the license may be found at\r
8   http://opensource.org/licenses/bsd-license.php\r
9 \r
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 \r
13   @par Reference(s):\r
14     - ACPI 6.2 Specification - Errata A, September 2017\r
15 **/\r
16 \r
17 #include <IndustryStandard/Acpi.h>\r
18 #include <Library/UefiLib.h>\r
19 #include <Library/PrintLib.h>\r
20 #include "AcpiParser.h"\r
21 #include "AcpiTableParser.h"\r
22 \r
23 // Local variables\r
24 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
25 \r
26 /** An ACPI_PARSER array describing the ACPI XSDT table.\r
27 */\r
28 STATIC CONST ACPI_PARSER XsdtParser[] = {\r
29   PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
30 };\r
31 \r
32 /**\r
33   Get the ACPI XSDT header info.\r
34 **/\r
35 CONST ACPI_DESCRIPTION_HEADER_INFO* CONST\r
36 EFIAPI\r
37 GetAcpiXsdtHeaderInfo (\r
38   VOID\r
39 )\r
40 {\r
41   return &AcpiHdrInfo;\r
42 }\r
43 \r
44 /**\r
45   This function parses the ACPI XSDT table and optionally traces the ACPI table fields.\r
46 \r
47   This function also performs validation of the XSDT table.\r
48 \r
49   @param [in] Trace              If TRUE, trace the ACPI fields.\r
50   @param [in] Ptr                Pointer to the start of the buffer.\r
51   @param [in] AcpiTableLength    Length of the ACPI table.\r
52   @param [in] AcpiTableRevision  Revision of the ACPI table.\r
53 **/\r
54 VOID\r
55 EFIAPI\r
56 ParseAcpiXsdt (\r
57   IN BOOLEAN Trace,\r
58   IN UINT8*  Ptr,\r
59   IN UINT32  AcpiTableLength,\r
60   IN UINT8   AcpiTableRevision\r
61   )\r
62 {\r
63   UINT32        Offset;\r
64   UINT32        TableOffset;\r
65   UINT64*       TablePointer;\r
66   UINTN         EntryIndex;\r
67   CHAR16        Buffer[32];\r
68 \r
69   // Parse the ACPI header to get the length\r
70   ParseAcpi (\r
71     FALSE,\r
72     0,\r
73     "XSDT",\r
74     Ptr,\r
75     ACPI_DESCRIPTION_HEADER_LENGTH,\r
76     PARSER_PARAMS (XsdtParser)\r
77     );\r
78 \r
79   Offset = ParseAcpi (\r
80              Trace,\r
81              0,\r
82              "XSDT",\r
83              Ptr,\r
84              *AcpiHdrInfo.Length,\r
85              PARSER_PARAMS (XsdtParser)\r
86              );\r
87 \r
88   TableOffset = Offset;\r
89 \r
90   if (Trace) {\r
91     EntryIndex = 0;\r
92     TablePointer = (UINT64*)(Ptr + TableOffset);\r
93     while (Offset < (*AcpiHdrInfo.Length)) {\r
94       CONST UINT32* Signature;\r
95       CONST UINT32* Length;\r
96       CONST UINT8*  Revision;\r
97 \r
98       if ((UINT64*)(UINTN)(*TablePointer) != NULL) {\r
99         UINT8*      Ptr;\r
100 \r
101         ParseAcpiHeader (\r
102           (UINT8*)(UINTN)(*TablePointer),\r
103           &Signature,\r
104           &Length,\r
105           &Revision\r
106           );\r
107 \r
108         Ptr = (UINT8*)Signature;\r
109 \r
110         UnicodeSPrint (\r
111           Buffer,\r
112           sizeof (Buffer),\r
113           L"Entry[%d] - %c%c%c%c",\r
114           EntryIndex++,\r
115           Ptr[0],\r
116           Ptr[1],\r
117           Ptr[2],\r
118           Ptr[3]\r
119           );\r
120       } else {\r
121         UnicodeSPrint (\r
122           Buffer,\r
123           sizeof (Buffer),\r
124           L"Entry[%d]",\r
125           EntryIndex++\r
126           );\r
127       }\r
128 \r
129       PrintFieldName (2, Buffer);\r
130       Print (L"0x%lx\n", *TablePointer);\r
131 \r
132       // Validate the table pointers are not NULL\r
133       if ((UINT64*)(UINTN)(*TablePointer) == NULL) {\r
134         IncrementErrorCount ();\r
135         Print (\r
136           L"ERROR: Invalid table entry at 0x%lx, table address is 0x%lx\n",\r
137           TablePointer,\r
138           *TablePointer\r
139           );\r
140       }\r
141       Offset += sizeof (UINT64);\r
142       TablePointer++;\r
143     } // while\r
144   }\r
145 \r
146   // Process the tables\r
147   Offset = TableOffset;\r
148   TablePointer = (UINT64*)(Ptr + TableOffset);\r
149   while (Offset < (*AcpiHdrInfo.Length)) {\r
150     if ((UINT64*)(UINTN)(*TablePointer) != NULL) {\r
151       ProcessAcpiTable ((UINT8*)(UINTN)(*TablePointer));\r
152     }\r
153     Offset += sizeof (UINT64);\r
154     TablePointer++;\r
155   } // while\r
156 }\r