ShellPkg/UefiShellDebug1CommandsLib
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Dmem.c
1 /** @file\r
2   Main file for Dmem shell Debug1 function.\r
3 \r
4   Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
5   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
6   (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
7   SPDX-License-Identifier: BSD-2-Clause-Patent\r
8 \r
9 **/\r
10 \r
11 #include "UefiShellDebug1CommandsLib.h"\r
12 #include <Protocol/PciRootBridgeIo.h>\r
13 #include <Guid/Acpi.h>\r
14 #include <Guid/Mps.h>\r
15 #include <Guid/SmBios.h>\r
16 \r
17 /**\r
18   Make a printable character.\r
19 \r
20   If Char is printable then return it, otherwise return a question mark.\r
21 \r
22   @param[in] Char     The character to make printable.\r
23 \r
24   @return A printable character representing Char.\r
25 **/\r
26 CHAR16\r
27 MakePrintable(\r
28   IN CONST CHAR16 Char\r
29   )\r
30 {\r
31   if ((Char < 0x20 && Char > 0)||(Char > 126)) {\r
32     return (L'?');\r
33   }\r
34   return (Char);\r
35 }\r
36 \r
37 /**\r
38   Display some Memory-Mapped-IO memory.\r
39 \r
40   @param[in] Address    The starting address to display.\r
41   @param[in] Size       The length of memory to display.\r
42 **/\r
43 SHELL_STATUS\r
44 DisplayMmioMemory(\r
45   IN CONST VOID   *Address,\r
46   IN CONST UINTN  Size\r
47   )\r
48 {\r
49   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRbIo;\r
50   EFI_STATUS                      Status;\r
51   VOID                            *Buffer;\r
52   SHELL_STATUS                    ShellStatus;\r
53 \r
54   ShellStatus = SHELL_SUCCESS;\r
55 \r
56   Status = gBS->LocateProtocol(&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID**)&PciRbIo);\r
57   if (EFI_ERROR(Status)) {\r
58     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"dmem");\r
59     return (SHELL_NOT_FOUND);\r
60   }\r
61   Buffer = AllocateZeroPool(Size);\r
62   if (Buffer == NULL) {\r
63     return SHELL_OUT_OF_RESOURCES;\r
64   }\r
65 \r
66   Status = PciRbIo->Mem.Read(PciRbIo, EfiPciWidthUint8, (UINT64)(UINTN)Address, Size, Buffer);\r
67   if (EFI_ERROR(Status)) {\r
68     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_ER), gShellDebug1HiiHandle, L"dmem");\r
69     ShellStatus = SHELL_NOT_FOUND;\r
70   } else {\r
71     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMEM_MMIO_HEADER_ROW), gShellDebug1HiiHandle, (UINT64)(UINTN)Address, Size);\r
72     DumpHex(2, (UINTN)Address, Size, Buffer);\r
73   }\r
74 \r
75   FreePool(Buffer);\r
76   return (ShellStatus);\r
77 }\r
78 \r
79 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
80   {L"-mmio", TypeFlag},\r
81   {NULL, TypeMax}\r
82   };\r
83 \r
84 /**\r
85   Function for 'dmem' command.\r
86 \r
87   @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
88   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
89 **/\r
90 SHELL_STATUS\r
91 EFIAPI\r
92 ShellCommandRunDmem (\r
93   IN EFI_HANDLE        ImageHandle,\r
94   IN EFI_SYSTEM_TABLE  *SystemTable\r
95   )\r
96 {\r
97   EFI_STATUS          Status;\r
98   LIST_ENTRY          *Package;\r
99   CHAR16              *ProblemParam;\r
100   SHELL_STATUS        ShellStatus;\r
101   VOID                *Address;\r
102   UINT64              Size;\r
103   CONST CHAR16        *Temp1;\r
104   UINT64              AcpiTableAddress;\r
105   UINT64              Acpi20TableAddress;\r
106   UINT64              SalTableAddress;\r
107   UINT64              SmbiosTableAddress;\r
108   UINT64              MpsTableAddress;\r
109   UINTN               TableWalker;\r
110 \r
111   ShellStatus         = SHELL_SUCCESS;\r
112   Status              = EFI_SUCCESS;\r
113   Address             = NULL;\r
114   Size                = 0;\r
115 \r
116   //\r
117   // initialize the shell lib (we must be in non-auto-init...)\r
118   //\r
119   Status = ShellInitialize();\r
120   ASSERT_EFI_ERROR(Status);\r
121 \r
122   Status = CommandInit();\r
123   ASSERT_EFI_ERROR(Status);\r
124 \r
125   //\r
126   // parse the command line\r
127   //\r
128   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
129   if (EFI_ERROR(Status)) {\r
130     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
131       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"dmem", ProblemParam);\r
132       FreePool(ProblemParam);\r
133       ShellStatus = SHELL_INVALID_PARAMETER;\r
134     } else {\r
135       ASSERT(FALSE);\r
136     }\r
137   } else {\r
138     if (ShellCommandLineGetCount(Package) > 3) {\r
139       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmem");\r
140       ShellStatus = SHELL_INVALID_PARAMETER;\r
141     } else {\r
142       Temp1 = ShellCommandLineGetRawValue(Package, 1);\r
143       if (Temp1 == NULL) {\r
144         Address = gST;\r
145         Size    = sizeof (*gST);\r
146       } else {\r
147         if (!ShellIsHexOrDecimalNumber(Temp1, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp1, (UINT64*)&Address, TRUE, FALSE))) {\r
148           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmem", Temp1);\r
149           ShellStatus = SHELL_INVALID_PARAMETER;\r
150         }\r
151         Temp1 = ShellCommandLineGetRawValue(Package, 2);\r
152         if (Temp1 == NULL) {\r
153           Size = 512;\r
154         } else {\r
155           if (!ShellIsHexOrDecimalNumber(Temp1, FALSE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp1, &Size, TRUE, FALSE))) {\r
156             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmem", Temp1);\r
157             ShellStatus = SHELL_INVALID_PARAMETER;\r
158           }\r
159         }\r
160       }\r
161     }\r
162 \r
163     if (ShellStatus == SHELL_SUCCESS) {\r
164       if (!ShellCommandLineGetFlag(Package, L"-mmio")) {\r
165         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMEM_HEADER_ROW), gShellDebug1HiiHandle, (UINT64)(UINTN)Address, Size);\r
166         DumpHex(2, (UINTN)Address, (UINTN)Size, Address);\r
167         if (Address == (VOID*)gST) {\r
168           Acpi20TableAddress  = 0;\r
169           AcpiTableAddress    = 0;\r
170           SalTableAddress     = 0;\r
171           SmbiosTableAddress  = 0;\r
172           MpsTableAddress     = 0;\r
173           for (TableWalker = 0 ; TableWalker < gST->NumberOfTableEntries ; TableWalker++) {\r
174             if (CompareGuid(&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiAcpi20TableGuid)) {\r
175               Acpi20TableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable;\r
176               continue;\r
177             }\r
178             if (CompareGuid(&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiAcpi10TableGuid)) {\r
179               AcpiTableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable;\r
180               continue;\r
181             }\r
182             if (CompareGuid(&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiSmbiosTableGuid)) {\r
183               SmbiosTableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable;\r
184               continue;\r
185             }\r
186             if (CompareGuid (&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiSmbios3TableGuid)) {\r
187               SmbiosTableAddress = (UINT64) (UINTN) gST->ConfigurationTable[TableWalker].VendorTable;\r
188               continue;\r
189             }\r
190             if (CompareGuid(&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiMpsTableGuid)) {\r
191               MpsTableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable;\r
192               continue;\r
193             }\r
194           }\r
195 \r
196           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMEM_SYSTEM_TABLE), gShellDebug1HiiHandle,\r
197             (UINT64)(UINTN)Address,\r
198             gST->Hdr.HeaderSize,\r
199             gST->Hdr.Revision,\r
200             (UINT64)(UINTN)gST->ConIn,\r
201             (UINT64)(UINTN)gST->ConOut,\r
202             (UINT64)(UINTN)gST->StdErr,\r
203             (UINT64)(UINTN)gST->RuntimeServices,\r
204             (UINT64)(UINTN)gST->BootServices,\r
205             SalTableAddress,\r
206             AcpiTableAddress,\r
207             Acpi20TableAddress,\r
208             MpsTableAddress,\r
209             SmbiosTableAddress\r
210             );\r
211         }\r
212       } else {\r
213         ShellStatus = DisplayMmioMemory(Address, (UINTN)Size);\r
214       }\r
215     }\r
216 \r
217 \r
218     ShellCommandLineFreeVarList (Package);\r
219   }\r
220 \r
221   return (ShellStatus);\r
222 }\r