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