Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Eugene Cohen eugene@hp.com Reviewed-by: Eric Dong <eric.dong@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13597 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			629 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			629 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Main file for Mm shell Debug1 function.
 | 
						|
 | 
						|
  Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
 | 
						|
  This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "UefiShellDebug1CommandsLib.h"
 | 
						|
#include <Library/ShellLib.h>
 | 
						|
#include <Protocol/PciRootBridgeIo.h>
 | 
						|
#include <Protocol/DeviceIo.h>
 | 
						|
 | 
						|
typedef enum {
 | 
						|
  EfiMemory,
 | 
						|
  EFIMemoryMappedIo,
 | 
						|
  EfiIo,
 | 
						|
  EfiPciConfig,
 | 
						|
  EfiPciEConfig
 | 
						|
} EFI_ACCESS_TYPE;
 | 
						|
 | 
						|
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
 | 
						|
  {L"-mmio", TypeFlag},
 | 
						|
  {L"-mem", TypeFlag},
 | 
						|
  {L"-io", TypeFlag},
 | 
						|
  {L"-pci", TypeFlag},
 | 
						|
  {L"-pcie", TypeFlag},
 | 
						|
  {L"-n", TypeFlag},
 | 
						|
  {L"-w", TypeValue},
 | 
						|
  {NULL, TypeMax}
 | 
						|
  };
 | 
						|
 | 
						|
STATIC CONST UINT64 MaxNum[9]      = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffULL };
 | 
						|
 | 
						|
/**
 | 
						|
  Read some data into a buffer from memory.
 | 
						|
 | 
						|
  @param[in] Width    The width of each read.
 | 
						|
  @param[in] Addresss The memory location to start reading at.
 | 
						|
  @param[in] Size     The size of Buffer in Width sized units.
 | 
						|
  @param[out] Buffer  The buffer to read into.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
ReadMem (
 | 
						|
  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
 | 
						|
  IN  UINT64        Address,
 | 
						|
  IN  UINTN         Size,
 | 
						|
  OUT VOID          *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // This function is defective.  This ASSERT prevents the defect from affecting anything.
 | 
						|
  //
 | 
						|
  ASSERT(Size == 1);
 | 
						|
  do {
 | 
						|
    if (Width == EfiPciWidthUint8) {
 | 
						|
      *(UINT8 *) Buffer = *(UINT8 *) (UINTN) Address;
 | 
						|
      Address -= 1;
 | 
						|
    } else if (Width == EfiPciWidthUint16) {
 | 
						|
      *(UINT16 *) Buffer = *(UINT16 *) (UINTN) Address;
 | 
						|
      Address -= 2;
 | 
						|
    } else if (Width == EfiPciWidthUint32) {
 | 
						|
      *(UINT32 *) Buffer = *(UINT32 *) (UINTN) Address;
 | 
						|
      Address -= 4;
 | 
						|
    } else if (Width == EfiPciWidthUint64) {
 | 
						|
      *(UINT64 *) Buffer = *(UINT64 *) (UINTN) Address;
 | 
						|
      Address -= 8;
 | 
						|
    } else {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_READ_ERROR), gShellDebug1HiiHandle);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    Size--;
 | 
						|
  } while (Size > 0);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Write some data to memory.
 | 
						|
 | 
						|
  @param[in] Width    The width of each write.
 | 
						|
  @param[in] Addresss The memory location to start writing at.
 | 
						|
  @param[in] Size     The size of Buffer in Width sized units.
 | 
						|
  @param[in] Buffer   The buffer to write from.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
WriteMem (
 | 
						|
  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
 | 
						|
  IN  UINT64        Address,
 | 
						|
  IN  UINTN         Size,
 | 
						|
  IN  VOID          *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // This function is defective.  This ASSERT prevents the defect from affecting anything.
 | 
						|
  //
 | 
						|
  ASSERT(Size == 1);
 | 
						|
  do {
 | 
						|
    if (Width == EfiPciWidthUint8) {
 | 
						|
      *(UINT8 *) (UINTN) Address = *(UINT8 *) Buffer;
 | 
						|
      Address += 1;
 | 
						|
    } else if (Width == EfiPciWidthUint16) {
 | 
						|
      *(UINT16 *) (UINTN) Address = *(UINT16 *) Buffer;
 | 
						|
      Address += 2;
 | 
						|
    } else if (Width == EfiPciWidthUint32) {
 | 
						|
      *(UINT32 *) (UINTN) Address = *(UINT32 *) Buffer;
 | 
						|
      Address += 4;
 | 
						|
    } else if (Width == EfiPciWidthUint64) {
 | 
						|
      *(UINT64 *) (UINTN) Address = *(UINT64 *) Buffer;
 | 
						|
      Address += 8;
 | 
						|
    } else {
 | 
						|
      ASSERT (FALSE);
 | 
						|
    }
 | 
						|
    //
 | 
						|
    //
 | 
						|
    //
 | 
						|
    Size--;
 | 
						|
  } while (Size > 0);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Convert a string to it's hex data.
 | 
						|
 | 
						|
  @param[in] str    The pointer to the string of hex data.
 | 
						|
  @param[out] data  The pointer to the buffer to fill.  Valid upon a TRUE return.
 | 
						|
 | 
						|
  @retval TRUE      The conversion was successful.
 | 
						|
  @retval FALSE     The conversion failed.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
GetHex (
 | 
						|
  IN  UINT16  *str,
 | 
						|
  OUT UINT64  *data
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN   TempUint;
 | 
						|
  CHAR16  TempChar;
 | 
						|
  BOOLEAN Find;
 | 
						|
 | 
						|
  Find = FALSE;
 | 
						|
  //
 | 
						|
  // convert hex digits
 | 
						|
  //
 | 
						|
  TempUint = 0;
 | 
						|
  TempChar = *(str++);
 | 
						|
  while (TempChar != CHAR_NULL) {
 | 
						|
    if (TempChar >= 'a' && TempChar <= 'f') {
 | 
						|
      TempChar -= 'a' - 'A';
 | 
						|
    }
 | 
						|
 | 
						|
    if (TempChar == ' ') {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((TempChar >= '0' && TempChar <= '9') || (TempChar >= 'A' && TempChar <= 'F')) {
 | 
						|
      TempUint     = (TempUint << 4) | (TempChar - (TempChar >= 'A' ? 'A' - 10 : '0'));
 | 
						|
 | 
						|
      Find  = TRUE;
 | 
						|
    } else {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    TempChar = *(str++);
 | 
						|
  }
 | 
						|
 | 
						|
  *data = TempUint;
 | 
						|
  return Find;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get the PCI-E Address from a PCI address format 0x0000ssbbddffrrr
 | 
						|
  where ss is SEGMENT, bb is BUS, dd is DEVICE, ff is FUNCTION
 | 
						|
  and rrr is REGISTER (extension format for PCI-E).
 | 
						|
 | 
						|
  @param[in] InputAddress       PCI address format on input.
 | 
						|
  @param[out]PciEAddress        PCI-E address extention format.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
GetPciEAddressFromInputAddress (
 | 
						|
  IN UINT64                 InputAddress,
 | 
						|
  OUT UINT64                *PciEAddress
 | 
						|
  )
 | 
						|
{
 | 
						|
  *PciEAddress = RShiftU64(InputAddress & ~(UINT64) 0xFFF, 4);
 | 
						|
  *PciEAddress += LShiftU64((UINT16) InputAddress & 0x0FFF, 32);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function for 'mm' command.
 | 
						|
 | 
						|
  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
 | 
						|
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
 | 
						|
**/
 | 
						|
