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