summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c')
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c1344
1 files changed, 672 insertions, 672 deletions
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
index b75e2f4770..152a7bcdcc 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
@@ -1,672 +1,672 @@
-/** @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>
-#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;
-}
+/** @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>
+#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;
+}