]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
e524fcb0b27ace37a5148615d6c12d4f6876c59f
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / AcpiView.c
1 /** @file
2
3 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6 @par Glossary:
7 - Sbbr or SBBR - Server Base Boot Requirements
8
9 @par Reference(s):
10 - Arm Server Base Boot Requirements 1.2, September 2019
11 **/
12
13 #include <Library/PrintLib.h>
14 #include <Library/UefiLib.h>
15 #include <Library/ShellLib.h>
16 #include <Library/UefiBootServicesTableLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include "AcpiParser.h"
21 #include "AcpiTableParser.h"
22 #include "AcpiView.h"
23 #include "AcpiViewConfig.h"
24 #include "UefiShellAcpiViewCommandLib.h"
25
26 #if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
27 #include "Arm/SbbrValidator.h"
28 #endif
29
30 EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;
31
32 STATIC UINT32 mTableCount;
33 STATIC UINT32 mBinTableCount;
34
35 /**
36 This function dumps the ACPI table to a file.
37
38 @param [in] Ptr Pointer to the ACPI table data.
39 @param [in] Length The length of the ACPI table.
40
41 @retval TRUE Success.
42 @retval FALSE Failure.
43 **/
44 STATIC
45 BOOLEAN
46 DumpAcpiTableToFile (
47 IN CONST UINT8* Ptr,
48 IN CONST UINTN Length
49 )
50 {
51 EFI_STATUS Status;
52 CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
53 SHELL_FILE_HANDLE DumpFileHandle;
54 UINTN TransferBytes;
55 SELECTED_ACPI_TABLE *SelectedTable;
56
57 DumpFileHandle = NULL;
58 TransferBytes = Length;
59 GetSelectedAcpiTable (&SelectedTable);
60
61 UnicodeSPrint (
62 FileNameBuffer,
63 sizeof (FileNameBuffer),
64 L".\\%s%04d.bin",
65 SelectedTable->Name,
66 mBinTableCount++
67 );
68
69 Status = ShellOpenFileByName (
70 FileNameBuffer,
71 &DumpFileHandle,
72 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
73 0
74 );
75 if (EFI_ERROR (Status)) {
76 ShellPrintHiiEx (
77 -1,
78 -1,
79 NULL,
80 STRING_TOKEN (STR_GEN_READONLY_MEDIA),
81 gShellAcpiViewHiiHandle,
82 L"acpiview"
83 );
84 return FALSE;
85 }
86
87 Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer);
88
89 Status = ShellWriteFile (
90 DumpFileHandle,
91 &TransferBytes,
92 (VOID*)Ptr
93 );
94 if (EFI_ERROR (Status)) {
95 Print (L"ERROR: Failed to dump table to binary file.\n");
96 TransferBytes = 0;
97 } else {
98 Print (L"DONE.\n");
99 }
100
101 ShellCloseFile (&DumpFileHandle);
102 return (Length == TransferBytes);
103 }
104
105 /**
106 This function processes the table reporting options for the ACPI table.
107
108 @param [in] Signature The ACPI table Signature.
109 @param [in] TablePtr Pointer to the ACPI table data.
110 @param [in] Length The length fo the ACPI table.
111
112 @retval Returns TRUE if the ACPI table should be traced.
113 **/
114 BOOLEAN
115 ProcessTableReportOptions (
116 IN CONST UINT32 Signature,
117 IN CONST UINT8* TablePtr,
118 IN CONST UINT32 Length
119 )
120 {
121 UINTN OriginalAttribute;
122 UINT8 *SignaturePtr;
123 BOOLEAN Log;
124 BOOLEAN HighLight;
125 SELECTED_ACPI_TABLE *SelectedTable;
126
127 //
128 // set local variables to suppress incorrect compiler/analyzer warnings
129 //
130 OriginalAttribute = 0;
131 SignaturePtr = (UINT8*)(UINTN)&Signature;
132 Log = FALSE;
133 HighLight = GetColourHighlighting ();
134 GetSelectedAcpiTable (&SelectedTable);
135
136 switch (GetReportOption ()) {
137 case ReportAll:
138 Log = TRUE;
139 break;
140 case ReportSelected:
141 if (Signature == SelectedTable->Type) {
142 Log = TRUE;
143 SelectedTable->Found = TRUE;
144 }
145 break;
146 case ReportTableList:
147 if (mTableCount == 0) {
148 if (HighLight) {
149 OriginalAttribute = gST->ConOut->Mode->Attribute;
150 gST->ConOut->SetAttribute (
151 gST->ConOut,
152 EFI_TEXT_ATTR(EFI_CYAN,
153 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
154 );
155 }
156 Print (L"\nInstalled Table(s):\n");
157 if (HighLight) {
158 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
159 }
160 }
161 Print (
162 L"\t%4d. %c%c%c%c\n",
163 ++mTableCount,
164 SignaturePtr[0],
165 SignaturePtr[1],
166 SignaturePtr[2],
167 SignaturePtr[3]
168 );
169 break;
170 case ReportDumpBinFile:
171 if (Signature == SelectedTable->Type) {
172 SelectedTable->Found = TRUE;
173 DumpAcpiTableToFile (TablePtr, Length);
174 }
175 break;
176 case ReportMax:
177 // We should never be here.
178 // This case is only present to prevent compiler warning.
179 break;
180 } // switch
181
182 if (Log) {
183 if (HighLight) {
184 OriginalAttribute = gST->ConOut->Mode->Attribute;
185 gST->ConOut->SetAttribute (
186 gST->ConOut,
187 EFI_TEXT_ATTR(EFI_LIGHTBLUE,
188 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
189 );
190 }
191 Print (
192 L"\n\n --------------- %c%c%c%c Table --------------- \n\n",
193 SignaturePtr[0],
194 SignaturePtr[1],
195 SignaturePtr[2],
196 SignaturePtr[3]
197 );
198 if (HighLight) {
199 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
200 }
201 }
202
203 return Log;
204 }
205
206
207
208 /**
209 This function iterates the configuration table entries in the
210 system table, retrieves the RSDP pointer and starts parsing the ACPI tables.
211
212 @param [in] SystemTable Pointer to the EFI system table.
213
214 @retval Returns EFI_NOT_FOUND if the RSDP pointer is not found.
215 Returns EFI_UNSUPPORTED if the RSDP version is less than 2.
216 Returns EFI_SUCCESS if successful.
217 **/
218 EFI_STATUS
219 EFIAPI
220 AcpiView (
221 IN EFI_SYSTEM_TABLE* SystemTable
222 )
223 {
224 EFI_STATUS Status;
225 UINTN Index;
226 EFI_CONFIGURATION_TABLE* EfiConfigurationTable;
227 BOOLEAN FoundAcpiTable;
228 UINTN OriginalAttribute;
229 UINTN PrintAttribute;
230 EREPORT_OPTION ReportOption;
231 UINT8* RsdpPtr;
232 UINT32 RsdpLength;
233 UINT8 RsdpRevision;
234 PARSE_ACPI_TABLE_PROC RsdpParserProc;
235 BOOLEAN Trace;
236 SELECTED_ACPI_TABLE *SelectedTable;
237
238 //
239 // set local variables to suppress incorrect compiler/analyzer warnings
240 //
241 EfiConfigurationTable = NULL;
242 OriginalAttribute = 0;
243
244 // Reset Table counts
245 mTableCount = 0;
246 mBinTableCount = 0;
247
248 // Reset The error/warning counters
249 ResetErrorCount ();
250 ResetWarningCount ();
251
252 // Retrieve the user selection of ACPI table to process
253 GetSelectedAcpiTable (&SelectedTable);
254
255 // Search the table for an entry that matches the ACPI Table Guid
256 FoundAcpiTable = FALSE;
257 for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
258 if (CompareGuid (&gEfiAcpiTableGuid,
259 &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
260 EfiConfigurationTable = &SystemTable->ConfigurationTable[Index];
261 FoundAcpiTable = TRUE;
262 break;
263 }
264 }
265
266 if (FoundAcpiTable) {
267 RsdpPtr = (UINT8*)EfiConfigurationTable->VendorTable;
268
269 // The RSDP revision is 1 byte starting at offset 15
270 RsdpRevision = *(RsdpPtr + RSDP_REVISION_OFFSET);
271
272 if (RsdpRevision < 2) {
273 Print (
274 L"ERROR: RSDP version less than 2 is not supported.\n"
275 );
276 return EFI_UNSUPPORTED;
277 }
278
279 #if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
280 if (GetMandatoryTableValidate ()) {
281 ArmSbbrResetTableCounts ();
282 }
283 #endif
284
285 // The RSDP length is 4 bytes starting at offset 20
286 RsdpLength = *(UINT32*)(RsdpPtr + RSDP_LENGTH_OFFSET);
287
288 Trace = ProcessTableReportOptions (RSDP_TABLE_INFO, RsdpPtr, RsdpLength);
289
290 Status = GetParser (RSDP_TABLE_INFO, &RsdpParserProc);
291 if (EFI_ERROR (Status)) {
292 Print (
293 L"ERROR: No registered parser found for RSDP.\n"
294 );
295 return Status;
296 }
297
298 RsdpParserProc (
299 Trace,
300 RsdpPtr,
301 RsdpLength,
302 RsdpRevision
303 );
304
305 } else {
306 IncrementErrorCount ();
307 Print (
308 L"ERROR: Failed to find ACPI Table Guid in System Configuration Table.\n"
309 );
310 return EFI_NOT_FOUND;
311 }
312
313 #if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
314 if (GetMandatoryTableValidate ()) {
315 ArmSbbrReqsValidate ((ARM_SBBR_VERSION)GetMandatoryTableSpec ());
316 }
317 #endif
318
319 ReportOption = GetReportOption ();
320 if (ReportTableList != ReportOption) {
321 if (((ReportSelected == ReportOption) ||
322 (ReportDumpBinFile == ReportOption)) &&
323 (!SelectedTable->Found)) {
324 Print (L"\nRequested ACPI Table not found.\n");
325 } else if (GetConsistencyChecking () &&
326 (ReportDumpBinFile != ReportOption)) {
327 OriginalAttribute = gST->ConOut->Mode->Attribute;
328
329 Print (L"\nTable Statistics:\n");
330
331 if (GetColourHighlighting ()) {
332 PrintAttribute = (GetErrorCount () > 0) ?
333 EFI_TEXT_ATTR (
334 EFI_RED,
335 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
336 ) :
337 OriginalAttribute;
338 gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
339 }
340 Print (L"\t%d Error(s)\n", GetErrorCount ());
341
342 if (GetColourHighlighting ()) {
343 PrintAttribute = (GetWarningCount () > 0) ?
344 EFI_TEXT_ATTR (
345 EFI_RED,
346 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
347 ) :
348 OriginalAttribute;
349
350 gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
351 }
352 Print (L"\t%d Warning(s)\n", GetWarningCount ());
353
354 if (GetColourHighlighting ()) {
355 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
356 }
357 }
358 }
359 return EFI_SUCCESS;
360 }