|
|
|
@ -2,7 +2,7 @@
|
|
|
|
|
Main file for Mm shell Debug1 function.
|
|
|
|
|
|
|
|
|
|
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
|
|
|
|
|
Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<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
|
|
|
|
@ -15,16 +15,25 @@
|
|
|
|
|
|
|
|
|
|
#include "UefiShellDebug1CommandsLib.h"
|
|
|
|
|
#include <Library/ShellLib.h>
|
|
|
|
|
#include <Library/IoLib.h>
|
|
|
|
|
#include <Protocol/PciRootBridgeIo.h>
|
|
|
|
|
#include <Protocol/DeviceIo.h>
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
|
EfiMemory,
|
|
|
|
|
EFIMemoryMappedIo,
|
|
|
|
|
EfiIo,
|
|
|
|
|
EfiPciConfig,
|
|
|
|
|
EfiPciEConfig
|
|
|
|
|
} EFI_ACCESS_TYPE;
|
|
|
|
|
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},
|
|
|
|
@ -37,161 +46,341 @@ STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
|
|
|
|
|
{NULL, TypeMax}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
STATIC CONST UINT64 MaxNum[9] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffULL };
|
|
|
|
|
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
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Read some data into a buffer from memory.
|
|
|
|
|
Extract the PCI segment, bus, device, function, register from
|
|
|
|
|
from a SHELL_MM_PCI or SHELL_MM_PCIE format of address..
|
|
|
|
|
|
|
|
|
|
@param[in] Width The width of each read.
|
|
|
|
|
@param[in] Addresss The memory location to start reading at.
|
|
|
|
|
@param[in] Size The size of Buffer in Width sized units.
|
|
|
|
|
@param[out] Buffer The buffer to read into.
|
|
|
|
|
@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
|
|
|
|
|
ReadMem (
|
|
|
|
|
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
|
|
|
|
ShellMmDecodePciAddress (
|
|
|
|
|
IN BOOLEAN PciFormat,
|
|
|
|
|
IN UINT64 Address,
|
|
|
|
|
IN UINTN Size,
|
|
|
|
|
OUT VOID *Buffer
|
|
|
|
|
OUT UINT32 *Segment,
|
|
|
|
|
OUT UINT8 *Bus,
|
|
|
|
|
OUT UINT8 *Device, OPTIONAL
|
|
|
|
|
OUT UINT8 *Function, OPTIONAL
|
|
|
|
|
OUT UINT32 *Register OPTIONAL
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
if (PciFormat) {
|
|
|
|
|
//
|
|
|
|
|
// This function is defective. This ASSERT prevents the defect from affecting anything.
|
|
|
|
|
// PCI Configuration Space.The address will have the format 0x000000ssbbddffrr,
|
|
|
|
|
// where ss = Segment, bb = Bus, dd = Device, ff = Function and rr = Register.
|
|
|
|
|
//
|
|
|
|
|
ASSERT(Size == 1);
|
|
|
|
|
do {
|
|
|
|
|
if (Width == EfiPciWidthUint8) {
|
|
|
|
|
*(UINT8 *) Buffer = *(UINT8 *) (UINTN) Address;
|
|
|
|
|
Address -= 1;
|
|
|
|
|
} else if (Width == EfiPciWidthUint16) {
|
|
|
|
|
*(UINT16 *) Buffer = *(UINT16 *) (UINTN) Address;
|
|
|
|
|
Address -= 2;
|
|
|
|
|
} else if (Width == EfiPciWidthUint32) {
|
|
|
|
|
*(UINT32 *) Buffer = *(UINT32 *) (UINTN) Address;
|
|
|
|
|
Address -= 4;
|
|
|
|
|
} else if (Width == EfiPciWidthUint64) {
|
|
|
|
|
*(UINT64 *) Buffer = *(UINT64 *) (UINTN) Address;
|
|
|
|
|
Address -= 8;
|
|
|
|
|
*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 {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_READ_ERROR), gShellDebug1HiiHandle, L"mm");
|
|
|
|
|
//
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
Size--;
|
|
|
|
|
} while (Size > 0);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Write some data to memory.
|
|
|
|
|
|
|
|
|
|
@param[in] Width The width of each write.
|
|
|
|
|
@param[in] Addresss The memory location to start writing at.
|
|
|
|
|
@param[in] Size The size of Buffer in Width sized units.
|
|
|
|
|
@param[in] Buffer The buffer to write from.
|
|
|
|
|
**/
|
|
|
|
|
VOID
|
|
|
|
|
EFIAPI
|
|
|
|
|
WriteMem (
|
|
|
|
|
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
|
|
|
|
IN UINT64 Address,
|
|
|
|
|
IN UINTN Size,
|
|
|
|
|
IN VOID *Buffer
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
// This function is defective. This ASSERT prevents the defect from affecting anything.
|
|
|
|
|
//
|
|
|
|
|
ASSERT(Size == 1);
|
|
|
|
|
do {
|
|
|
|
|
if (Width == EfiPciWidthUint8) {
|
|
|
|
|
*(UINT8 *) (UINTN) Address = *(UINT8 *) Buffer;
|
|
|
|
|
Address += 1;
|
|
|
|
|
} else if (Width == EfiPciWidthUint16) {
|
|
|
|
|
*(UINT16 *) (UINTN) Address = *(UINT16 *) Buffer;
|
|
|
|
|
Address += 2;
|
|
|
|
|
} else if (Width == EfiPciWidthUint32) {
|
|
|
|
|
*(UINT32 *) (UINTN) Address = *(UINT32 *) Buffer;
|
|
|
|
|
Address += 4;
|
|
|
|
|
} else if (Width == EfiPciWidthUint64) {
|
|
|
|
|
*(UINT64 *) (UINTN) Address = *(UINT64 *) Buffer;
|
|
|
|
|
Address += 8;
|
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
|
if (AccessType == ShellMmIo) {
|
|
|
|
|
switch (Size) {
|
|
|
|
|
case 1:
|
|
|
|
|
if (Read) {
|
|
|
|
|
*(UINT8 *) Buffer = IoRead8 ((UINTN) Address);
|
|
|
|
|
} else {
|
|
|
|
|
ASSERT (FALSE);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
Size--;
|
|
|
|
|
} while (Size > 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Convert a string to it's hex data.
|
|
|
|
|
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] str The pointer to the string of hex data.
|
|
|
|
|
@param[out] data The pointer to the buffer to fill. Valid upon a TRUE return.
|
|
|
|
|
@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 The conversion was successful.
|
|
|
|
|
@retval FALSE The conversion failed.
|
|
|
|
|
@retval TRUE There are PciRootBridgeIo instances in the platform.
|
|
|
|
|
@retval FALSE There isn't PciRootBridgeIo instance in the platform.
|
|
|
|
|
**/
|
|
|
|
|
BOOLEAN
|
|
|
|
|
EFIAPI
|
|
|
|
|
GetHex (
|
|
|
|
|
IN UINT16 *str,
|
|
|
|
|
OUT UINT64 *data
|
|
|
|
|
ShellMmLocateIoProtocol (
|
|
|
|
|
IN SHELL_MM_ACCESS_TYPE AccessType,
|
|
|
|
|
IN UINT64 Address,
|
|
|
|
|
OUT EFI_CPU_IO2_PROTOCOL **CpuIo,
|
|
|
|
|
OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **PciRootBridgeIo
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
UINTN TempUint;
|
|
|
|
|
CHAR16 TempChar;
|
|
|
|
|
BOOLEAN Find;
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
Find = FALSE;
|
|
|
|
|
//
|
|
|
|
|
// convert hex digits
|
|
|
|
|
//
|
|
|
|
|
TempUint = 0;
|
|
|
|
|
TempChar = *(str++);
|
|
|
|
|
while (TempChar != CHAR_NULL) {
|
|
|
|
|
if (TempChar >= 'a' && TempChar <= 'f') {
|
|
|
|
|
TempChar -= 'a' - 'A';
|
|
|
|
|
Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **) CpuIo);
|
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
|
*CpuIo = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TempChar == ' ') {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((TempChar >= '0' && TempChar <= '9') || (TempChar >= 'A' && TempChar <= 'F')) {
|
|
|
|
|
TempUint = (TempUint << 4) | (TempChar - (TempChar >= 'A' ? 'A' - 10 : '0'));
|
|
|
|
|
|
|
|
|
|
Find = TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
*PciRootBridgeIo = NULL;
|
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
|
|
|
ByProtocol,
|
|
|
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
|
|
|
NULL,
|
|
|
|
|
&HandleCount,
|
|
|
|
|
&HandleBuffer
|
|
|
|
|
);
|
|
|
|
|
if (EFI_ERROR (Status) || (HandleCount == 0)) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TempChar = *(str++);
|
|
|
|
|
if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) {
|
|
|
|
|
ShellMmDecodePciAddress ((BOOLEAN) (AccessType == ShellMmPci), Address, &Segment, &Bus, NULL, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*data = TempUint;
|
|
|
|
|
return Find;
|
|
|
|
|
//
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Get the PCI-E Address from a PCI address format 0x0000ssbbddffrrr
|
|
|
|
|
where ss is SEGMENT, bb is BUS, dd is DEVICE, ff is FUNCTION
|
|
|
|
|
and rrr is REGISTER (extension format for PCI-E).
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
@param[in] InputAddress PCI address format on input.
|
|
|
|
|
@param[out]PciEAddress PCI-E address extention format.
|
|
|
|
|
**/
|
|
|
|
|
VOID
|
|
|
|
|
EFIAPI
|
|
|
|
|
GetPciEAddressFromInputAddress (
|
|
|
|
|
IN UINT64 InputAddress,
|
|
|
|
|
OUT UINT64 *PciEAddress
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
*PciEAddress = RShiftU64(InputAddress & ~(UINT64) 0xFFF, 4);
|
|
|
|
|
*PciEAddress += LShiftU64((UINT16) InputAddress & 0x0FFF, 32);
|
|
|
|
|
//
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -208,48 +397,33 @@ ShellCommandRunMm (
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev;
|
|
|
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
|
|
|
|
|
EFI_CPU_IO2_PROTOCOL *CpuIo;
|
|
|
|
|
UINT64 Address;
|
|
|
|
|
UINT64 PciEAddress;
|
|
|
|
|
UINT64 Value;
|
|
|
|
|
UINT32 SegmentNumber;
|
|
|
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width;
|
|
|
|
|
EFI_ACCESS_TYPE AccessType;
|
|
|
|
|
SHELL_MM_ACCESS_TYPE AccessType;
|
|
|
|
|
UINT64 Buffer;
|
|
|
|
|
UINTN Index;
|
|
|
|
|
UINTN Size;
|
|
|
|
|
// CHAR16 *ValueStr;
|
|
|
|
|
BOOLEAN Complete;
|
|
|
|
|
CHAR16 *InputStr;
|
|
|
|
|
BOOLEAN Interactive;
|
|
|
|
|
EFI_HANDLE *HandleBuffer;
|
|
|
|
|
UINTN BufferSize;
|
|
|
|
|
UINTN ItemValue;
|
|
|
|
|
LIST_ENTRY *Package;
|
|
|
|
|
CHAR16 *ProblemParam;
|
|
|
|
|
SHELL_STATUS ShellStatus;
|
|
|
|
|
CONST CHAR16 *Temp;
|
|
|
|
|
BOOLEAN HasPciRootBridgeIo;
|
|
|
|
|
|
|
|
|
|
Value = 0;
|
|
|
|
|
Address = 0;
|
|
|
|
|
PciEAddress = 0;
|
|
|
|
|
IoDev = NULL;
|
|
|
|
|
HandleBuffer = NULL;
|
|
|
|
|
BufferSize = 0;
|
|
|
|
|
SegmentNumber = 0;
|
|
|
|
|
ShellStatus = SHELL_SUCCESS;
|
|
|
|
|
InputStr = NULL;
|
|
|
|
|
Size = 1;
|
|
|
|
|
AccessType = ShellMmMemory;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Parse arguments
|
|
|
|
|
//
|
|
|
|
|
Width = EfiPciWidthUint8;
|
|
|
|
|
Size = 1;
|
|
|
|
|
AccessType = EfiMemory;
|
|
|
|
|
// ValueStr = NULL;
|
|
|
|
|
Interactive = TRUE;
|
|
|
|
|
Package = NULL;
|
|
|
|
|
|
|
|
|
|
Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
|
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
|
if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
|
|
|
|
@ -275,7 +449,7 @@ ShellCommandRunMm (
|
|
|
|
|
goto Done;
|
|
|
|
|
} else {
|
|
|
|
|
if (ShellCommandLineGetFlag (Package, L"-mmio")) {
|
|
|
|
|
AccessType = EFIMemoryMappedIo;
|
|
|
|
|
AccessType = ShellMmMemoryMappedIo;
|
|
|
|
|
if (ShellCommandLineGetFlag (Package, L"-mem")
|
|
|
|
|
|| ShellCommandLineGetFlag (Package, L"-io")
|
|
|
|
|
|| ShellCommandLineGetFlag (Package, L"-pci")
|
|
|
|
@ -286,7 +460,7 @@ ShellCommandRunMm (
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
} else if (ShellCommandLineGetFlag (Package, L"-mem")) {
|
|
|
|
|
AccessType = EfiMemory;
|
|
|
|
|
AccessType = ShellMmMemory;
|
|
|
|
|
if (ShellCommandLineGetFlag (Package, L"-io")
|
|
|
|
|
|| ShellCommandLineGetFlag (Package, L"-pci")
|
|
|
|
|
|| ShellCommandLineGetFlag (Package, L"-pcie")
|
|
|
|
@ -296,7 +470,7 @@ ShellCommandRunMm (
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
} else if (ShellCommandLineGetFlag (Package, L"-io")) {
|
|
|
|
|
AccessType = EfiIo;
|
|
|
|
|
AccessType = ShellMmIo;
|
|
|
|
|
if (ShellCommandLineGetFlag (Package, L"-pci")
|
|
|
|
|
|| ShellCommandLineGetFlag (Package, L"-pcie")
|
|
|
|
|
) {
|
|
|
|
@ -305,7 +479,7 @@ ShellCommandRunMm (
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
} else if (ShellCommandLineGetFlag (Package, L"-pci")) {
|
|
|
|
|
AccessType = EfiPciConfig;
|
|
|
|
|
AccessType = ShellMmPci;
|
|
|
|
|
if (ShellCommandLineGetFlag (Package, L"-pcie")
|
|
|
|
|
) {
|
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
|
|
|
|
@ -313,274 +487,118 @@ ShellCommandRunMm (
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
} else if (ShellCommandLineGetFlag (Package, L"-pcie")) {
|
|
|
|
|
AccessType = EfiPciEConfig;
|
|
|
|
|
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) {
|
|
|
|
|
ItemValue = ShellStrToUintn (Temp);
|
|
|
|
|
|
|
|
|
|
switch (ItemValue) {
|
|
|
|
|
case 1:
|
|
|
|
|
Width = EfiPciWidthUint8;
|
|
|
|
|
Size = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
Width = EfiPciWidthUint16;
|
|
|
|
|
Size = 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
|
Width = EfiPciWidthUint32;
|
|
|
|
|
Size = 4;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
|
Width = EfiPciWidthUint64;
|
|
|
|
|
Size = 8;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
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);
|
|
|
|
|
if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, (UINT64*)&Address, TRUE, FALSE))) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Temp = ShellCommandLineGetRawValue(Package, 2);
|
|
|
|
|
if (Temp != NULL) {
|
|
|
|
|
//
|
|
|
|
|
// Per spec if value is specified, then -n is assumed.
|
|
|
|
|
//
|
|
|
|
|
Interactive = FALSE;
|
|
|
|
|
|
|
|
|
|
if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, &Value, TRUE, FALSE))) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);
|
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
switch (Size) {
|
|
|
|
|
case 1:
|
|
|
|
|
if (Value > 0xFF) {
|
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
if (Value > 0xFFFF) {
|
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
|
if (Value > 0xFFFFFFFF) {
|
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ShellStatus != SHELL_SUCCESS) {
|
|
|
|
|
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 DeviceIO protocol interface
|
|
|
|
|
// locate IO protocol interface
|
|
|
|
|
//
|
|
|
|
|
if (AccessType != EfiMemory) {
|
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
|
|
|
ByProtocol,
|
|
|
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
|
|
|
NULL,
|
|
|
|
|
&BufferSize,
|
|
|
|
|
&HandleBuffer
|
|
|
|
|
);
|
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
// In the case of PCI or PCIE
|
|
|
|
|
// Get segment number and mask the segment bits in Address
|
|
|
|
|
//
|
|
|
|
|
if (AccessType == EfiPciEConfig) {
|
|
|
|
|
SegmentNumber = (UINT32) RShiftU64 (Address, 36) & 0xff;
|
|
|
|
|
Address &= 0xfffffffffULL;
|
|
|
|
|
} else {
|
|
|
|
|
if (AccessType == EfiPciConfig) {
|
|
|
|
|
SegmentNumber = (UINT32) RShiftU64 (Address, 32) & 0xff;
|
|
|
|
|
Address &= 0xffffffff;
|
|
|
|
|
if (PciRootBridgeIo == NULL) {
|
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE_ADDRESS_RANGE), gShellDebug1HiiHandle, L"mm", Address);
|
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment number
|
|
|
|
|
// Mode 1: Directly set a value
|
|
|
|
|
//
|
|
|
|
|
for (Index = 0; Index < BufferSize; Index++) {
|
|
|
|
|
Status = gBS->HandleProtocol (
|
|
|
|
|
HandleBuffer[Index],
|
|
|
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
|
|
|
(VOID *) &IoDev
|
|
|
|
|
);
|
|
|
|
|
Temp = ShellCommandLineGetRawValue (Package, 2);
|
|
|
|
|
if (Temp != NULL) {
|
|
|
|
|
Status = ShellConvertStringToUint64 (Temp, &Value, TRUE, FALSE);
|
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (IoDev->SegmentNumber != SegmentNumber) {
|
|
|
|
|
IoDev = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (IoDev == NULL) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_SEGMENT_NOT_FOUND), gShellDebug1HiiHandle, L"mm", SegmentNumber);
|
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (AccessType == EfiIo && Address + Size > 0x10000) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE), gShellDebug1HiiHandle, L"mm");
|
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);
|
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (AccessType == EfiPciEConfig) {
|
|
|
|
|
GetPciEAddressFromInputAddress (Address, &PciEAddress);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Set value
|
|
|
|
|
//
|
|
|
|
|
if (ShellCommandLineGetRawValue(Package, 2) != NULL) {
|
|
|
|
|
if (AccessType == EFIMemoryMappedIo) {
|
|
|
|
|
IoDev->Mem.Write (IoDev, Width, Address, 1, &Value);
|
|
|
|
|
} else if (AccessType == EfiIo) {
|
|
|
|
|
IoDev->Io.Write (IoDev, Width, Address, 1, &Value);
|
|
|
|
|
} else if (AccessType == EfiPciConfig) {
|
|
|
|
|
IoDev->Pci.Write (IoDev, Width, Address, 1, &Value);
|
|
|
|
|
} else if (AccessType == EfiPciEConfig) {
|
|
|
|
|
IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Value);
|
|
|
|
|
} else {
|
|
|
|
|
WriteMem (Width, Address, 1, &Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ASSERT(ShellStatus == SHELL_SUCCESS);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// non-interactive mode
|
|
|
|
|
// Mode 2: Directly show a value
|
|
|
|
|
//
|
|
|
|
|
if (!Interactive) {
|
|
|
|
|
Buffer = 0;
|
|
|
|
|
if (AccessType == EFIMemoryMappedIo) {
|
|
|
|
|
if (!gEfiShellProtocol->BatchIsActive ()) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
|
|
|
|
|
}
|
|
|
|
|
IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiIo) {
|
|
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
|
|
|
|
|
}
|
|
|
|
|
IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiPciConfig) {
|
|
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
|
|
|
|
|
}
|
|
|
|
|
IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiPciEConfig) {
|
|
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
|
|
|
|
|
}
|
|
|
|
|
IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);
|
|
|
|
|
} else {
|
|
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
|
|
|
|
|
}
|
|
|
|
|
ReadMem (Width, Address, 1, &Buffer);
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
if (Size == 1) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
|
|
|
|
|
} else if (Size == 2) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);
|
|
|
|
|
} else if (Size == 4) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);
|
|
|
|
|
} else if (Size == 8) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);
|
|
|
|
|
ShellPrintEx (-1, -1, L"\r\n");
|
|
|
|
|
|
|
|
|
|
ASSERT(ShellStatus == SHELL_SUCCESS);
|
|
|
|
|
goto Done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// interactive mode
|
|
|
|
|
// Mode 3: Show or set values in interactive mode
|
|
|
|
|
//
|
|
|
|
|
Complete = FALSE;
|
|
|
|
|
do {
|
|
|
|
|
if (AccessType == EfiIo && Address + Size > 0x10000) {
|
|
|
|
|
if ((AccessType == ShellMmIo) && (Address + Size > MAX_UINT16 + 1)) {
|
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE2), gShellDebug1HiiHandle, L"mm");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Buffer = 0;
|
|
|
|
|
if (AccessType == EFIMemoryMappedIo) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
|
|
|
|
|
IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiIo) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
|
|
|
|
|
IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiPciConfig) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
|
|
|
|
|
IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiPciEConfig) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
|
|
|
|
|
IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);
|
|
|
|
|
} else {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
|
|
|
|
|
ReadMem (Width, Address, 1, &Buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
if (Size == 1) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
|
|
|
|
|
} else if (Size == 2) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);
|
|
|
|
|
} else if (Size == 4) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);
|
|
|
|
|
} else if (Size == 8) {
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);
|
|
|
|
|
}
|
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);
|
|
|
|
|
ShellPrintEx (-1, -1, L" > ");
|
|
|
|
|
//
|
|
|
|
|
// wait user input to modify
|
|
|
|
@ -591,55 +609,36 @@ ShellCommandRunMm (
|
|
|
|
|
}
|
|
|
|
|
ShellPromptForResponse (ShellPromptResponseTypeFreeform, NULL, (VOID**) &InputStr);
|
|
|
|
|
|
|
|
|
|
if (InputStr != NULL) {
|
|
|
|
|
//
|
|
|
|
|
// skip space characters
|
|
|
|
|
//
|
|
|
|
|
for (Index = 0; InputStr != NULL && InputStr[Index] == ' '; Index++);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// parse input string
|
|
|
|
|
//
|
|
|
|
|
if (InputStr != NULL && (InputStr[Index] == '.' || InputStr[Index] == 'q' || InputStr[Index] == 'Q')) {
|
|
|
|
|
Complete = TRUE;
|
|
|
|
|
} else if (InputStr == NULL || InputStr[Index] == CHAR_NULL) {
|
|
|
|
|
//
|
|
|
|
|
// Continue to next address
|
|
|
|
|
//
|
|
|
|
|
} else if (GetHex (InputStr + Index, &Buffer) && Buffer <= MaxNum[Width]) {
|
|
|
|
|
if (AccessType == EFIMemoryMappedIo) {
|
|
|
|
|
IoDev->Mem.Write (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiIo) {
|
|
|
|
|
IoDev->Io.Write (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiPciConfig) {
|
|
|
|
|
IoDev->Pci.Write (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
|
} else if (AccessType == EfiPciEConfig) {
|
|
|
|
|
IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Buffer);
|
|
|
|
|
} else {
|
|
|
|
|
WriteMem (Width, Address, 1, &Buffer);
|
|
|
|
|
for (Index = 0; InputStr[Index] == ' '; Index++);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((InputStr != NULL) && (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;
|
|
|
|
|
// PrintToken (STRING_TOKEN (STR_IOMOD_ERROR), HiiHandle);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Address += Size;
|
|
|
|
|
if (AccessType == EfiPciEConfig) {
|
|
|
|
|
GetPciEAddressFromInputAddress (Address, &PciEAddress);
|
|
|
|
|
}
|
|
|
|
|
ShellPrintEx (-1, -1, L"\r\n");
|
|
|
|
|
// Print (L"\n");
|
|
|
|
|
} while (!Complete);
|
|
|
|
|
}
|
|
|
|
|
ASSERT (ShellStatus == SHELL_SUCCESS);
|
|
|
|
|
Done:
|
|
|
|
|
|
|
|
|
|
Done:
|
|
|
|
|
if (InputStr != NULL) {
|
|
|
|
|
FreePool (InputStr);
|
|
|
|
|
}
|
|
|
|
|
if (HandleBuffer != NULL) {
|
|
|
|
|
FreePool (HandleBuffer);
|
|
|
|
|
}
|
|
|
|
|
if (Package != NULL) {
|
|
|
|
|
ShellCommandLineFreeVarList (Package);
|
|
|
|
|
}
|
|
|
|
|