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