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