]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
This patch replaces StrCpy with StrnCpy or refactors out the usage of StrCpy through...
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Mm.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for Mm shell Debug1 function.\r
3\r
81cd2f53 4 Copyright (c) 2005 - 2014, 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
81cd2f53 232 Value = 0;\r
5d73d92f 233 Address = 0;\r
234 PciEAddress = 0;\r
235 IoDev = NULL;\r
236 HandleBuffer = NULL;\r
237 BufferSize = 0;\r
238 SegmentNumber = 0;\r
239 ShellStatus = SHELL_SUCCESS;\r
240 InputStr = NULL;\r
241\r
242 //\r
243 // Parse arguments\r
244 //\r
245 Width = EfiPciWidthUint8;\r
246 Size = 1;\r
247 AccessType = EfiMemory;\r
5d73d92f 248// ValueStr = NULL;\r
249 Interactive = TRUE;\r
250 Package = NULL;\r
251\r
252 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
253 if (EFI_ERROR(Status)) {\r
254 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
255 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);\r
256 FreePool(ProblemParam);\r
257 ShellStatus = SHELL_INVALID_PARAMETER;\r
258 goto Done;\r
259 } else {\r
260 ASSERT(FALSE);\r
261 }\r
262 } else {\r
3737ac2b 263 if (ShellCommandLineGetCount(Package) < 2) {\r
5d73d92f 264 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
265 ShellStatus = SHELL_INVALID_PARAMETER;\r
266 goto Done;\r
267 } else if (ShellCommandLineGetCount(Package) > 3) {\r
268 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
269 ShellStatus = SHELL_INVALID_PARAMETER;\r
270 goto Done;\r
3737ac2b 271 } else if (ShellCommandLineGetFlag(Package, L"-w") && ShellCommandLineGetValue(Package, L"-w") == NULL) {\r
272 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-w");\r
273 ShellStatus = SHELL_INVALID_PARAMETER;\r
274 goto Done;\r
5d73d92f 275 } else {\r
276 if (ShellCommandLineGetFlag(Package, L"-mmio")) {\r
277 AccessType = EFIMemoryMappedIo;\r
3737ac2b 278 if (ShellCommandLineGetFlag(Package, L"-mem")\r
279 ||ShellCommandLineGetFlag(Package, L"-io")\r
280 ||ShellCommandLineGetFlag(Package, L"-pci")\r
281 ||ShellCommandLineGetFlag(Package, L"-pcie")\r
282 ){\r
283 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
284 ShellStatus = SHELL_INVALID_PARAMETER;\r
285 goto Done;\r
286 }\r
5d73d92f 287 } else if (ShellCommandLineGetFlag(Package, L"-mem")) {\r
288 AccessType = EfiMemory;\r
3737ac2b 289 if (ShellCommandLineGetFlag(Package, L"-io")\r
290 ||ShellCommandLineGetFlag(Package, L"-pci")\r
291 ||ShellCommandLineGetFlag(Package, L"-pcie")\r
292 ){\r
293 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
294 ShellStatus = SHELL_INVALID_PARAMETER;\r
295 goto Done;\r
296 }\r
5d73d92f 297 } else if (ShellCommandLineGetFlag(Package, L"-io")) {\r
298 AccessType = EfiIo;\r
3737ac2b 299 if (ShellCommandLineGetFlag(Package, L"-pci")\r
300 ||ShellCommandLineGetFlag(Package, L"-pcie")\r
301 ){\r
302 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
303 ShellStatus = SHELL_INVALID_PARAMETER;\r
304 goto Done;\r
305 }\r
5d73d92f 306 } else if (ShellCommandLineGetFlag(Package, L"-pci")) {\r
307 AccessType = EfiPciConfig;\r
3737ac2b 308 if (ShellCommandLineGetFlag(Package, L"-pcie")\r
309 ){\r
310 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
311 ShellStatus = SHELL_INVALID_PARAMETER;\r
312 goto Done;\r
313 }\r
5d73d92f 314 } else if (ShellCommandLineGetFlag(Package, L"-pcie")) {\r
315 AccessType = EfiPciEConfig;\r
316 }\r
317 }\r
318\r
f79868cd
JC
319 //\r
320 // Non interactive for a script file or for the specific parameter\r
321 //\r
322 if (gEfiShellProtocol->BatchIsActive() || ShellCommandLineGetFlag (Package, L"-n")) {\r
5d73d92f 323 Interactive = FALSE;\r
324 }\r
325\r
326 Temp = ShellCommandLineGetValue(Package, L"-w");\r
327 if (Temp != NULL) {\r
3737ac2b 328 ItemValue = ShellStrToUintn (Temp);\r
5d73d92f 329\r
330 switch (ItemValue) {\r
331 case 1:\r
332 Width = EfiPciWidthUint8;\r
333 Size = 1;\r
334 break;\r
335\r
336 case 2:\r
337 Width = EfiPciWidthUint16;\r
338 Size = 2;\r
339 break;\r
340\r
341 case 4:\r
342 Width = EfiPciWidthUint32;\r
343 Size = 4;\r
344 break;\r
345\r
346 case 8:\r
347 Width = EfiPciWidthUint64;\r
348 Size = 8;\r
349 break;\r
350\r
351 default:\r
3737ac2b 352 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"-w");\r
5d73d92f 353 ShellStatus = SHELL_INVALID_PARAMETER;\r
354 goto Done;\r
355 }\r
356 }\r
357\r
358 Temp = ShellCommandLineGetRawValue(Package, 1);\r
3737ac2b 359 if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, (UINT64*)&Address, TRUE, FALSE))) {\r
360 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);\r
361 ShellStatus = SHELL_INVALID_PARAMETER;\r
362 goto Done;\r
5d73d92f 363 }\r
364\r
365 Temp = ShellCommandLineGetRawValue(Package, 2);\r
366 if (Temp != NULL) {\r
f79868cd
JC
367 //\r
368 // Per spec if value is specified, then -n is assumed.\r
369 //\r
370 Interactive = FALSE;\r
371\r
3737ac2b 372 if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, &Value, TRUE, FALSE))) {\r
373 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);\r
374 ShellStatus = SHELL_INVALID_PARAMETER;\r
375 goto Done;\r
376 }\r
5d73d92f 377 switch (Size) {\r
378 case 1:\r
379 if (Value > 0xFF) {\r
380 ShellStatus = SHELL_INVALID_PARAMETER;\r
381 }\r
382 break;\r
383\r
384 case 2:\r
385 if (Value > 0xFFFF) {\r
386 ShellStatus = SHELL_INVALID_PARAMETER;\r
387 }\r
388 break;\r
389\r
390 case 4:\r
391 if (Value > 0xFFFFFFFF) {\r
392 ShellStatus = SHELL_INVALID_PARAMETER;\r
393 }\r
394 break;\r
395\r
396 default:\r
397 break;\r
398 }\r
399\r
400 if (ShellStatus != SHELL_SUCCESS) {\r
401 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);\r
402 ShellStatus = SHELL_INVALID_PARAMETER;\r
403 goto Done;\r
404 }\r
405 }\r
406\r
407 if ((Address & (Size - 1)) != 0) {\r
408 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_NOT_ALIGNED), gShellDebug1HiiHandle, Address);\r
409 ShellStatus = SHELL_INVALID_PARAMETER;\r
410 goto Done;\r
411 }\r
412 //\r
413 // locate DeviceIO protocol interface\r
414 //\r
415 if (AccessType != EfiMemory) {\r
416 Status = gBS->LocateHandleBuffer (\r
417 ByProtocol,\r
418 &gEfiPciRootBridgeIoProtocolGuid,\r
419 NULL,\r
420 &BufferSize,\r
421 &HandleBuffer\r
422 );\r
423 if (EFI_ERROR (Status)) {\r
424 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle);\r
425 ShellStatus = SHELL_NOT_FOUND;\r
426 goto Done;\r
427 }\r
428 //\r
429 // In the case of PCI or PCIE\r
430 // Get segment number and mask the segment bits in Address\r
431 //\r
432 if (AccessType == EfiPciEConfig) {\r
433 SegmentNumber = (UINT32) RShiftU64 (Address, 36) & 0xff;\r
e0c2cc6f 434 Address &= 0xfffffffffULL;\r
5d73d92f 435 } else {\r
436 if (AccessType == EfiPciConfig) {\r
437 SegmentNumber = (UINT32) RShiftU64 (Address, 32) & 0xff;\r
438 Address &= 0xffffffff;\r
439 }\r
440 }\r
441 //\r
442 // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment number\r
443 //\r
444 for (Index = 0; Index < BufferSize; Index++) {\r
445 Status = gBS->HandleProtocol (\r
446 HandleBuffer[Index],\r
447 &gEfiPciRootBridgeIoProtocolGuid,\r
448 (VOID *) &IoDev\r
449 );\r
450 if (EFI_ERROR (Status)) {\r
451 continue;\r
452 }\r
453 if (IoDev->SegmentNumber != SegmentNumber) {\r
454 IoDev = NULL;\r
455 }\r
456 }\r
457 if (IoDev == NULL) {\r
5d73d92f 458 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_SEGMENT_NOT_FOUND), gShellDebug1HiiHandle, SegmentNumber);\r
459 ShellStatus = SHELL_INVALID_PARAMETER;\r
460 goto Done;\r
461 }\r
462 }\r
463\r
464 if (AccessType == EfiIo && Address + Size > 0x10000) {\r
465 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE), gShellDebug1HiiHandle);\r
466 ShellStatus = SHELL_INVALID_PARAMETER;\r
467 goto Done;\r
468 }\r
469\r
470 if (AccessType == EfiPciEConfig) {\r
471 GetPciEAddressFromInputAddress (Address, &PciEAddress);\r
472 }\r
473\r
a0cd353d 474 //\r
475 // Set value\r
476 //\r
477 if (ShellCommandLineGetRawValue(Package, 2) != NULL) {\r
478 if (AccessType == EFIMemoryMappedIo) {\r
479 IoDev->Mem.Write (IoDev, Width, Address, 1, &Value);\r
480 } else if (AccessType == EfiIo) {\r
481 IoDev->Io.Write (IoDev, Width, Address, 1, &Value);\r
482 } else if (AccessType == EfiPciConfig) {\r
483 IoDev->Pci.Write (IoDev, Width, Address, 1, &Value);\r
484 } else if (AccessType == EfiPciEConfig) {\r
485 IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Value);\r
486 } else {\r
487 WriteMem (Width, Address, 1, &Value);\r
488 }\r
489\r
490 ASSERT(ShellStatus == SHELL_SUCCESS);\r
491 goto Done;\r
492 }\r
5d73d92f 493\r
494\r
495 //\r
496 // non-interactive mode\r
497 //\r
498 if (!Interactive) {\r
499 Buffer = 0;\r
500 if (AccessType == EFIMemoryMappedIo) {\r
f79868cd
JC
501 if (!gEfiShellProtocol->BatchIsActive()) {\r
502 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);\r
503 }\r
5d73d92f 504 IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);\r
505 } else if (AccessType == EfiIo) {\r
f79868cd
JC
506 if (!gEfiShellProtocol->BatchIsActive()) {\r
507 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);\r
508 }\r
5d73d92f 509 IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);\r
510 } else if (AccessType == EfiPciConfig) {\r
f79868cd
JC
511 if (!gEfiShellProtocol->BatchIsActive()) {\r
512 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);\r
513 }\r
5d73d92f 514 IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);\r
515 } else if (AccessType == EfiPciEConfig) {\r
f79868cd
JC
516 if (!gEfiShellProtocol->BatchIsActive()) {\r
517 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);\r
518 }\r
5d73d92f 519 IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);\r
520 } else {\r
f79868cd
JC
521 if (!gEfiShellProtocol->BatchIsActive()) {\r
522 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);\r
523 }\r
5d73d92f 524 ReadMem (Width, Address, 1, &Buffer);\r
525 }\r
f79868cd
JC
526 if (!gEfiShellProtocol->BatchIsActive()) {\r
527 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);\r
528 }\r
5d73d92f 529 if (Size == 1) {\r
a7e57bd9 530 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 531 } else if (Size == 2) {\r
a7e57bd9 532 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 533 } else if (Size == 4) {\r
a7e57bd9 534 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 535 } else if (Size == 8) {\r
536 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);\r
537 }\r
538\r
539 ShellPrintEx(-1, -1, L"\r\n");\r
540\r
541 ASSERT(ShellStatus == SHELL_SUCCESS);\r
542 goto Done;\r
543 }\r
544 //\r
545 // interactive mode\r
546 //\r
547 Complete = FALSE;\r
548 do {\r
549 if (AccessType == EfiIo && Address + Size > 0x10000) {\r
550 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE2), gShellDebug1HiiHandle);\r
5d73d92f 551 break;\r
552 }\r
553\r
554 Buffer = 0;\r
555 if (AccessType == EFIMemoryMappedIo) {\r
556 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);\r
5d73d92f 557 IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);\r
558 } else if (AccessType == EfiIo) {\r
559 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);\r
5d73d92f 560 IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);\r
561 } else if (AccessType == EfiPciConfig) {\r
562 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);\r
5d73d92f 563 IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);\r
564 } else if (AccessType == EfiPciEConfig) {\r
565 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);\r
5d73d92f 566 IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);\r
567 } else {\r
568 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);\r
5d73d92f 569 ReadMem (Width, Address, 1, &Buffer);\r
570 }\r
571\r
572 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);\r
5d73d92f 573\r
574 if (Size == 1) {\r
a7e57bd9 575 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 576 } else if (Size == 2) {\r
a7e57bd9 577 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 578 } else if (Size == 4) {\r
a7e57bd9 579 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);\r
5d73d92f 580 } else if (Size == 8) {\r
581 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);\r
5d73d92f 582 }\r
3737ac2b 583 ShellPrintEx(-1, -1, L" > ");\r
5d73d92f 584 //\r
585 // wait user input to modify\r
586 //\r
587 if (InputStr != NULL) {\r
588 FreePool(InputStr);\r
3737ac2b 589 InputStr = NULL;\r
5d73d92f 590 }\r
591 ShellPromptForResponse(ShellPromptResponseTypeFreeform, NULL, (VOID**)&InputStr);\r
592\r
593 //\r
594 // skip space characters\r
595 //\r
3737ac2b 596 for (Index = 0; InputStr != NULL && InputStr[Index] == ' '; Index++);\r
5d73d92f 597\r
598 //\r
599 // parse input string\r
600 //\r
3737ac2b 601 if (InputStr != NULL && (InputStr[Index] == '.' || InputStr[Index] == 'q' || InputStr[Index] == 'Q')) {\r
5d73d92f 602 Complete = TRUE;\r
3737ac2b 603 } else if (InputStr == NULL || InputStr[Index] == CHAR_NULL) {\r
5d73d92f 604 //\r
605 // Continue to next address\r
606 //\r
607 } else if (GetHex (InputStr + Index, &Buffer) && Buffer <= MaxNum[Width]) {\r
608 if (AccessType == EFIMemoryMappedIo) {\r
609 IoDev->Mem.Write (IoDev, Width, Address, 1, &Buffer);\r
610 } else if (AccessType == EfiIo) {\r
611 IoDev->Io.Write (IoDev, Width, Address, 1, &Buffer);\r
612 } else if (AccessType == EfiPciConfig) {\r
613 IoDev->Pci.Write (IoDev, Width, Address, 1, &Buffer);\r
614 } else if (AccessType == EfiPciEConfig) {\r
615 IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Buffer);\r
616 } else {\r
617 WriteMem (Width, Address, 1, &Buffer);\r
618 }\r
619 } else {\r
620 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle);\r
5d73d92f 621 continue;\r
3737ac2b 622 // PrintToken (STRING_TOKEN (STR_IOMOD_ERROR), HiiHandle);\r
5d73d92f 623 }\r
624\r
625 Address += Size;\r
626 if (AccessType == EfiPciEConfig) {\r
627 GetPciEAddressFromInputAddress (Address, &PciEAddress);\r
628 }\r
629 ShellPrintEx(-1, -1, L"\r\n");\r
630 // Print (L"\n");\r
631 } while (!Complete);\r
632 }\r
633 ASSERT(ShellStatus == SHELL_SUCCESS);\r
634Done:\r
635\r
636 if (InputStr != NULL) {\r
637 FreePool(InputStr);\r
638 }\r
639 if (HandleBuffer != NULL) {\r
640 FreePool (HandleBuffer);\r
641 }\r
642 if (Package != NULL) {\r
643 ShellCommandLineFreeVarList (Package);\r
644 }\r
645 return ShellStatus;\r
646}\r