/** @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;
    }

    if ((AccessType == ShellMmIo) && (Address + Size > MAX_UINT16 + 1)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_IO_ADDRESS_RANGE), gShellDebug1HiiHandle, L"mm");
      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 {
      if ((AccessType == ShellMmIo) && (Address + Size > MAX_UINT16 + 1)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE2), gShellDebug1HiiHandle, L"mm");
        break;
      }

      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;
}
