/** @file
  Main file for Mm shell Debug1 function.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellDebug1CommandsLib.h"
#include <Library/ShellLib.h>
#include <Library/IoLib.h>
#include <Protocol/PciRootBridgeIo.h>

typedef enum {
  ShellMmMemory,
  ShellMmMemoryMappedIo,
  ShellMmIo,
  ShellMmPci,
  ShellMmPciExpress
} SHELL_MM_ACCESS_TYPE;

CONST UINT16  mShellMmAccessTypeStr[] = {
  STRING_TOKEN (STR_MM_MEM),
  STRING_TOKEN (STR_MM_MMIO),
  STRING_TOKEN (STR_MM_IO),
  STRING_TOKEN (STR_MM_PCI),
  STRING_TOKEN (STR_MM_PCIE)
};

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   }
};

CONST UINT64                                 mShellMmMaxNumber[] = {
  0, MAX_UINT8, MAX_UINT16, 0, MAX_UINT32, 0, 0, 0, MAX_UINT64
};
CONST EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  mShellMmRootBridgeIoWidth[] = {
  0, EfiPciWidthUint8, EfiPciWidthUint16, 0, EfiPciWidthUint32, 0, 0, 0, EfiPciWidthUint64
};
CONST EFI_CPU_IO_PROTOCOL_WIDTH              mShellMmCpuIoWidth[] = {
  0, EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, 0, EfiCpuIoWidthUint32, 0, 0, 0, EfiCpuIoWidthUint64
};

/**
  Extract the PCI segment, bus, device, function, register from
  from a PCI or PCIE format of address..

  @param[in]  PciFormat      Whether the address is of PCI format of PCIE format.
  @param[in]  Address        PCI or PCIE address.
  @param[out] Segment        PCI segment number.
  @param[out] Bus            PCI bus number.
  @param[out] Device         PCI device number.
  @param[out] Function       PCI function number.
  @param[out] Register       PCI register offset.
**/
VOID
ShellMmDecodePciAddress (
  IN BOOLEAN  PciFormat,
  IN UINT64   Address,
  OUT UINT32  *Segment,
  OUT UINT8   *Bus,
  OUT UINT8   *Device    OPTIONAL,
  OUT UINT8   *Function  OPTIONAL,
  OUT UINT32  *Register  OPTIONAL
  )
{
  if (PciFormat) {
    //
    // PCI Configuration Space.The address will have the format ssssbbddffrr,
    // where ssss = Segment, bb = Bus, dd = Device, ff = Function and rr = Register.
    //
    *Segment = (UINT32)(RShiftU64 (Address, 32) & 0xFFFF);
    *Bus     = (UINT8)(((UINT32)Address) >> 24);

    if (Device != NULL) {
      *Device = (UINT8)(((UINT32)Address) >> 16);
    }

    if (Function != NULL) {
      *Function = (UINT8)(((UINT32)Address) >> 8);
    }

    if (Register != NULL) {
      *Register = (UINT8)Address;
    }
  } else {
    //
    // PCI Express Configuration Space.The address will have the format ssssssbbddffrrr,
    // where ssss = Segment, bb = Bus, dd = Device, ff = Function and rrr = Register.
    //
    *Segment = (UINT32)(RShiftU64 (Address, 36) & 0xFFFF);
    *Bus     = (UINT8)RShiftU64 (Address, 28);
    if (Device != NULL) {
      *Device = (UINT8)(((UINT32)Address) >> 20);
    }

    if (Function != NULL) {
      *Function = (UINT8)(((UINT32)Address) >> 12);
    }

    if (Register != NULL) {
      *Register = (UINT32)(Address & 0xFFF);
    }
  }
}

