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