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