/**
  Read or write some data from or into the Address.

  @param[in]      AccessType      Access type.
  @param[in]      PciRootBridgeIo PciRootBridgeIo instance.
  @param[in]      CpuIo           CpuIo instance.
  @param[in]      Read            TRUE for read, FALSE for write.
  @param[in]      Addresss        The memory location to access.
  @param[in]      Size            The size of Buffer in Width sized units.
  @param[in, out] Buffer          The buffer to read into or write from.
**/
VOID
ShellMmAccess (
  IN     SHELL_MM_ACCESS_TYPE             AccessType,
  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
  IN     EFI_CPU_IO2_PROTOCOL             *CpuIo,
  IN     BOOLEAN                          Read,
  IN     UINT64                           Address,
  IN     UINTN                            Size,
  IN OUT VOID                             *Buffer
  )
{
  EFI_STATUS                              Status;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM  RootBridgeIoMem;
  EFI_CPU_IO_PROTOCOL_IO_MEM              CpuIoMem;
  UINT32                                  Segment;
  UINT8                                   Bus;
  UINT8                                   Device;
  UINT8                                   Function;
  UINT32                                  Register;

  if (AccessType == ShellMmMemory) {
    if (Read) {
      CopyMem (Buffer, (VOID *)(UINTN)Address, Size);
    } else {
      CopyMem ((VOID *)(UINTN)Address, Buffer, Size);
    }
  } else {
    RootBridgeIoMem = NULL;
    CpuIoMem        = NULL;
    switch (AccessType) {
      case ShellMmPci:
      case ShellMmPciExpress:
        ASSERT (PciRootBridgeIo != NULL);
        ShellMmDecodePciAddress ((BOOLEAN)(AccessType == ShellMmPci), Address, &Segment, &Bus, &Device, &Function, &Register);
        if (Read) {
          Status = PciRootBridgeIo->Pci.Read (
                                          PciRootBridgeIo,
                                          mShellMmRootBridgeIoWidth[Size],
                                          EFI_PCI_ADDRESS (Bus, Device, Function, Register),
                                          1,
                                          Buffer
                                          );
        } else {
          Status = PciRootBridgeIo->Pci.Write (
                                          PciRootBridgeIo,
                                          mShellMmRootBridgeIoWidth[Size],
                                          EFI_PCI_ADDRESS (Bus, Device, Function, Register),
                                          1,
                                          Buffer
                                          );
        }

        ASSERT_EFI_ERROR (Status);
        return;

      case ShellMmMemoryMappedIo:
        if (PciRootBridgeIo != NULL) {
          RootBridgeIoMem = Read ? PciRootBridgeIo->Mem.Read : PciRootBridgeIo->Mem.Write;
        }

        if (CpuIo != NULL) {
          CpuIoMem = Read ? CpuIo->Mem.Read : CpuIo->Mem.Write;
        }

        break;

      case ShellMmIo:
        if (PciRootBridgeIo != NULL) {
          RootBridgeIoMem = Read ? PciRootBridgeIo->Io.Read : PciRootBridgeIo->Io.Write;
        }

        if (CpuIo != NULL) {
          CpuIoMem = Read ? CpuIo->Io.Read : CpuIo->Io.Write;
        }

        break;
      default:
        ASSERT (FALSE);
        break;
    }

    Status = EFI_UNSUPPORTED;
    if (RootBridgeIoMem != NULL) {
      Status = RootBridgeIoMem (PciRootBridgeIo, mShellMmRootBridgeIoWidth[Size], Address, 1, Buffer);
    }

    if (EFI_ERROR (Status) && (CpuIoMem != NULL)) {
      Status = CpuIoMem (CpuIo, mShellMmCpuIoWidth[Size], Address, 1, Buffer);
    }

    if (EFI_ERROR (Status)) {
      if (AccessType == ShellMmIo) {
        switch (Size) {
          case 1:
            if (Read) {
              *(UINT8 *)Buffer = IoRead8 ((UINTN)Address);
            } else {
              IoWrite8 ((UINTN)Address, *(UINT8 *)Buffer);
            }

            break;
          case 2:
            if (Read) {
              *(UINT16 *)Buffer = IoRead16 ((UINTN)Address);
            } else {
              IoWrite16 ((UINTN)Address, *(UINT16 *)Buffer);
            }

            break;
          case 4:
            if (Read) {
              *(UINT32 *)Buffer = IoRead32 ((UINTN)Address);
            } else {
              IoWrite32 ((UINTN)Address, *(UINT32 *)Buffer);
            }

            break;
          case 8:
            if (Read) {
              *(UINT64 *)Buffer = IoRead64 ((UINTN)Address);
            } else {
              IoWrite64 ((UINTN)Address, *(UINT64 *)Buffer);
            }

            break;
          default:
            ASSERT (FALSE);
            break;
        }
      } else {
        switch (Size) {
          case 1:
            if (Read) {
              *(UINT8 *)Buffer = MmioRead8 ((UINTN)Address);
            } else {
              MmioWrite8 ((UINTN)Address, *(UINT8 *)Buffer);
            }

            break;
          case 2:
            if (Read) {
              *(UINT16 *)Buffer = MmioRead16 ((UINTN)Address);
            } else {
              MmioWrite16 ((UINTN)Address, *(UINT16 *)Buffer);
            }

            break;
          case 4:
            if (Read) {
              *(UINT32 *)Buffer = MmioRead32 ((UINTN)Address);
            } else {
              MmioWrite32 ((UINTN)Address, *(UINT32 *)Buffer);
            }

            break;
          case 8:
            if (Read) {
              *(UINT64 *)Buffer = MmioRead64 ((UINTN)Address);
            } else {
              MmioWrite64 ((UINTN)Address, *(UINT64 *)Buffer);
            }

            break;
          default:
            ASSERT (FALSE);
            break;
        }
      }
    }
  }
}

