2010-11-16 23:36:37 +01:00
|
|
|
/** @file
|
|
|
|
Main file for Mm shell Debug1 function.
|
|
|
|
|
2013-11-20 18:25:02 +01:00
|
|
|
Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
|
2010-11-16 23:36:37 +01:00
|
|
|
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 <Protocol/PciRootBridgeIo.h>
|
|
|
|
#include <Protocol/DeviceIo.h>
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
EfiMemory,
|
|
|
|
EFIMemoryMappedIo,
|
|
|
|
EfiIo,
|
|
|
|
EfiPciConfig,
|
|
|
|
EfiPciEConfig
|
|
|
|
} EFI_ACCESS_TYPE;
|
|
|
|
|
2011-03-25 22:22:20 +01:00
|
|
|
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}
|
|
|
|
};
|
|
|
|
|
2011-04-07 23:50:16 +02:00
|
|
|
STATIC CONST UINT64 MaxNum[9] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffULL };
|
2011-03-25 22:22:20 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
Read some data into a buffer from memory.
|
2010-11-16 23:36:37 +01:00
|
|
|
|
2011-03-25 22:22:20 +01:00
|
|
|
@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.
|
|
|
|
**/
|
2010-11-16 23:36:37 +01:00
|
|
|
VOID
|
|
|
|
EFIAPI
|
|
|
|
ReadMem (
|
|
|
|
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
|
|
|
IN UINT64 Address,
|
|
|
|
IN UINTN Size,
|
2011-03-25 22:22:20 +01:00
|
|
|
OUT VOID *Buffer
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// This function is defective. This ASSERT prevents the defect from affecting anything.
|
|
|
|
//
|
|
|
|
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;
|
|
|
|
} else {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_READ_ERROR), gShellDebug1HiiHandle);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Size--;
|
|
|
|
} while (Size > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Write some data to memory.
|
2010-11-16 23:36:37 +01:00
|
|
|
|
2011-03-25 22:22:20 +01:00
|
|
|
@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.
|
|
|
|
**/
|
2010-11-16 23:36:37 +01:00
|
|
|
VOID
|
|
|
|
EFIAPI
|
|
|
|
WriteMem (
|
|
|
|
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
|
|
|
IN UINT64 Address,
|
|
|
|
IN UINTN Size,
|
|
|
|
IN VOID *Buffer
|
2011-03-25 22:22:20 +01:00
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// 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;
|
|
|
|
} else {
|
|
|
|
ASSERT (FALSE);
|
|
|
|
}
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
Size--;
|
|
|
|
} while (Size > 0);
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
|
2011-03-25 22:22:20 +01:00
|
|
|
/**
|
|
|
|
Convert a string to it's hex data.
|
|
|
|
|
|
|
|
@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.
|
|
|
|
|
|
|
|
@retval TRUE The conversion was successful.
|
|
|
|
@retval FALSE The conversion failed.
|
|
|
|
**/
|
2010-11-16 23:36:37 +01:00
|
|
|
BOOLEAN
|
|
|
|
EFIAPI
|
|
|
|
GetHex (
|
|
|
|
IN UINT16 *str,
|
|
|
|
OUT UINT64 *data
|
2011-03-25 22:22:20 +01:00
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN TempUint;
|
|
|
|
CHAR16 TempChar;
|
|
|
|
BOOLEAN Find;
|
2010-11-16 23:36:37 +01:00
|
|
|
|
2011-03-25 22:22:20 +01:00
|
|
|
Find = FALSE;
|
|
|
|
//
|
|
|
|
// convert hex digits
|
|
|
|
//
|
|
|
|
TempUint = 0;
|
|
|
|
TempChar = *(str++);
|
|
|
|
while (TempChar != CHAR_NULL) {
|
|
|
|
if (TempChar >= 'a' && TempChar <= 'f') {
|
|
|
|
TempChar -= 'a' - 'A';
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
|
2011-03-25 22:22:20 +01:00
|
|
|
if (TempChar == ' ') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((TempChar >= '0' && TempChar <= '9') || (TempChar >= 'A' && TempChar <= 'F')) {
|
2011-04-05 23:19:39 +02:00
|
|
|
TempUint = (TempUint << 4) | (TempChar - (TempChar >= 'A' ? 'A' - 10 : '0'));
|
2011-03-25 22:22:20 +01:00
|
|
|
|
|
|
|
Find = TRUE;
|
|
|
|
} else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
TempChar = *(str++);
|
|
|
|
}
|
|
|
|
|
|
|
|
*data = TempUint;
|
|
|
|
return Find;
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
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).
|
|
|
|
|
|
|
|
@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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
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 *IoDev;
|
|
|
|
UINT64 Address;
|
|
|
|
UINT64 PciEAddress;
|
|
|
|
UINT64 Value;
|
|
|
|
UINT32 SegmentNumber;
|
|
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width;
|
|
|
|
EFI_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;
|
|
|
|
|
|
|
|
Address = 0;
|
|
|
|
PciEAddress = 0;
|
|
|
|
IoDev = NULL;
|
|
|
|
HandleBuffer = NULL;
|
|
|
|
BufferSize = 0;
|
|
|
|
SegmentNumber = 0;
|
|
|
|
ShellStatus = SHELL_SUCCESS;
|
|
|
|
InputStr = NULL;
|
|
|
|
|
|
|
|
//
|
|
|
|
// 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) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);
|
|
|
|
FreePool(ProblemParam);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
} else {
|
|
|
|
ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
} else {
|
2011-03-25 22:22:20 +01:00
|
|
|
if (ShellCommandLineGetCount(Package) < 2) {
|
2010-11-16 23:36:37 +01:00
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
} else if (ShellCommandLineGetCount(Package) > 3) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
2011-03-25 22:22:20 +01:00
|
|
|
} else if (ShellCommandLineGetFlag(Package, L"-w") && ShellCommandLineGetValue(Package, L"-w") == NULL) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-w");
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
2010-11-16 23:36:37 +01:00
|
|
|
} else {
|
|
|
|
if (ShellCommandLineGetFlag(Package, L"-mmio")) {
|
|
|
|
AccessType = EFIMemoryMappedIo;
|
2011-03-25 22:22:20 +01:00
|
|
|
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);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (ShellCommandLineGetFlag(Package, L"-mem")) {
|
|
|
|
AccessType = EfiMemory;
|
2011-03-25 22:22:20 +01:00
|
|
|
if (ShellCommandLineGetFlag(Package, L"-io")
|
|
|
|
||ShellCommandLineGetFlag(Package, L"-pci")
|
|
|
|
||ShellCommandLineGetFlag(Package, L"-pcie")
|
|
|
|
){
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (ShellCommandLineGetFlag(Package, L"-io")) {
|
|
|
|
AccessType = EfiIo;
|
2011-03-25 22:22:20 +01:00
|
|
|
if (ShellCommandLineGetFlag(Package, L"-pci")
|
|
|
|
||ShellCommandLineGetFlag(Package, L"-pcie")
|
|
|
|
){
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (ShellCommandLineGetFlag(Package, L"-pci")) {
|
|
|
|
AccessType = EfiPciConfig;
|
2011-03-25 22:22:20 +01:00
|
|
|
if (ShellCommandLineGetFlag(Package, L"-pcie")
|
|
|
|
){
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (ShellCommandLineGetFlag(Package, L"-pcie")) {
|
|
|
|
AccessType = EfiPciEConfig;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-20 18:25:02 +01:00
|
|
|
//
|
|
|
|
// Non interactive for a script file or for the specific parameter
|
|
|
|
//
|
|
|
|
if (gEfiShellProtocol->BatchIsActive() || ShellCommandLineGetFlag (Package, L"-n")) {
|
2010-11-16 23:36:37 +01:00
|
|
|
Interactive = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Temp = ShellCommandLineGetValue(Package, L"-w");
|
|
|
|
if (Temp != NULL) {
|
2011-03-25 22:22:20 +01:00
|
|
|
ItemValue = ShellStrToUintn (Temp);
|
2010-11-16 23:36:37 +01:00
|
|
|
|
|
|
|
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:
|
2011-03-25 22:22:20 +01:00
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"-w");
|
2010-11-16 23:36:37 +01:00
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Temp = ShellCommandLineGetRawValue(Package, 1);
|
2011-03-25 22:22:20 +01:00
|
|
|
if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, (UINT64*)&Address, TRUE, FALSE))) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
2010-11-16 23:36:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Temp = ShellCommandLineGetRawValue(Package, 2);
|
|
|
|
if (Temp != NULL) {
|
2013-11-20 18:25:02 +01:00
|
|
|
//
|
|
|
|
// Per spec if value is specified, then -n is assumed.
|
|
|
|
//
|
|
|
|
Interactive = FALSE;
|
|
|
|
|
2011-03-25 22:22:20 +01:00
|
|
|
if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, &Value, TRUE, FALSE))) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
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_PROBLEM), gShellDebug1HiiHandle, Temp);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((Address & (Size - 1)) != 0) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_NOT_ALIGNED), gShellDebug1HiiHandle, Address);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// locate DeviceIO protocol interface
|
|
|
|
//
|
|
|
|
if (AccessType != EfiMemory) {
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
|
|
ByProtocol,
|
|
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
|
|
NULL,
|
|
|
|
&BufferSize,
|
|
|
|
&HandleBuffer
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle);
|
|
|
|
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;
|
2011-04-07 23:50:16 +02:00
|
|
|
Address &= 0xfffffffffULL;
|
2010-11-16 23:36:37 +01:00
|
|
|
} else {
|
|
|
|
if (AccessType == EfiPciConfig) {
|
|
|
|
SegmentNumber = (UINT32) RShiftU64 (Address, 32) & 0xff;
|
|
|
|
Address &= 0xffffffff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment number
|
|
|
|
//
|
|
|
|
for (Index = 0; Index < BufferSize; Index++) {
|
|
|
|
Status = gBS->HandleProtocol (
|
|
|
|
HandleBuffer[Index],
|
|
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
|
|
(VOID *) &IoDev
|
|
|
|
);
|
|
|
|
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, SegmentNumber);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (AccessType == EfiIo && Address + Size > 0x10000) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE), gShellDebug1HiiHandle);
|
|
|
|
ShellStatus = SHELL_INVALID_PARAMETER;
|
|
|
|
goto Done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (AccessType == EfiPciEConfig) {
|
|
|
|
GetPciEAddressFromInputAddress (Address, &PciEAddress);
|
|
|
|
}
|
|
|
|
|
2011-09-08 18:50:17 +02:00
|
|
|
//
|
|
|
|
// 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);
|
|
|
|
goto Done;
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// non-interactive mode
|
|
|
|
//
|
|
|
|
if (!Interactive) {
|
|
|
|
Buffer = 0;
|
|
|
|
if (AccessType == EFIMemoryMappedIo) {
|
2013-11-20 18:25:02 +01:00
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
} else if (AccessType == EfiIo) {
|
2013-11-20 18:25:02 +01:00
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
} else if (AccessType == EfiPciConfig) {
|
2013-11-20 18:25:02 +01:00
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
|
|
|
|
} else if (AccessType == EfiPciEConfig) {
|
2013-11-20 18:25:02 +01:00
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);
|
|
|
|
} else {
|
2013-11-20 18:25:02 +01:00
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
ReadMem (Width, Address, 1, &Buffer);
|
|
|
|
}
|
2013-11-20 18:25:02 +01:00
|
|
|
if (!gEfiShellProtocol->BatchIsActive()) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
|
|
|
|
}
|
2010-11-16 23:36:37 +01:00
|
|
|
if (Size == 1) {
|
2012-08-07 02:54:29 +02:00
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (Size == 2) {
|
2012-08-07 02:54:29 +02:00
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (Size == 4) {
|
2012-08-07 02:54:29 +02:00
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (Size == 8) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
ShellPrintEx(-1, -1, L"\r\n");
|
|
|
|
|
|
|
|
ASSERT(ShellStatus == SHELL_SUCCESS);
|
|
|
|
goto Done;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// interactive mode
|
|
|
|
//
|
|
|
|
Complete = FALSE;
|
|
|
|
do {
|
|
|
|
if (AccessType == EfiIo && Address + Size > 0x10000) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE2), gShellDebug1HiiHandle);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
|
|
|
|
|
|
|
|
if (Size == 1) {
|
2012-08-07 02:54:29 +02:00
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (Size == 2) {
|
2012-08-07 02:54:29 +02:00
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (Size == 4) {
|
2012-08-07 02:54:29 +02:00
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);
|
2010-11-16 23:36:37 +01:00
|
|
|
} else if (Size == 8) {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);
|
|
|
|
}
|
2011-03-25 22:22:20 +01:00
|
|
|
ShellPrintEx(-1, -1, L" > ");
|
2010-11-16 23:36:37 +01:00
|
|
|
//
|
|
|
|
// wait user input to modify
|
|
|
|
//
|
|
|
|
if (InputStr != NULL) {
|
|
|
|
FreePool(InputStr);
|
2011-03-25 22:22:20 +01:00
|
|
|
InputStr = NULL;
|
2010-11-16 23:36:37 +01:00
|
|
|
}
|
|
|
|
ShellPromptForResponse(ShellPromptResponseTypeFreeform, NULL, (VOID**)&InputStr);
|
|
|
|
|
|
|
|
//
|
|
|
|
// skip space characters
|
|
|
|
//
|
2011-03-25 22:22:20 +01:00
|
|
|
for (Index = 0; InputStr != NULL && InputStr[Index] == ' '; Index++);
|
2010-11-16 23:36:37 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
// parse input string
|
|
|
|
//
|
2011-03-25 22:22:20 +01:00
|
|
|
if (InputStr != NULL && (InputStr[Index] == '.' || InputStr[Index] == 'q' || InputStr[Index] == 'Q')) {
|
2010-11-16 23:36:37 +01:00
|
|
|
Complete = TRUE;
|
2011-03-25 22:22:20 +01:00
|
|
|
} else if (InputStr == NULL || InputStr[Index] == CHAR_NULL) {
|
2010-11-16 23:36:37 +01:00
|
|
|
//
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle);
|
|
|
|
continue;
|
2011-03-25 22:22:20 +01:00
|
|
|
// PrintToken (STRING_TOKEN (STR_IOMOD_ERROR), HiiHandle);
|
2010-11-16 23:36:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Address += Size;
|
|
|
|
if (AccessType == EfiPciEConfig) {
|
|
|
|
GetPciEAddressFromInputAddress (Address, &PciEAddress);
|
|
|
|
}
|
|
|
|
ShellPrintEx(-1, -1, L"\r\n");
|
|
|
|
// Print (L"\n");
|
|
|
|
} while (!Complete);
|
|
|
|
}
|
|
|
|
ASSERT(ShellStatus == SHELL_SUCCESS);
|
|
|
|
Done:
|
|
|
|
|
|
|
|
if (InputStr != NULL) {
|
|
|
|
FreePool(InputStr);
|
|
|
|
}
|
|
|
|
if (HandleBuffer != NULL) {
|
|
|
|
FreePool (HandleBuffer);
|
|
|
|
}
|
|
|
|
if (Package != NULL) {
|
|
|
|
ShellCommandLineFreeVarList (Package);
|
|
|
|
}
|
|
|
|
return ShellStatus;
|
|
|
|
}
|