/** @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>
  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 <Library/IoLib.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/DeviceIo.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) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"mm", 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, L"mm");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } else if (ShellCommandLineGetCount (Package) > 3) {
      ShellPrintHiiEx (-1, -1, NULL, 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) {
      ShellPrintHiiEx (-1, -1, NULL, 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")
            ) {
          ShellPrintHiiEx (-1, -1, NULL, 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")
            ) {
          ShellPrintHiiEx (-1, -1, NULL, 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")
            ) {
          ShellPrintHiiEx (-1, -1, NULL, 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")
            ) {
          ShellPrintHiiEx (-1, -1, NULL, 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)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"mm", Temp, L"-w");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    Temp = ShellCommandLineGetRawValue (Package, 1);
    Status = ShellConvertStringToUint64 (Temp, &Address, TRUE, FALSE);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if ((Address & (Size - 1)) != 0) {
      ShellPrintHiiEx (-1, -1, NULL, 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) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"mm");
        ShellStatus = SHELL_NOT_FOUND;
        goto Done;
      }
      if (PciRootBridgeIo == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, 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)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }

      if (Value > mShellMmMaxNumber[Size]) {
        ShellPrintHiiEx (-1, -1, NULL, 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 ()) {
        ShellPrintHiiEx (-1, -1, NULL, mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle);
      }
      ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, TRUE, Address, Size, &Buffer);

      if (!gEfiShellProtocol->BatchIsActive ()) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
      }
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);
      ShellPrintEx (-1, -1, 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);
      ShellPrintHiiEx (-1, -1, NULL, mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle);
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);
      ShellPrintEx (-1, -1, 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 {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle, L"mm");
            continue;
          }
        }
      }

      Address += Size;
      ShellPrintEx (-1, -1, L"\r\n");
    } while (!Complete);
  }
  ASSERT (ShellStatus == SHELL_SUCCESS);

Done:
  if (InputStr != NULL) {
    FreePool (InputStr);
  }
  if (Package != NULL) {
    ShellCommandLineFreeVarList (Package);
  }
  return ShellStatus;
}