/**
  Find the CpuIo instance and PciRootBridgeIo instance in the platform.
  If there are multiple PciRootBridgeIo instances, the instance which manages
  the Address is returned.

  @param[in]  AccessType      Access type.
  @param[in]  Address         Address to access.
  @param[out] CpuIo           Return the CpuIo instance.
  @param[out] PciRootBridgeIo Return the proper PciRootBridgeIo instance.

  @retval TRUE  There are PciRootBridgeIo instances in the platform.
  @retval FALSE There isn't PciRootBridgeIo instance in the platform.
**/
BOOLEAN
ShellMmLocateIoProtocol (
  IN SHELL_MM_ACCESS_TYPE              AccessType,
  IN UINT64                            Address,
  OUT EFI_CPU_IO2_PROTOCOL             **CpuIo,
  OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  **PciRootBridgeIo
  )
{
  EFI_STATUS                         Status;
  UINTN                              Index;
  UINTN                              HandleCount;
  EFI_HANDLE                         *HandleBuffer;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Io;
  UINT32                             Segment;
  UINT8                              Bus;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Descriptors;

  Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)CpuIo);
  if (EFI_ERROR (Status)) {
    *CpuIo = NULL;
  }

  *PciRootBridgeIo = NULL;
  HandleBuffer     = NULL;
  Status           = gBS->LocateHandleBuffer (
                            ByProtocol,
                            &gEfiPciRootBridgeIoProtocolGuid,
                            NULL,
                            &HandleCount,
                            &HandleBuffer
                            );
  if (EFI_ERROR (Status) || (HandleCount == 0) || (HandleBuffer == NULL)) {
    return FALSE;
  }

  Segment = 0;
  Bus     = 0;
  if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) {
    ShellMmDecodePciAddress ((BOOLEAN)(AccessType == ShellMmPci), Address, &Segment, &Bus, NULL, NULL, NULL);
  }

  //
  // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment & bus number
  //
  for (Index = 0; (Index < HandleCount) && (*PciRootBridgeIo == NULL); Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiPciRootBridgeIoProtocolGuid,
                    (VOID *)&Io
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }

    if ((((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) && (Io->SegmentNumber == Segment)) ||
        ((AccessType == ShellMmIo) || (AccessType == ShellMmMemoryMappedIo))
        )
    {
      Status = Io->Configuration (Io, (VOID **)&Descriptors);
      if (!EFI_ERROR (Status)) {
        while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {
          //
          // Compare the segment and bus range for PCI/PCIE access
          //
          if ((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) &&
              ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) &&
              ((Bus >= Descriptors->AddrRangeMin) && (Bus <= Descriptors->AddrRangeMax))
              )
          {
            *PciRootBridgeIo = Io;
            break;

            //
            // Compare the address range for MMIO/IO access
            //
          } else if ((((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) && (AccessType == ShellMmIo)) ||
                      ((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) && (AccessType == ShellMmMemoryMappedIo))
                      ) && ((Address >= Descriptors->AddrRangeMin) && (Address <= Descriptors->AddrRangeMax))
                     )
          {
            *PciRootBridgeIo = Io;
            break;
          }

          Descriptors++;
        }
      }
    }
  }

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
  }

  return TRUE;
}