SHELL_STATUS
 | 
						|
EFIAPI
 | 
						|
ShellCommandRunMm (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev;
 | 
						|
  UINT64                          Address;
 | 
						|
  UINT64                          PciEAddress;
 | 
						|
  UINT64                          Value;
 | 
						|
  UINT32                          SegmentNumber;
 | 
						|
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH                    Width;
 | 
						|
  EFI_ACCESS_TYPE                 AccessType;
 | 
						|
  UINT64                          Buffer;
 | 
						|
  UINTN                           Index;
 | 
						|
  UINTN                           Size;
 | 
						|
  CHAR16                          *AddressStr;
 | 
						|
//  CHAR16                          *ValueStr;
 | 
						|
  BOOLEAN                         Complete;
 | 
						|
  CHAR16                          *InputStr;
 | 
						|
  BOOLEAN                         Interactive;
 | 
						|
  EFI_HANDLE                      *HandleBuffer;
 | 
						|
  UINTN                           BufferSize;
 | 
						|
  UINTN                           ItemValue;
 | 
						|
  LIST_ENTRY                      *Package;
 | 
						|
  CHAR16                          *ProblemParam;
 | 
						|
  SHELL_STATUS                    ShellStatus;
 | 
						|
  CONST CHAR16                    *Temp;
 | 
						|
 | 
						|
  Address       = 0;
 | 
						|
  PciEAddress   = 0;
 | 
						|
  IoDev         = NULL;
 | 
						|
  HandleBuffer  = NULL;
 | 
						|
  BufferSize    = 0;
 | 
						|
  SegmentNumber = 0;
 | 
						|
  ShellStatus   = SHELL_SUCCESS;
 | 
						|
  InputStr      = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Parse arguments
 | 
						|
  //
 | 
						|
  Width       = EfiPciWidthUint8;
 | 
						|
  Size        = 1;
 | 
						|
  AccessType  = EfiMemory;
 | 
						|
  AddressStr  = NULL;
 | 
						|
//  ValueStr    = NULL;
 | 
						|
  Interactive = TRUE;
 | 
						|
  Package     = NULL;
 | 
						|
 | 
						|
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
 | 
						|
  if (EFI_ERROR(Status)) {
 | 
						|
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);
 | 
						|
      FreePool(ProblemParam);
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      goto Done;
 | 
						|
    } else {
 | 
						|
      ASSERT(FALSE);
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    if (ShellCommandLineGetCount(Package) < 2) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      goto Done;
 | 
						|
    } else if (ShellCommandLineGetCount(Package) > 3) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      goto Done;
 | 
						|
    } else if (ShellCommandLineGetFlag(Package, L"-w") && ShellCommandLineGetValue(Package, L"-w") == NULL) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-w");
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      goto Done;
 | 
						|
    } else {
 | 
						|
      if (ShellCommandLineGetFlag(Package, L"-mmio")) {
 | 
						|
        AccessType = EFIMemoryMappedIo;
 | 
						|
        if (ShellCommandLineGetFlag(Package, L"-mem")
 | 
						|
          ||ShellCommandLineGetFlag(Package, L"-io")
 | 
						|
          ||ShellCommandLineGetFlag(Package, L"-pci")
 | 
						|
          ||ShellCommandLineGetFlag(Package, L"-pcie")
 | 
						|
        ){
 | 
						|
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
          goto Done;
 | 
						|
        }
 | 
						|
      } else if (ShellCommandLineGetFlag(Package, L"-mem")) {
 | 
						|
        AccessType = EfiMemory;
 | 
						|
        if (ShellCommandLineGetFlag(Package, L"-io")
 | 
						|
          ||ShellCommandLineGetFlag(Package, L"-pci")
 | 
						|
          ||ShellCommandLineGetFlag(Package, L"-pcie")
 | 
						|
        ){
 | 
						|
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
          goto Done;
 | 
						|
        }
 | 
						|
      } else if (ShellCommandLineGetFlag(Package, L"-io")) {
 | 
						|
        AccessType = EfiIo;
 | 
						|
        if (ShellCommandLineGetFlag(Package, L"-pci")
 | 
						|
          ||ShellCommandLineGetFlag(Package, L"-pcie")
 | 
						|
        ){
 | 
						|
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
          goto Done;
 | 
						|
        }
 | 
						|
      } else if (ShellCommandLineGetFlag(Package, L"-pci")) {
 | 
						|
        AccessType = EfiPciConfig;
 | 
						|
        if (ShellCommandLineGetFlag(Package, L"-pcie")
 | 
						|
        ){
 | 
						|
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
          goto Done;
 | 
						|
        }
 | 
						|
      } else if (ShellCommandLineGetFlag(Package, L"-pcie")) {
 | 
						|
        AccessType = EfiPciEConfig;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (ShellCommandLineGetFlag (Package, L"-n")) {
 | 
						|
      Interactive = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    Temp = ShellCommandLineGetValue(Package, L"-w");
 | 
						|
    if (Temp != NULL) {
 | 
						|
      ItemValue = ShellStrToUintn (Temp);
 | 
						|
 | 
						|
      switch (ItemValue) {
 | 
						|
      case 1:
 | 
						|
        Width = EfiPciWidthUint8;
 | 
						|
        Size  = 1;
 | 
						|
        break;
 | 
						|
 | 
						|
      case 2:
 | 
						|
        Width = EfiPciWidthUint16;
 | 
						|
        Size  = 2;
 | 
						|
        break;
 | 
						|
 | 
						|
      case 4:
 | 
						|
        Width = EfiPciWidthUint32;
 | 
						|
        Size  = 4;
 | 
						|
        break;
 | 
						|
 | 
						|
      case 8:
 | 
						|
        Width = EfiPciWidthUint64;
 | 
						|
        Size  = 8;
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"-w");
 | 
						|
        ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    Temp = ShellCommandLineGetRawValue(Package, 1);
 | 
						|
    if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, (UINT64*)&Address, TRUE, FALSE))) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    Temp = ShellCommandLineGetRawValue(Package, 2);
 | 
						|
    if (Temp != NULL) {
 | 
						|
      if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, &Value, TRUE, FALSE))) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
 | 
						|
        ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
      switch (Size) {
 | 
						|
      case 1:
 | 
						|
        if (Value > 0xFF) {
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
      case 2:
 | 
						|
        if (Value > 0xFFFF) {
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
      case 4:
 | 
						|
        if (Value > 0xFFFFFFFF) {
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      if (ShellStatus != SHELL_SUCCESS) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
 | 
						|
        ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if ((Address & (Size - 1)) != 0) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_NOT_ALIGNED), gShellDebug1HiiHandle, Address);
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // locate DeviceIO protocol interface
 | 
						|
    //
 | 
						|
    if (AccessType != EfiMemory) {
 | 
						|
      Status = gBS->LocateHandleBuffer (
 | 
						|
                 ByProtocol,
 | 
						|
                 &gEfiPciRootBridgeIoProtocolGuid,
 | 
						|
                 NULL,
 | 
						|
                 &BufferSize,
 | 
						|
                 &HandleBuffer
 | 
						|
                );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle);
 | 
						|
        ShellStatus = SHELL_NOT_FOUND;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // In the case of PCI or PCIE
 | 
						|
      // Get segment number and mask the segment bits in Address
 | 
						|
      //
 | 
						|
      if (AccessType == EfiPciEConfig) {
 | 
						|
        SegmentNumber = (UINT32) RShiftU64 (Address, 36) & 0xff;
 | 
						|
        Address      &= 0xfffffffffULL;
 | 
						|
      } else {
 | 
						|
        if (AccessType == EfiPciConfig) {
 | 
						|
          SegmentNumber = (UINT32) RShiftU64 (Address, 32) & 0xff;
 | 
						|
          Address      &= 0xffffffff;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment number
 | 
						|
      //
 | 
						|
      for (Index = 0; Index < BufferSize; Index++) {
 | 
						|
        Status = gBS->HandleProtocol (
 | 
						|
                       HandleBuffer[Index],
 | 
						|
                       &gEfiPciRootBridgeIoProtocolGuid,
 | 
						|
                       (VOID *) &IoDev
 | 
						|
                      );
 | 
						|
        if (EFI_ERROR (Status)) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
        if (IoDev->SegmentNumber != SegmentNumber) {
 | 
						|
          IoDev = NULL;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (IoDev == NULL) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_SEGMENT_NOT_FOUND), gShellDebug1HiiHandle, SegmentNumber);
 | 
						|
        ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (AccessType == EfiIo && Address + Size > 0x10000) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE), gShellDebug1HiiHandle);
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    if (AccessType == EfiPciEConfig) {
 | 
						|
      GetPciEAddressFromInputAddress (Address, &PciEAddress);
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Set value
 | 
						|
    //
 | 
						|
    if (ShellCommandLineGetRawValue(Package, 2) != NULL) {
 | 
						|
      if (AccessType == EFIMemoryMappedIo) {
 | 
						|
        IoDev->Mem.Write (IoDev, Width, Address, 1, &Value);
 | 
						|
      } else if (AccessType == EfiIo) {
 | 
						|
        IoDev->Io.Write (IoDev, Width, Address, 1, &Value);
 | 
						|
      } else if (AccessType == EfiPciConfig) {
 | 
						|
        IoDev->Pci.Write (IoDev, Width, Address, 1, &Value);
 | 
						|
      } else if (AccessType == EfiPciEConfig) {
 | 
						|
        IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Value);
 | 
						|
      } else {
 | 
						|
        WriteMem (Width, Address, 1, &Value);
 | 
						|
      }
 | 
						|
 | 
						|
      ASSERT(ShellStatus == SHELL_SUCCESS);
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    //
 | 
						|
    // non-interactive mode
 | 
						|
    //
 | 
						|
    if (!Interactive) {
 | 
						|
      Buffer = 0;
 | 
						|
      if (AccessType == EFIMemoryMappedIo) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
 | 
						|
        IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
 | 
						|
      } else if (AccessType == EfiIo) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
 | 
						|
        IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
 | 
						|
      } else if (AccessType == EfiPciConfig) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
 | 
						|
        IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
 | 
						|
      } else if (AccessType == EfiPciEConfig) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
 | 
						|
        IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
 | 
						|
        ReadMem (Width, Address, 1, &Buffer);
 | 
						|
      }
 | 
						|
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
 | 
						|
      if (Size == 1) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
 | 
						|
      } else if (Size == 2) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);
 | 
						|
      } else if (Size == 4) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);
 | 
						|
      } else if (Size == 8) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);
 | 
						|
      }
 | 
						|
 | 
						|
      ShellPrintEx(-1, -1, L"\r\n");
 | 
						|
 | 
						|
      ASSERT(ShellStatus == SHELL_SUCCESS);
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // interactive mode
 | 
						|
    //
 | 
						|
    Complete = FALSE;
 | 
						|
    do {
 | 
						|
      if (AccessType == EfiIo && Address + Size > 0x10000) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE2), gShellDebug1HiiHandle);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      Buffer = 0;
 | 
						|
      if (AccessType == EFIMemoryMappedIo) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
 | 
						|
        IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
 | 
						|
      } else if (AccessType == EfiIo) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
 | 
						|
        IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
 | 
						|
      } else if (AccessType == EfiPciConfig) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
 | 
						|
        IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
 | 
						|
      } else if (AccessType == EfiPciEConfig) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
 | 
						|
        IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
 | 
						|
        ReadMem (Width, Address, 1, &Buffer);
 | 
						|
      }
 | 
						|
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
 | 
						|
 | 
						|
      if (Size == 1) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
 | 
						|
      } else if (Size == 2) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);
 | 
						|
      } else if (Size == 4) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);
 | 
						|
      } else if (Size == 8) {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);
 | 
						|
      }
 | 
						|
      ShellPrintEx(-1, -1, L" > ");
 | 
						|
      //
 | 
						|
      // wait user input to modify
 | 
						|
      //
 | 
						|
      if (InputStr != NULL) {
 | 
						|
        FreePool(InputStr);
 | 
						|
        InputStr = NULL;
 | 
						|
      }
 | 
						|
      ShellPromptForResponse(ShellPromptResponseTypeFreeform, NULL, (VOID**)&InputStr);
 | 
						|
 | 
						|
      //
 | 
						|
      // skip space characters
 | 
						|
      //
 | 
						|
      for (Index = 0; InputStr != NULL && InputStr[Index] == ' '; Index++);
 | 
						|
 | 
						|
      //
 | 
						|
      // parse input string
 | 
						|
      //
 | 
						|
      if (InputStr != NULL && (InputStr[Index] == '.' || InputStr[Index] == 'q' || InputStr[Index] == 'Q')) {
 | 
						|
        Complete = TRUE;
 | 
						|
      } else if (InputStr == NULL || InputStr[Index] == CHAR_NULL) {
 | 
						|
        //
 | 
						|
        // Continue to next address
 | 
						|
        //
 | 
						|
      } else if (GetHex (InputStr + Index, &Buffer) && Buffer <= MaxNum[Width]) {
 | 
						|
        if (AccessType == EFIMemoryMappedIo) {
 | 
						|
          IoDev->Mem.Write (IoDev, Width, Address, 1, &Buffer);
 | 
						|
        } else if (AccessType == EfiIo) {
 | 
						|
          IoDev->Io.Write (IoDev, Width, Address, 1, &Buffer);
 | 
						|
        } else if (AccessType == EfiPciConfig) {
 | 
						|
          IoDev->Pci.Write (IoDev, Width, Address, 1, &Buffer);
 | 
						|
        } else if (AccessType == EfiPciEConfig) {
 | 
						|
          IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Buffer);
 | 
						|
        } else {
 | 
						|
          WriteMem (Width, Address, 1, &Buffer);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle);
 | 
						|
        continue;
 | 
						|
  //      PrintToken (STRING_TOKEN (STR_IOMOD_ERROR), HiiHandle);
 | 
						|
      }
 | 
						|
 | 
						|
      Address += Size;
 | 
						|
      if (AccessType == EfiPciEConfig) {
 | 
						|
        GetPciEAddressFromInputAddress (Address, &PciEAddress);
 | 
						|
      }
 | 
						|
      ShellPrintEx(-1, -1, L"\r\n");
 | 
						|
  //    Print (L"\n");
 | 
						|
    } while (!Complete);
 | 
						|
  }
 | 
						|
  ASSERT(ShellStatus == SHELL_SUCCESS);
 | 
						|
Done:
 | 
						|
 | 
						|
  if (InputStr != NULL) {
 | 
						|
    FreePool(InputStr);
 | 
						|
  }
 | 
						|
  if (HandleBuffer != NULL) {
 | 
						|
    FreePool (HandleBuffer);
 | 
						|
  }
 | 
						|
  if (Package != NULL) {
 | 
						|
    ShellCommandLineFreeVarList (Package);
 | 
						|
  }
 | 
						|
  return ShellStatus;
 | 
						|
}
 |