]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
ShellPkg/Acpiview: AEST Parser
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / UefiShellAcpiViewCommandLib.c
1 /** @file
2 Main file for 'acpiview' Shell command function.
3
4 Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 **/
7
8 #include <Guid/ShellLibHiiGuid.h>
9 #include <IndustryStandard/Acpi.h>
10 #include <IndustryStandard/ArmErrorSourceTable.h>
11
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/HiiLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/PrintLib.h>
16 #include <Library/ShellCommandLib.h>
17 #include <Library/ShellLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Library/UefiLib.h>
20 #include <Library/AcpiViewCommandLib.h>
21 #include <Uefi.h>
22
23 #include "AcpiParser.h"
24 #include "AcpiTableParser.h"
25 #include "AcpiView.h"
26 #include "AcpiViewConfig.h"
27
28 CONST CHAR16 gShellAcpiViewFileName[] = L"ShellCommand";
29 EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;
30
31 /**
32 An array of acpiview command line parameters.
33 **/
34 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
35 {L"-q", TypeFlag},
36 {L"-d", TypeFlag},
37 {L"-h", TypeFlag},
38 {L"-l", TypeFlag},
39 {L"-s", TypeValue},
40 {L"-r", TypeValue},
41 {NULL, TypeMax}
42 };
43
44 /**
45 A list of available table parsers.
46 */
47 STATIC
48 CONST
49 ACPI_TABLE_PARSER ParserList[] = {
50 {EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE, ParseAcpiAest},
51 {EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE, ParseAcpiBgrt},
52 {EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, ParseAcpiDbg2},
53 {EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
54 ParseAcpiDsdt},
55 {EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs},
56 {EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt},
57 {EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt},
58 {EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, ParseAcpiIort},
59 {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt},
60 {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
61 ParseAcpiMcfg},
62 {EFI_ACPI_6_2_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
63 ParseAcpiPcct},
64 {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
65 ParseAcpiPptt},
66 {RSDP_TABLE_INFO, ParseAcpiRsdp},
67 {EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, ParseAcpiSlit},
68 {EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, ParseAcpiSpcr},
69 {EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, ParseAcpiSrat},
70 {EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiSsdt},
71 {EFI_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiXsdt}
72 };
73
74 /**
75 This function registers all the available table parsers.
76
77 @retval EFI_SUCCESS The parser is registered.
78 @retval EFI_ALREADY_STARTED The parser for the ACPI Table
79 was already registered.
80 @retval EFI_INVALID_PARAMETER A parameter is invalid.
81 @retval EFI_OUT_OF_RESOURCES No space to register the
82 parser.
83 **/
84 EFI_STATUS
85 RegisterAllParsers (
86 )
87 {
88 EFI_STATUS Status;
89 UINTN Count;
90
91 Status = EFI_SUCCESS;
92 Count = sizeof (ParserList) / sizeof (ParserList[0]);
93
94 while (Count-- != 0) {
95 Status = RegisterParser (
96 ParserList[Count].Signature,
97 ParserList[Count].Parser
98 );
99 if (EFI_ERROR (Status)) {
100 return Status;
101 }
102 }
103 return Status;
104 }
105
106 /**
107 Dump a buffer to a file. Print error message if a file cannot be created.
108
109 @param[in] FileName The filename that shall be created to contain the buffer.
110 @param[in] Buffer Pointer to buffer that shall be dumped.
111 @param[in] BufferSize The size of buffer to be dumped in bytes.
112
113 @return The number of bytes that were written
114 **/
115 UINTN
116 EFIAPI
117 ShellDumpBufferToFile (
118 IN CONST CHAR16* FileNameBuffer,
119 IN CONST VOID* Buffer,
120 IN CONST UINTN BufferSize
121 )
122 {
123 EFI_STATUS Status;
124 SHELL_FILE_HANDLE DumpFileHandle;
125 UINTN TransferBytes;
126
127 Status = ShellOpenFileByName (
128 FileNameBuffer,
129 &DumpFileHandle,
130 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
131 0
132 );
133
134 if (EFI_ERROR (Status)) {
135 ShellPrintHiiEx (
136 -1,
137 -1,
138 NULL,
139 STRING_TOKEN (STR_GEN_READONLY_MEDIA),
140 gShellAcpiViewHiiHandle,
141 L"acpiview"
142 );
143 return 0;
144 }
145
146 TransferBytes = BufferSize;
147 Status = ShellWriteFile (
148 DumpFileHandle,
149 &TransferBytes,
150 (VOID *) Buffer
151 );
152
153 if (EFI_ERROR (Status)) {
154 Print (L"ERROR: Failed to write binary file.\n");
155 TransferBytes = 0;
156 } else {
157 Print (L"DONE.\n");
158 }
159
160 ShellCloseFile (&DumpFileHandle);
161 return TransferBytes;
162 }
163
164 /**
165 Return the file name of the help text file if not using HII.
166
167 @return The string pointer to the file name.
168 **/
169 CONST CHAR16*
170 EFIAPI
171 ShellCommandGetManFileNameAcpiView (
172 VOID
173 )
174 {
175 return gShellAcpiViewFileName;
176 }
177
178 /**
179 Function for 'acpiview' command.
180
181 @param[in] ImageHandle Handle to the Image (NULL if internal).
182 @param[in] SystemTable Pointer to the System Table (NULL if internal).
183
184 @retval SHELL_INVALID_PARAMETER The command line invocation could not be parsed
185 @retval SHELL_NOT_FOUND The command failed
186 @retval SHELL_SUCCESS The command was successful
187 **/
188 SHELL_STATUS
189 EFIAPI
190 ShellCommandRunAcpiView (
191 IN EFI_HANDLE ImageHandle,
192 IN EFI_SYSTEM_TABLE* SystemTable
193 )
194 {
195 EFI_STATUS Status;
196 SHELL_STATUS ShellStatus;
197 LIST_ENTRY* Package;
198 CHAR16* ProblemParam;
199 SHELL_FILE_HANDLE TmpDumpFileHandle;
200 CONST CHAR16* MandatoryTableSpecStr;
201 CONST CHAR16* SelectedTableName;
202
203 // Set configuration defaults
204 AcpiConfigSetDefaults ();
205
206 ShellStatus = SHELL_SUCCESS;
207 Package = NULL;
208 TmpDumpFileHandle = NULL;
209
210 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
211 if (EFI_ERROR (Status)) {
212 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
213 ShellPrintHiiEx (
214 -1,
215 -1,
216 NULL,
217 STRING_TOKEN (STR_GEN_PROBLEM),
218 gShellAcpiViewHiiHandle,
219 L"acpiview",
220 ProblemParam
221 );
222 FreePool (ProblemParam);
223 } else {
224 Print (L"acpiview: Error processing input parameter(s)\n");
225 }
226 ShellStatus = SHELL_INVALID_PARAMETER;
227 } else {
228 if (ShellCommandLineGetCount (Package) > 1) {
229 ShellPrintHiiEx (
230 -1,
231 -1,
232 NULL,
233 STRING_TOKEN (STR_GEN_TOO_MANY),
234 gShellAcpiViewHiiHandle,
235 L"acpiview"
236 );
237 ShellStatus = SHELL_INVALID_PARAMETER;
238 } else if (ShellCommandLineGetFlag (Package, L"-?")) {
239 ShellPrintHiiEx (
240 -1,
241 -1,
242 NULL,
243 STRING_TOKEN (STR_GET_HELP_ACPIVIEW),
244 gShellAcpiViewHiiHandle,
245 L"acpiview"
246 );
247 } else if (ShellCommandLineGetFlag (Package, L"-s") &&
248 ShellCommandLineGetValue (Package, L"-s") == NULL) {
249 ShellPrintHiiEx (
250 -1,
251 -1,
252 NULL,
253 STRING_TOKEN (STR_GEN_NO_VALUE),
254 gShellAcpiViewHiiHandle,
255 L"acpiview",
256 L"-s"
257 );
258 ShellStatus = SHELL_INVALID_PARAMETER;
259 } else if (ShellCommandLineGetFlag (Package, L"-r") &&
260 ShellCommandLineGetValue (Package, L"-r") == NULL) {
261 ShellPrintHiiEx (
262 -1,
263 -1,
264 NULL,
265 STRING_TOKEN (STR_GEN_NO_VALUE),
266 gShellAcpiViewHiiHandle,
267 L"acpiview",
268 L"-r"
269 );
270 ShellStatus = SHELL_INVALID_PARAMETER;
271 } else if ((ShellCommandLineGetFlag (Package, L"-s") &&
272 ShellCommandLineGetFlag (Package, L"-l"))) {
273 ShellPrintHiiEx (
274 -1,
275 -1,
276 NULL,
277 STRING_TOKEN (STR_GEN_TOO_MANY),
278 gShellAcpiViewHiiHandle,
279 L"acpiview"
280 );
281 ShellStatus = SHELL_INVALID_PARAMETER;
282 } else if (ShellCommandLineGetFlag (Package, L"-d") &&
283 !ShellCommandLineGetFlag (Package, L"-s")) {
284 ShellPrintHiiEx (
285 -1,
286 -1,
287 NULL,
288 STRING_TOKEN (STR_GEN_MISSING_OPTION),
289 gShellAcpiViewHiiHandle,
290 L"acpiview",
291 L"-s",
292 L"-d"
293 );
294 ShellStatus = SHELL_INVALID_PARAMETER;
295 } else {
296 // Turn on colour highlighting if requested
297 SetColourHighlighting (ShellCommandLineGetFlag (Package, L"-h"));
298
299 // Surpress consistency checking if requested
300 SetConsistencyChecking (!ShellCommandLineGetFlag (Package, L"-q"));
301
302 // Evaluate the parameters for mandatory ACPI table presence checks
303 SetMandatoryTableValidate (ShellCommandLineGetFlag (Package, L"-r"));
304 MandatoryTableSpecStr = ShellCommandLineGetValue (Package, L"-r");
305
306 if (MandatoryTableSpecStr != NULL) {
307 SetMandatoryTableSpec (ShellHexStrToUintn (MandatoryTableSpecStr));
308 }
309
310 if (ShellCommandLineGetFlag (Package, L"-l")) {
311 SetReportOption (ReportTableList);
312 } else {
313 SelectedTableName = ShellCommandLineGetValue (Package, L"-s");
314 if (SelectedTableName != NULL) {
315 SelectAcpiTable (SelectedTableName);
316 SetReportOption (ReportSelected);
317
318 if (ShellCommandLineGetFlag (Package, L"-d")) {
319 // Create a temporary file to check if the media is writable.
320 CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
321 SetReportOption (ReportDumpBinFile);
322
323 UnicodeSPrint (
324 FileNameBuffer,
325 sizeof (FileNameBuffer),
326 L".\\%s0000.tmp",
327 SelectedTableName
328 );
329
330 Status = ShellOpenFileByName (
331 FileNameBuffer,
332 &TmpDumpFileHandle,
333 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |
334 EFI_FILE_MODE_CREATE,
335 0
336 );
337
338 if (EFI_ERROR (Status)) {
339 ShellStatus = SHELL_INVALID_PARAMETER;
340 TmpDumpFileHandle = NULL;
341 ShellPrintHiiEx (
342 -1,
343 -1,
344 NULL,
345 STRING_TOKEN (STR_GEN_READONLY_MEDIA),
346 gShellAcpiViewHiiHandle,
347 L"acpiview"
348 );
349 goto Done;
350 }
351 // Delete Temporary file.
352 ShellDeleteFile (&TmpDumpFileHandle);
353 } // -d
354 } // -s
355 }
356
357 // Parse ACPI Table information
358 Status = AcpiView (SystemTable);
359 if (EFI_ERROR (Status)) {
360 ShellStatus = SHELL_NOT_FOUND;
361 }
362 }
363 }
364
365 Done:
366 if (Package != NULL) {
367 ShellCommandLineFreeVarList (Package);
368 }
369 return ShellStatus;
370 }
371
372 /**
373 Constructor for the Shell AcpiView Command library.
374
375 Install the handlers for acpiview UEFI Shell command.
376
377 @param ImageHandle The image handle of the process.
378 @param SystemTable The EFI System Table pointer.
379
380 @retval EFI_SUCCESS The Shell command handlers were installed
381 successfully.
382 @retval EFI_DEVICE_ERROR Hii package failed to install.
383 **/
384 EFI_STATUS
385 EFIAPI
386 UefiShellAcpiViewCommandLibConstructor (
387 IN EFI_HANDLE ImageHandle,
388 IN EFI_SYSTEM_TABLE *SystemTable
389 )
390 {
391 EFI_STATUS Status;
392 gShellAcpiViewHiiHandle = NULL;
393
394 // Check Shell Profile Debug1 bit of the profiles mask
395 if ((PcdGet8 (PcdShellProfileMask) & BIT1) == 0) {
396 return EFI_SUCCESS;
397 }
398
399 Status = RegisterAllParsers ();
400 if (EFI_ERROR (Status)) {
401 Print (L"acpiview: Error failed to register parser.\n");
402 return Status;
403 }
404
405 gShellAcpiViewHiiHandle = HiiAddPackages (
406 &gShellAcpiViewHiiGuid,
407 gImageHandle,
408 UefiShellAcpiViewCommandLibStrings,
409 NULL
410 );
411 if (gShellAcpiViewHiiHandle == NULL) {
412 return EFI_DEVICE_ERROR;
413 }
414 // Install our Shell command handler
415 ShellCommandRegisterCommandName (
416 L"acpiview",
417 ShellCommandRunAcpiView,
418 ShellCommandGetManFileNameAcpiView,
419 0,
420 L"acpiview",
421 TRUE,
422 gShellAcpiViewHiiHandle,
423 STRING_TOKEN (STR_GET_HELP_ACPIVIEW)
424 );
425
426 return EFI_SUCCESS;
427 }
428
429 /**
430 Destructor for the library. free any resources.
431
432 @param ImageHandle The image handle of the process.
433 @param SystemTable The EFI System Table pointer.
434 **/
435 EFI_STATUS
436 EFIAPI
437 UefiShellAcpiViewCommandLibDestructor (
438 IN EFI_HANDLE ImageHandle,
439 IN EFI_SYSTEM_TABLE *SystemTable
440 )
441 {
442 if (gShellAcpiViewHiiHandle != NULL) {
443 HiiRemovePackages (gShellAcpiViewHiiHandle);
444 }
445 return EFI_SUCCESS;
446 }