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