]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / AcpiTableParser.c
1 /** @file
2 ACPI table parser
3
4 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 @par Glossary:
8 - Sbbr or SBBR - Server Base Boot Requirements
9
10 @par Reference(s):
11 - Arm Server Base Boot Requirements 1.2, September 2019
12 **/
13
14 #include <Uefi.h>
15 #include <IndustryStandard/Acpi.h>
16 #include <Library/UefiLib.h>
17 #include "AcpiParser.h"
18 #include "AcpiTableParser.h"
19 #include "AcpiView.h"
20 #include "AcpiViewConfig.h"
21
22 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
23 #include "Arm/SbbrValidator.h"
24 #endif
25
26 /**
27 A list of registered ACPI table parsers.
28 **/
29 STATIC ACPI_TABLE_PARSER mTableParserList[MAX_ACPI_TABLE_PARSERS];
30
31 /**
32 Register the ACPI table Parser
33
34 This function registers the ACPI table parser.
35
36 @param [in] Signature The ACPI table signature.
37 @param [in] ParserProc The ACPI table parser.
38
39 @retval EFI_SUCCESS The parser is registered.
40 @retval EFI_INVALID_PARAMETER A parameter is invalid.
41 @retval EFI_ALREADY_STARTED The parser for the Table
42 was already registered.
43 @retval EFI_OUT_OF_RESOURCES No space to register the
44 parser.
45 **/
46 EFI_STATUS
47 EFIAPI
48 RegisterParser (
49 IN UINT32 Signature,
50 IN PARSE_ACPI_TABLE_PROC ParserProc
51 )
52 {
53 UINT32 Index;
54
55 if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) {
56 return EFI_INVALID_PARAMETER;
57 }
58
59 // Search if a parser is already installed
60 for (Index = 0;
61 Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
62 Index++)
63 {
64 if (Signature == mTableParserList[Index].Signature) {
65 if (mTableParserList[Index].Parser != NULL) {
66 return EFI_ALREADY_STARTED;
67 }
68 }
69 }
70
71 // Find the first free slot and register the parser
72 for (Index = 0;
73 Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
74 Index++)
75 {
76 if (mTableParserList[Index].Signature == ACPI_PARSER_SIGNATURE_NULL) {
77 mTableParserList[Index].Signature = Signature;
78 mTableParserList[Index].Parser = ParserProc;
79 return EFI_SUCCESS;
80 }
81 }
82
83 // No free slot found
84 return EFI_OUT_OF_RESOURCES;
85 }
86
87 /**
88 Deregister the ACPI table Parser
89
90 This function deregisters the ACPI table parser.
91
92 @param [in] Signature The ACPI table signature.
93
94 @retval EFI_SUCCESS The parser was deregistered.
95 @retval EFI_INVALID_PARAMETER A parameter is invalid.
96 @retval EFI_NOT_FOUND A registered parser was not found.
97 **/
98 EFI_STATUS
99 EFIAPI
100 DeregisterParser (
101 IN UINT32 Signature
102 )
103 {
104 UINT32 Index;
105
106 if (Signature == ACPI_PARSER_SIGNATURE_NULL) {
107 return EFI_INVALID_PARAMETER;
108 }
109
110 for (Index = 0;
111 Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
112 Index++)
113 {
114 if (Signature == mTableParserList[Index].Signature) {
115 mTableParserList[Index].Signature = ACPI_PARSER_SIGNATURE_NULL;
116 mTableParserList[Index].Parser = NULL;
117 return EFI_SUCCESS;
118 }
119 }
120
121 // No matching registered parser found.
122 return EFI_NOT_FOUND;
123 }
124
125 /**
126 Get the ACPI table Parser
127
128 This function returns the ACPI table parser proc from the list of
129 registered parsers.
130
131 @param [in] Signature The ACPI table signature.
132 @param [out] ParserProc Pointer to a ACPI table parser proc.
133
134 @retval EFI_SUCCESS The parser was returned successfully.
135 @retval EFI_INVALID_PARAMETER A parameter is invalid.
136 @retval EFI_NOT_FOUND A registered parser was not found.
137 **/
138 EFI_STATUS
139 EFIAPI
140 GetParser (
141 IN UINT32 Signature,
142 OUT PARSE_ACPI_TABLE_PROC *ParserProc
143 )
144 {
145 UINT32 Index;
146
147 if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) {
148 return EFI_INVALID_PARAMETER;
149 }
150
151 for (Index = 0;
152 Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
153 Index++)
154 {
155 if (Signature == mTableParserList[Index].Signature) {
156 *ParserProc = mTableParserList[Index].Parser;
157 return EFI_SUCCESS;
158 }
159 }
160
161 // No matching registered parser found.
162 return EFI_NOT_FOUND;
163 }
164
165 /**
166 This function processes the ACPI tables.
167 This function calls ProcessTableReportOptions() to list the ACPI
168 tables, perform binary dump of the tables and determine if the
169 ACPI fields should be traced.
170
171 This function also invokes the parser for the ACPI tables.
172
173 This function also performs a RAW dump of the ACPI table including
174 the unknown/unparsed ACPI tables and validates the checksum.
175
176 @param [in] Ptr Pointer to the start of the ACPI
177 table data buffer.
178 **/
179 VOID
180 EFIAPI
181 ProcessAcpiTable (
182 IN UINT8 *Ptr
183 )
184 {
185 EFI_STATUS Status;
186 BOOLEAN Trace;
187 CONST UINT32 *AcpiTableSignature;
188 CONST UINT32 *AcpiTableLength;
189 CONST UINT8 *AcpiTableRevision;
190 CONST UINT8 *SignaturePtr;
191 PARSE_ACPI_TABLE_PROC ParserProc;
192
193 ParseAcpiHeader (
194 Ptr,
195 &AcpiTableSignature,
196 &AcpiTableLength,
197 &AcpiTableRevision
198 );
199
200 Trace = ProcessTableReportOptions (
201 *AcpiTableSignature,
202 Ptr,
203 *AcpiTableLength
204 );
205
206 if (Trace) {
207 DumpRaw (Ptr, *AcpiTableLength);
208
209 // Do not process the ACPI table any further if the table length read
210 // is invalid. The ACPI table should at least contain the table header.
211 if (*AcpiTableLength < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
212 SignaturePtr = (CONST UINT8 *)AcpiTableSignature;
213 IncrementErrorCount ();
214 Print (
215 L"ERROR: Invalid %c%c%c%c table length. Length = %d\n",
216 SignaturePtr[0],
217 SignaturePtr[1],
218 SignaturePtr[2],
219 SignaturePtr[3],
220 *AcpiTableLength
221 );
222 return;
223 }
224
225 if (GetConsistencyChecking ()) {
226 VerifyChecksum (TRUE, Ptr, *AcpiTableLength);
227 }
228 }
229
230 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
231 if (GetMandatoryTableValidate ()) {
232 ArmSbbrIncrementTableCount (*AcpiTableSignature);
233 }
234
235 #endif
236
237 Status = GetParser (*AcpiTableSignature, &ParserProc);
238 if (EFI_ERROR (Status)) {
239 // No registered parser found, do default handling.
240 if (Trace) {
241 DumpAcpiHeader (Ptr);
242 }
243
244 return;
245 }
246
247 ParserProc (
248 Trace,
249 Ptr,
250 *AcpiTableLength,
251 *AcpiTableRevision
252 );
253 }