UefiShellAcpiViewCommandLib.c 14 KB

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