Mm.c revision f79868cd18238805fe64d2ceca573e7c85ea8146
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 20typedef enum { 21 EfiMemory, 22 EFIMemoryMappedIo, 23 EfiIo, 24 EfiPciConfig, 25 EfiPciEConfig 26} EFI_ACCESS_TYPE; 27 28STATIC 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 39STATIC 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**/ 49VOID 50EFIAPI 51ReadMem ( 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**/ 91VOID 92EFIAPI 93WriteMem ( 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**/ 136BOOLEAN 137EFIAPI 138GetHex ( 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**/ 185VOID 186EFIAPI 187GetPciEAddressFromInputAddress ( 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**/ 202SHELL_STATUS 203EFIAPI 204ShellCommandRunMm ( 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); 633Done: 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} 646