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