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