/** @file
  Main file for Mm shell Debug1 function.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2005 - 2015, 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 SHELL_MM_PCI or SHELL_MM_PCIE format of address..

  @param[in]  PciFormat      Whether the address is of PCI format of PCIE format.
  @param[in]  Address        SHELL_MM_PCI or SHELL_MM_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
EFIAPI
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 0x000000ssbbddffrr,
    // where ss = Segment, bb = Bus, dd = Device, ff = Function and rr = Register.
    //
    *Segment = (UINT32) (RShiftU64 (Address, 32) & 0xFF);
    *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 0x0000000ssbbddffrrr,
    // where ss = Segment, bb = Bus, dd = Device, ff = Function and rrr = Register.
    //
    *Segment = (UINT32) (RShiftU64 (Address, 36) & 0xFF);
    *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;
}
