]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
ShellPkg: Change MM command output during script execution
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Mm.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for Mm shell Debug1 function.\r
3\r
f79868cd 4 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>\r
5d73d92f 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellDebug1CommandsLib.h"\r
16#include <Library/ShellLib.h>\r
17#include <Protocol/PciRootBridgeIo.h>\r
18#include <Protocol/DeviceIo.h>\r
19\r
20typedef enum {\r
21 EfiMemory,\r
22 EFIMemoryMappedIo,\r
23 EfiIo,\r
24 EfiPciConfig,\r
25 EfiPciEConfig\r
26} EFI_ACCESS_TYPE;\r
27\r
3737ac2b 28STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
29 {L"-mmio", TypeFlag},\r
30 {L"-mem", TypeFlag},\r
31 {L"-io", TypeFlag},\r
32 {L"-pci", TypeFlag},\r
33 {L"-pcie", TypeFlag},\r
34 {L"-n", TypeFlag},\r
35 {L"-w", TypeValue},\r
36 {NULL, TypeMax}\r
37 };\r
38\r
e0c2cc6f 39STATIC CONST UINT64 MaxNum[9] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffULL };\r
3737ac2b 40\r
41/**\r
42 Read some data into a buffer from memory.\r
5d73d92f 43\r
3737ac2b 44 @param[in] Width The width of each read.\r
45 @param[in] Addresss The memory location to start reading at.\r
46 @param[in] Size The size of Buffer in Width sized units.\r
47 @param[out] Buffer The buffer to read into.\r
48**/\r
5d73d92f 49VOID\r
50EFIAPI\r
51ReadMem (\r
52 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
53 IN UINT64 Address,\r
54 IN UINTN Size,\r
3737ac2b 55 OUT VOID *Buffer\r
56 )\r
57{\r
58 //\r
59 // This function is defective. This ASSERT prevents the defect from affecting anything.\r
60 //\r
61 ASSERT(Size == 1);\r
62 do {\r
63 if (Width == EfiPciWidthUint8) {\r
64 *(UINT8 *) Buffer = *(UINT8 *) (UINTN) Address;\r
65 Address -= 1;\r
66 } else if (Width == EfiPciWidthUint16) {\r
67 *(UINT16 *) Buffer = *(UINT16 *) (UINTN) Address;\r
68 Address -= 2;\r
69 } else if (Width == EfiPciWidthUint32) {\r
70 *(UINT32 *) Buffer = *(UINT32 *) (UINTN) Address;\r
71 Address -= 4;\r
72 } else if (Width == EfiPciWidthUint64) {\r
73 *(UINT64 *) Buffer = *(UINT64 *) (UINTN) Address;\r
74 Address -= 8;\r
75 } else {\r
76 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_READ_ERROR), gShellDebug1HiiHandle);\r
77 break;\r
78 }\r
79 Size--;\r
80 } while (Size > 0);\r
81}\r
82\r
83/**\r
84 Write some data to memory.\r
5d73d92f 85\r
3737ac2b 86 @param[in] Width The width of each write.\r
87 @param[in] Addresss The memory location to start writing at.\r
88 @param[in] Size The size of Buffer in Width sized units.\r
89 @param[in] Buffer The buffer to write from.\r
90**/\r
5d73d92f 91VOID\r
92EFIAPI\r
93WriteMem (\r
94 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
95 IN UINT64 Address,\r
96 IN UINTN Size,\r
97 IN VOID *Buffer\r
3737ac2b 98 )\r
99{\r
100 //\r
101 // This function is defective. This ASSERT prevents the defect from affecting anything.\r
102 //\r
103 ASSERT(Size == 1);\r
104 do {\r
105 if (Width == EfiPciWidthUint8) {\r
106 *(UINT8 *) (UINTN) Address = *(UINT8 *) Buffer;\r
107 Address += 1;\r
108 } else if (Width == EfiPciWidthUint16) {\r
109 *(UINT16 *) (UINTN) Address = *(UINT16 *) Buffer;\r
110 Address += 2;\r
111 } else if (Width == EfiPciWidthUint32) {\r
112 *(UINT32 *) (UINTN) Address = *(UINT32 *) Buffer;\r
113 Address += 4;\r
114 } else if (Width == EfiPciWidthUint64) {\r
115 *(UINT64 *) (UINTN) Address = *(UINT64 *) Buffer;\r
116 Address += 8;\r
117 } else {\r
118 ASSERT (FALSE);\r
119 }\r
120 //\r
121 //\r
122 //\r
123 Size--;\r
124 } while (Size > 0);\r
125}\r
5d73d92f 126\r
3737ac2b 127/**\r
128 Convert a string to it's hex data.\r
129\r
130 @param[in] str The pointer to the string of hex data.\r
131 @param[out] data The pointer to the buffer to fill. Valid upon a TRUE return.\r
132\r
133 @retval TRUE The conversion was successful.\r
134 @retval FALSE The conversion failed.\r
135**/\r
5d73d92f 136BOOLEAN\r
137EFIAPI\r
138GetHex (\r
139 IN UINT16 *str,\r
140 OUT UINT64 *data\r
3737ac2b 141 )\r
142{\r
143 UINTN TempUint;\r
144 CHAR16 TempChar;\r
145 BOOLEAN Find;\r
5d73d92f 146\r
3737ac2b 147 Find = FALSE;\r
148 //\r
149 // convert hex digits\r
150 //\r
151 TempUint = 0;\r
152 TempChar = *(str++);\r
153 while (TempChar != CHAR_NULL) {\r
154 if (TempChar >= 'a' && TempChar <= 'f') {\r
155 TempChar -= 'a' - 'A';\r
156 }\r
5d73d92f 157\r
3737ac2b 158 if (TempChar == ' ') {\r
159 break;\r
160 }\r
161\r
162 if ((TempChar >= '0' && TempChar <= '9') || (TempChar >= 'A' && TempChar <= 'F')) {\r
f3c59716 163 TempUint = (TempUint << 4) | (TempChar - (TempChar >= 'A' ? 'A' - 10 : '0'));\r
3737ac2b 164\r
165 Find = TRUE;\r
166 } else {\r
167 return FALSE;\r
168 }\r
169\r
170 TempChar = *(str++);\r
171 }\r
172\r
173 *data = TempUint;\r
174 return Find;\r
175}\r
5d73d92f 176\r
177/**\r
178 Get the PCI-E Address from a PCI address format 0x0000ssbbddffrrr\r
179 where ss is SEGMENT, bb is BUS, dd is DEVICE, ff is FUNCTION\r
180 and rrr is REGISTER (extension format for PCI-E).\r
181\r
182 @param[in] InputAddress PCI address format on input.\r
183 @param[out]PciEAddress PCI-E address extention format.\r
184**/\r
185VOID\r
186EFIAPI\r
187GetPciEAddressFromInputAddress (\r
188 IN UINT64 InputAddress,\r
189 OUT UINT64 *PciEAddress\r
190 )\r
191{\r
192 *PciEAddress = RShiftU64(InputAddress & ~(UINT64) 0xFFF, 4);\r
193 *PciEAddress += LShiftU64((UINT16) InputAddress & 0x0FFF, 32);\r
194}\r
195\r
196/**\r
197 Function for 'mm' command.\r
198\r
199 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
200 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
201**/\r
202SHELL_STATUS\r
203EFIAPI\r
204ShellCommandRunMm (\r
205 IN EFI_HANDLE ImageHandle,\r
206 IN EFI_SYSTEM_TABLE *SystemTable\r
207 )\r
208{\r
209 EFI_STATUS Status;\r
210 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev;\r
211 UINT64 Address;\r
212 UINT64 PciEAddress;\r
213 UINT64 Value;\r
214 UINT32 SegmentNumber;\r
215 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width;\r
216 EFI_ACCESS_TYPE AccessType;\r
217 UINT64 Buffer;\r
218 UINTN Index;\r
219 UINTN Size;\r
5d73d92f 220// CHAR16 *ValueStr;\r
221 BOOLEAN Complete;\r
222 CHAR16 *InputStr;\r
223 BOOLEAN Interactive;\r
224 EFI_HANDLE *HandleBuffer;\r
225 UINTN BufferSize;\r
226 UINTN ItemValue;\r
227 LIST_ENTRY *Package;\r
228 CHAR16 *ProblemParam;\r
229 SHELL_STATUS ShellStatus;\r
230 CONST CHAR16 *Temp;\r
231\r
232 Address = 0;\r
233 PciEAddress = 0;\r
234 IoDev = NULL;\r
235 HandleBuffer = NULL;\r
236 BufferSize = 0;\r
237 SegmentNumber = 0;\r
238 ShellStatus = SHELL_SUCCESS;\r
239 InputStr = NULL;\r
240\r
241 //\r
242 // Parse arguments\r
243 //\r
244 Width = EfiPciWidthUint8;\r
245 Size = 1;\r
246 AccessType = EfiMemory;\r
5d73d92f 247// ValueStr = NULL;\r
248 Interactive = TRUE;\r
249 Package = NULL;\r
250\r
251 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
252 if (EFI_ERROR(Status)) {\r
253 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
254 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);\r
255 FreePool(ProblemParam);\r
256 ShellStatus = SHELL_INVALID_PARAMETER;\r
257 goto Done;\r
258 } else {\r
259 ASSERT(FALSE);\r
260 }\r
261 } else {\r
3737ac2b 262 if (ShellCommandLineGetCount(Package) < 2) {\r
5d73d92f 263 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
264 ShellStatus = SHELL_INVALID_PARAMETER;\r
265 goto Done;\r
266 } else if (ShellCommandLineGetCount(Package) > 3) {\r
267 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
268 ShellStatus = SHELL_INVALID_PARAMETER;\r
269 goto Done;\r
3737ac2b 270 } else if (ShellCommandLineGetFlag(Package, L"-w") && ShellCommandLineGetValue(Package, L"-w") == NULL) {\r
271 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-w");\r
272 ShellStatus = SHELL_INVALID_PARAMETER;\r
273 goto Done;\r
5d73d92f 274 } else {\r
275 if (ShellCommandLineGetFlag(Package, L"-mmio")) {\r
276 AccessType = EFIMemoryMappedIo;\r
3737ac2b 277 if (ShellCommandLineGetFlag(Package, L"-mem")\r
278 ||ShellCommandLineGetFlag(Package, L"-io")\r
279 ||ShellCommandLineGetFlag(Package, L"-pci")\r
280 ||ShellCommandLineGetFlag(Package, L"-pcie")\r
281 ){\r
282 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
283 ShellStatus = SHELL_INVALID_PARAMETER;\r
284 goto Done;\r
285 }\r
5d73d92f 286 } else if (ShellCommandLineGetFlag(Package, L"-mem")) {\r
287 AccessType = EfiMemory;\r
3737ac2b 288 if (ShellCommandLineGetFlag(Package, L"-io")\r
289 ||ShellCommandLineGetFlag(Package, L"-pci")\r
290 ||ShellCommandLineGetFlag(Package, L"-pcie")\r
291 ){\r
292 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
293 ShellStatus = SHELL_INVALID_PARAMETER;\r
294 goto Done;\r
295 }\r
5d73d92f 296 } else if (ShellCommandLineGetFlag(Package, L"-io")) {\r
297 AccessType = EfiIo;\r
3737ac2b 298 if (ShellCommandLineGetFlag(Package, L"-pci")\r
299 ||ShellCommandLineGetFlag(Package, L"-pcie")\r
300 ){\r
301 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
302 ShellStatus = SHELL_INVALID_PARAMETER;\r
303 goto Done;\r
304 }\r
5d73d92f 305 } else if (ShellCommandLineGetFlag(Package, L"-pci")) {\r
306 AccessType = EfiPciConfig;\r
3737ac2b 307 if (ShellCommandLineGetFlag(Package, L"-pcie")\r
308 ){\r
309 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
310 ShellStatus = SHELL_INVALID_PARAMETER;\r
311 goto Done;\r
312 }\r
5d73d92f 313 } else if (ShellCommandLineGetFlag(Package, L"-pcie")) {\r
314 AccessType = EfiPciEConfig;\r
315 }\r
316 }\r
317\r
f79868cd
JC
318 //\r
319 // Non interactive for a script file or for the specific parameter\r
320 //\r
321 if (gEfiShellProtocol->BatchIsActive() || ShellCommandLineGetFlag (Package, L"-n")) {\r
5d73d92f 322 Interactive = FALSE;\r
323 }\r
324\r
325 Temp = ShellCommandLineGetValue(Package, L"-w");\r
326 if (Temp != NULL) {\r
3737ac2b 327 ItemValue = ShellStrToUintn (Temp);\r
5d73d92f 328\r
329 switch (ItemValue) {\r
330 case 1:\r
331 Width = EfiPciWidthUint8;\r
332 Size = 1;\r
333 break;\r
334\r
335 case 2:\r
336 Width = EfiPciWidthUint16;\r
337 Size = 2;\r
338 break;\r
339\r
340 case 4:\r
341 Width = EfiPciWidthUint32;\r
342 Size = 4;\r
343 break;\r
344\r
345 case 8:\r
346 Width = EfiPciWidthUint64;\r
347 Size = 8;\r
348 break;\r
349\r
350 default:\r
3737ac2b 351 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"-w");\r
5d73d92f 352 ShellStatus = SHELL_INVALID_PARAMETER;\r
353 goto Done;\r
354 }\r
355 }\r
356\r
357 Temp = ShellCommandLineGetRawValue(Package, 1);\r
3737ac2b 358 if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, (UINT64*)&Address, TRUE, FALSE))) {\r
359 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);\r
360 ShellStatus = SHELL_INVALID_PARAMETER;\r
361 goto Done;\r
5d73d92f 362 }\r
363\r
364 Temp = ShellCommandLineGetRawValue(Package, 2);\r
365 if (Temp != NULL) {\r
f79868cd
JC
366 //\r
367 // Per spec if value is specified, then -n is assumed.\r
368 //\r
369 Interactive = FALSE;\r
370\r
3737ac2b 371 if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, &Value, TRUE, FALSE))) {\r
372 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);\r
373 ShellStatus = SHELL_INVALID_PARAMETER;\r
374 goto Done;\r
375 }\r
5d73d92f 376 switch (Size) {\r
377 case 1:\r
378 if (Value > 0xFF) {\r
379 ShellStatus = SHELL_INVALID_PARAMETER;\r
380 }\r
381 break;\r
382\r
383 case 2:\r
384 if (Value > 0xFFFF) {\r
385 ShellStatus = SHELL_INVALID_PARAMETER;\r
386 }\r
387 break;\r
388\r
389 case 4:\r
390 if (Value > 0xFFFFFFFF) {\r
391 ShellStatus = SHELL_INVALID_PARAMETER;\r
392 }\r
393 break;\r
394\r
395 default:\r
396 break;\r
397 }\r
398\r
399 if (ShellStatus != SHELL_SUCCESS) {\r
400 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);\r
401 ShellStatus = SHELL_INVALID_PARAMETER;\r
402 goto Done;\r
403 }\r
404 }\r
405\r
406 if ((Address & (Size - 1)) != 0) {\r
407 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_NOT_ALIGNED), gShellDebug1HiiHandle, Address);\r
408 ShellStatus = SHELL_INVALID_PARAMETER;\r
409 goto Done;\r
410 }\r
411 //\r
412 // locate DeviceIO protocol interface\r
413 //\r
414 if (AccessType != EfiMemory) {\r
415 Status = gBS->LocateHandleBuffer (\r
416 ByProtocol,\r
417 &gEfiPciRootBridgeIoProtocolGuid,\r
418 NULL,\r
419 &BufferSize,\r
420 &HandleBuffer\r
421 );\r
422 if (EFI_ERROR (Status)) {\r
423 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle);\r
424 ShellStatus = SHELL_NOT_FOUND;\r
425 goto Done;\r
426 }\r
427 //\r
428 // In the case of PCI or PCIE\r
429 // Get segment number and mask the segment bits in Address\r
430 //\r
431 if (AccessType == EfiPciEConfig) {\r
432 SegmentNumber = (UINT32) RShiftU64 (Address, 36) & 0xff;\r
e0c2cc6f 433 Address &= 0xfffffffffULL;\r
5d73d92f 434 } else {\r
435 if (AccessType == EfiPciConfig) {\r
436 SegmentNumber = (UINT32) RShiftU64 (Address, 32) & 0xff;\r
437 Address &= 0xffffffff;\r
438 }\r
439 }\r
440 //\r
441 // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment number\r
442 //\r
443 for (Index = 0; Index < BufferSize; Index++) {\r
444 Status = gBS->HandleProtocol (\r
445 HandleBuffer[Index],\r
446 &gEfiPciRootBridgeIoProtocolGuid,\r
447 (VOID *) &IoDev\r
448 );\r
449 if (EFI_ERROR (Status)) {\r
450 continue;\r
451 }\r
452 if (IoDev->SegmentNumber != SegmentNumber) {\r
453 IoDev = NULL;\r
454 }\r
455 }\r
456 if (IoDev == NULL) {\r
5d73d92f 457 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_SEGMENT_NOT_FOUND), gShellDebug1HiiHandle, SegmentNumber);\r
458 ShellStatus = SHELL_INVALID_PARAMETER;\r
459 goto Done;\r
460 }\r
461 }\r
462\r
463 if (AccessType == EfiIo && Address + Size > 0x10000) {\r
464 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE), gShellDebug1HiiHandle);\r
465 ShellStatus = SHELL_INVALID_PARAMETER;\r
466 goto Done;\r
467 }\r
468\r
469 if (AccessType == EfiPciEConfig) {\r
470 GetPciEAddressFromInputAddress (Address, &PciEAddress);\r
471 }\r
472\r
a0cd353d 473 //\r
474 // Set value\r
475 //\r
476 if (ShellCommandLineGetRawValue(Package, 2) != NULL) {\r
477 if (AccessType == EFIMemoryMappedIo) {\r
478 IoDev->Mem.Write (IoDev, Width, Address, 1, &Value);\r
479 } else if (AccessType == EfiIo) {\r
480 IoDev->Io.Write (IoDev, Width, Address, 1, &Value);\r
481 } else if (AccessType == EfiPciConfig) {\r
482 IoDev->Pci.Write (IoDev, Width, Address, 1, &Value);\r
483 } else if (AccessType == EfiPciEConfig) {\r
484 IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Value);\r
485 } else {\r
486 WriteMem (Width, Address, 1, &Value);\r
487 }\r
488\r
489 ASSERT(ShellStatus == SHELL_SUCCESS);\r
490 goto Done;\r
491 }\r
5d73d92f 492\r
493\r
494 //\r
495 // non-interactive mode\r
496 //\r
497 if (!Interactive) {\r
498 Buffer = 0;\r
499 if (AccessType == EFIMemoryMappedIo) {\r
f79868cd
JC
500 if (!gEfiShellProtocol->BatchIsActive()) {\r
501 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);\r
502 }\r
5d73d92f 503 IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);\r
504 } else if (AccessType == EfiIo) {\r
f79868cd
JC
505 if (!gEfiShellProtocol->BatchIsActive()) {\r
506 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);\r
507 }\r
5d73d92f 508 IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);\r
509 } else if (AccessType == EfiPciConfig) {\r
f79868cd
JC
510 if (!gEfiShellProtocol->BatchIsActive()) {\r
511 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);\r
512 }\r
5d73d92f 513 IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);\r
514 } else if (AccessType == EfiPciEConfig) {\r
f79868cd
JC
515 if (!gEfiShellProtocol->BatchIsActive()) {\r
516 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);\r
517 }\r
5d73d92f 518 IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);\r
519 } else {\r
f79868cd
JC
520 if (!gEfiShellProtocol->BatchIsActive()) {\r
521 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);\r
522 }\r
5d73d92f 523 ReadMem (Width, Address, 1, &Buffer);\r
524 }\r
f79868cd
JC
525 if (!gEfiShellProtocol->BatchIsActive()) {\r
526 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);\r
527 }\r
5d73d92f 528 if (Size == 1) {\r
a7e57bd9 529 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 530 } else if (Size == 2) {\r
a7e57bd9 531 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 532 } else if (Size == 4) {\r
a7e57bd9 533 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 534 } else if (Size == 8) {\r
535 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);\r
536 }\r
537\r
538 ShellPrintEx(-1, -1, L"\r\n");\r
539\r
540 ASSERT(ShellStatus == SHELL_SUCCESS);\r
541 goto Done;\r
542 }\r
543 //\r
544 // interactive mode\r
545 //\r
546 Complete = FALSE;\r
547 do {\r
548 if (AccessType == EfiIo && Address + Size > 0x10000) {\r
549 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE2), gShellDebug1HiiHandle);\r
5d73d92f 550 break;\r
551 }\r
552\r
553 Buffer = 0;\r
554 if (AccessType == EFIMemoryMappedIo) {\r
555 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);\r
5d73d92f 556 IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);\r
557 } else if (AccessType == EfiIo) {\r
558 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);\r
5d73d92f 559 IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);\r
560 } else if (AccessType == EfiPciConfig) {\r
561 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);\r
5d73d92f 562 IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);\r
563 } else if (AccessType == EfiPciEConfig) {\r
564 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);\r
5d73d92f 565 IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);\r
566 } else {\r
567 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);\r
5d73d92f 568 ReadMem (Width, Address, 1, &Buffer);\r
569 }\r
570\r
571 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);\r
5d73d92f 572\r
573 if (Size == 1) {\r
a7e57bd9 574 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 575 } else if (Size == 2) {\r
a7e57bd9 576 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 577 } else if (Size == 4) {\r
a7e57bd9 578 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 579 } else if (Size == 8) {\r
580 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);\r
5d73d92f 581 }\r
3737ac2b 582 ShellPrintEx(-1, -1, L" > ");\r
5d73d92f 583 //\r
584 // wait user input to modify\r
585 //\r
586 if (InputStr != NULL) {\r
587 FreePool(InputStr);\r
3737ac2b 588 InputStr = NULL;\r
5d73d92f 589 }\r
590 ShellPromptForResponse(ShellPromptResponseTypeFreeform, NULL, (VOID**)&InputStr);\r
591\r
592 //\r
593 // skip space characters\r
594 //\r
3737ac2b 595 for (Index = 0; InputStr != NULL && InputStr[Index] == ' '; Index++);\r
5d73d92f 596\r
597 //\r
598 // parse input string\r
599 //\r
3737ac2b 600 if (InputStr != NULL && (InputStr[Index] == '.' || InputStr[Index] == 'q' || InputStr[Index] == 'Q')) {\r
5d73d92f 601 Complete = TRUE;\r
3737ac2b 602 } else if (InputStr == NULL || InputStr[Index] == CHAR_NULL) {\r
5d73d92f 603 //\r
604 // Continue to next address\r
605 //\r
606 } else if (GetHex (InputStr + Index, &Buffer) && Buffer <= MaxNum[Width]) {\r
607 if (AccessType == EFIMemoryMappedIo) {\r
608 IoDev->Mem.Write (IoDev, Width, Address, 1, &Buffer);\r
609 } else if (AccessType == EfiIo) {\r
610 IoDev->Io.Write (IoDev, Width, Address, 1, &Buffer);\r
611 } else if (AccessType == EfiPciConfig) {\r
612 IoDev->Pci.Write (IoDev, Width, Address, 1, &Buffer);\r
613 } else if (AccessType == EfiPciEConfig) {\r
614 IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Buffer);\r
615 } else {\r
616 WriteMem (Width, Address, 1, &Buffer);\r
617 }\r
618 } else {\r
619 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle);\r
5d73d92f 620 continue;\r
3737ac2b 621 // PrintToken (STRING_TOKEN (STR_IOMOD_ERROR), HiiHandle);\r
5d73d92f 622 }\r
623\r
624 Address += Size;\r
625 if (AccessType == EfiPciEConfig) {\r
626 GetPciEAddressFromInputAddress (Address, &PciEAddress);\r
627 }\r
628 ShellPrintEx(-1, -1, L"\r\n");\r
629 // Print (L"\n");\r
630 } while (!Complete);\r
631 }\r
632 ASSERT(ShellStatus == SHELL_SUCCESS);\r
633Done:\r
634\r
635 if (InputStr != NULL) {\r
636 FreePool(InputStr);\r
637 }\r
638 if (HandleBuffer != NULL) {\r
639 FreePool (HandleBuffer);\r
640 }\r
641 if (Package != NULL) {\r
642 ShellCommandLineFreeVarList (Package);\r
643 }\r
644 return ShellStatus;\r
645}\r