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