/**
  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  *PciRootBridgeIo;
  EFI_CPU_IO2_PROTOCOL             *CpuIo;
  UINT64                           Address;
  UINT64                           Value;
  SHELL_MM_ACCESS_TYPE             AccessType;
  UINT64                           Buffer;
  UINTN                            Index;
  UINTN                            Size;
  BOOLEAN                          Complete;
  CHAR16                           *InputStr;
  BOOLEAN                          Interactive;
  LIST_ENTRY                       *Package;
  CHAR16                           *ProblemParam;
  SHELL_STATUS                     ShellStatus;
  CONST CHAR16                     *Temp;
  BOOLEAN                          HasPciRootBridgeIo;

  Value       = 0;
  Address     = 0;
  ShellStatus = SHELL_SUCCESS;
  InputStr    = NULL;
  Size        = 1;
  AccessType  = ShellMmMemory;

  //
  // Parse arguments
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"mm", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  if (ShellCommandLineGetCount (Package) < 2) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"mm");
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto Done;
  } else if (ShellCommandLineGetCount (Package) > 3) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto Done;
  } else if (ShellCommandLineGetFlag (Package, L"-w") && (ShellCommandLineGetValue (Package, L"-w") == NULL)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"mm", L"-w");
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto Done;
  } else {
    if (ShellCommandLineGetFlag (Package, L"-mmio")) {
      AccessType = ShellMmMemoryMappedIo;
      if (  ShellCommandLineGetFlag (Package, L"-mem")
         || ShellCommandLineGetFlag (Package, L"-io")
         || ShellCommandLineGetFlag (Package, L"-pci")
         || ShellCommandLineGetFlag (Package, L"-pcie")
            )
      {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    } else if (ShellCommandLineGetFlag (Package, L"-mem")) {
      AccessType = ShellMmMemory;
      if (  ShellCommandLineGetFlag (Package, L"-io")
         || ShellCommandLineGetFlag (Package, L"-pci")
         || ShellCommandLineGetFlag (Package, L"-pcie")
            )
      {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    } else if (ShellCommandLineGetFlag (Package, L"-io")) {
      AccessType = ShellMmIo;
      if (  ShellCommandLineGetFlag (Package, L"-pci")
         || ShellCommandLineGetFlag (Package, L"-pcie")
            )
      {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    } else if (ShellCommandLineGetFlag (Package, L"-pci")) {
      AccessType = ShellMmPci;
      if (ShellCommandLineGetFlag (Package, L"-pcie")
          )
      {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    } else if (ShellCommandLineGetFlag (Package, L"-pcie")) {
      AccessType = ShellMmPciExpress;
    }
  }

  //
  // Non interactive for a script file or for the specific parameter
  //
  Interactive = TRUE;
  if (gEfiShellProtocol->BatchIsActive () || ShellCommandLineGetFlag (Package, L"-n")) {
    Interactive = FALSE;
  }

  Temp = ShellCommandLineGetValue (Package, L"-w");
  if (Temp != NULL) {
    Size = ShellStrToUintn (Temp);
  }

  if ((Size != 1) && (Size != 2) && (Size != 4) && (Size != 8)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"mm", Temp, L"-w");
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto Done;
  }

  Temp = ShellCommandLineGetRawValue (Package, 1);
  if (Temp == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"mm", L"NULL");
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto Done;
  }

  Status = ShellConvertStringToUint64 (Temp, &Address, TRUE, FALSE);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto Done;
  }

  if ((Address & (Size - 1)) != 0) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MM_NOT_ALIGNED), gShellDebug1HiiHandle, L"mm", Address);
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto Done;
  }

  //
  // locate IO protocol interface
  //
  HasPciRootBridgeIo = ShellMmLocateIoProtocol (AccessType, Address, &CpuIo, &PciRootBridgeIo);
  if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) {
    if (!HasPciRootBridgeIo) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"mm");
      ShellStatus = SHELL_NOT_FOUND;
      goto Done;
    }

    if (PciRootBridgeIo == NULL) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MM_PCIE_ADDRESS_RANGE), gShellDebug1HiiHandle, L"mm", Address);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }
  }

  //
  // Mode 1: Directly set a value
  //
  Temp = ShellCommandLineGetRawValue (Package, 2);
  if (Temp != NULL) {
    Status = ShellConvertStringToUint64 (Temp, &Value, TRUE, FALSE);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (Value > mShellMmMaxNumber[Size]) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, FALSE, Address, Size, &Value);
    goto Done;
  }

  //
  // Mode 2: Directly show a value
  //
  if (!Interactive) {
    if (!gEfiShellProtocol->BatchIsActive ()) {
      ShellPrintHiiDefaultEx (mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle);
    }

    ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, TRUE, Address, Size, &Buffer);

    if (!gEfiShellProtocol->BatchIsActive ()) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
    }

    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);
    ShellPrintDefaultEx (L"\r\n");
    goto Done;
  }

  //
  // Mode 3: Show or set values in interactive mode
  //
  Complete = FALSE;
  do {
    ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, TRUE, Address, Size, &Buffer);
    ShellPrintHiiDefaultEx (mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle);
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);
    ShellPrintDefaultEx (L" > ");
    //
    // wait user input to modify
    //
    if (InputStr != NULL) {
      FreePool (InputStr);
      InputStr = NULL;
    }

    ShellPromptForResponse (ShellPromptResponseTypeFreeform, NULL, (VOID **)&InputStr);

    if (InputStr != NULL) {
      //
      // skip space characters
      //
      for (Index = 0; InputStr[Index] == ' '; Index++) {
      }

      if (InputStr[Index] != CHAR_NULL) {
        if ((InputStr[Index] == '.') || (InputStr[Index] == 'q') || (InputStr[Index] == 'Q')) {
          Complete = TRUE;
        } else if (!EFI_ERROR (ShellConvertStringToUint64 (InputStr + Index, &Buffer, TRUE, TRUE)) &&
                   (Buffer <= mShellMmMaxNumber[Size])
                   )
        {
          ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, FALSE, Address, Size, &Buffer);
        } else {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle, L"mm");
          continue;
        }
      }
    }

    Address += Size;
    ShellPrintDefaultEx (L"\r\n");
  } while (!Complete);

  ASSERT (ShellStatus == SHELL_SUCCESS);

Done:
  if (InputStr != NULL) {
    FreePool (InputStr);
  }

  if (Package != NULL) {
    ShellCommandLineFreeVarList (Package);
  }

  return ShellStatus;
}
