UefiShellAcpiViewCommandLib.c 14 KB

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