windows-nt/Source/XPSP1/NT/base/efiutil/sdk/shell/iomod/iomod.c

352 lines
10 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1999 Intel Corporation
Module Name:
io.c
Abstract:
Revision History
--*/
#include "shelle.h"
typedef enum {
EfiMemory,
EFIMemoryMappedIo,
EfiIo,
EfiPciConfig
} EFI_ACCESS_TYPE;
EFI_STATUS
DumpIoModify (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
VOID
ReadMem (
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Size,
IN VOID *Buffer
);
VOID
WriteMem (
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Size,
IN VOID *Buffer
);
EFI_DRIVER_ENTRY_POINT(DumpIoModify)
EFI_STATUS
DumpIoModify (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*+++
iomod Address [Width] [;[MEM | MMIO | IO | PCI]] [:Value]
if no Width 1 byte is default, 1|2|4|8 supported byte widths
if no ; then default access type is memory (MEM)
After a ; ;MEM = Memory, ;MMIO = Memmory Mapped IO, ;IO = in/out, PCI = PCI Config space
--*/
{
EFI_STATUS Status;
EFI_HANDLE Handle;
EFI_DEVICE_PATH *DevicePath;
EFI_DEVICE_IO_INTERFACE *IoDev;
UINT64 Address;
UINT64 Value;
EFI_IO_WIDTH Width;
EFI_ACCESS_TYPE AccessType;
UINT64 Buffer;
UINTN Index;
UINTN Size;
CHAR16 *AddressStr, *WidthStr, *p, *ValueStr;
BOOLEAN Done;
CHAR16 InputStr[80];
BOOLEAN Interactive;
InstallInternalShellCommand (
ImageHandle, SystemTable, DumpIoModify,
L"mm", /* command */
L"mm Address [Width] [;Type]", /* command syntax */
L"Memory Modify: Mem, MMIO, IO, PCI", /* 1 line descriptor */
NULL /* command help page */
);
/*
* The End Device Path represents the Root of the tree, thus get the global IoDev
* for the system
*/
InitializeShellApplication (ImageHandle, SystemTable);
Width = IO_UINT8;
Size = 1;
AccessType = EfiMemory;
AddressStr = WidthStr = NULL;
ValueStr = NULL;
Interactive = TRUE;
for (Index = 1; Index < SI->Argc; Index += 1) {
p = SI->Argv[Index];
if (*p == ';') {
switch (p[1]) {
case 'I':
case 'i':
AccessType = EfiIo;
continue;
case 'P':
case 'p':
AccessType = EfiPciConfig;
continue;
default:
case 'M':
case 'm':
if (p[2] == 'E' || p[2] == 'e') {
AccessType = EfiMemory;
}
if (p[2] == 'M' || p[2] == 'm') {
AccessType = EFIMemoryMappedIo;
}
continue;
}
} else if (*p == ':') {
ValueStr = &p[1];
Value = xtoi(ValueStr);
continue;
} else if (*p == '-') {
switch (p[1]) {
case 'n':
case 'N': Interactive = FALSE;
break;
case 'h':
case 'H':
case '?':
default:
goto UsageError;
};
continue;
}
if (!AddressStr) {
AddressStr = p;
Address = xtoi(AddressStr);
continue;
}
if (!WidthStr) {
WidthStr = p;
switch (xtoi(WidthStr)) {
case 2:
Width = IO_UINT16;
Size = 2;
continue;
case 4:
Width = IO_UINT32;
Size = 4;
continue;
case 8:
Width = IO_UINT64;
Size = 8;
continue;
case 1:
default:
Width = IO_UINT8;
Size = 1;
continue;
}
}
}
if (!AddressStr) {
goto UsageError;
}
if ((Address & (Size - 1)) != 0) {
goto UsageError;
}
if (AccessType != EfiMemory) {
DevicePath = EndDevicePath;
Status = BS->LocateDevicePath (&DeviceIoProtocol, &DevicePath, &Handle);
if (!EFI_ERROR(Status)) {
Status = BS->HandleProtocol (Handle, &DeviceIoProtocol, (VOID*)&IoDev);
}
if (EFI_ERROR(Status)) {
Print (L"%E - handle protocol error %r%N", Status);
return Status;
}
}
if (ValueStr) {
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 {
WriteMem (Width, Address, 1, &Value);
}
return EFI_SUCCESS;
}
if (Interactive == FALSE) {
Buffer = 0;
if (AccessType == EFIMemoryMappedIo) {
Print (L"%HMMIO%N");
IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
} else if (AccessType == EfiIo) {
Print (L"%HIO%N");
IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
} else if (AccessType == EfiPciConfig) {
Print (L"%HPCI%N");
IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
} else {
Print (L"%HMEM%N");
ReadMem (Width, Address, 1, &Buffer);
}
Print (L" 0x%016lx : 0x", Address);
if (Size == 1) {
Print (L"%02x", Buffer);
} else if (Size == 2) {
Print (L"%04x", Buffer);
} else if (Size == 4) {
Print (L"%08x", Buffer);
} else if (Size == 8) {
Print (L"%016lx", Buffer);
}
Print(L"\n");
return EFI_SUCCESS;
}
Done = FALSE;
do {
Buffer = 0;
if (AccessType == EFIMemoryMappedIo) {
Print (L"%HMMIO%N");
IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
} else if (AccessType == EfiIo) {
Print (L"%HIO%N");
IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
} else if (AccessType == EfiPciConfig) {
Print (L"%HPCI%N");
IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
} else {
Print (L"%HMEM%N");
ReadMem (Width, Address, 1, &Buffer);
}
Print (L" 0x%016lx : 0x", Address);
if (Size == 1) {
Print (L"%02x", Buffer);
} else if (Size == 2) {
Print (L"%04x", Buffer);
} else if (Size == 4) {
Print (L"%08x", Buffer);
} else if (Size == 8) {
Print (L"%016lx", Buffer);
}
Input (L" > ", InputStr, sizeof(InputStr));
if (*InputStr == '.' || *InputStr == 'e' || *InputStr == 'q' || *InputStr == 'E' || *InputStr == 'Q' ) {
Done = TRUE;
} else if (*InputStr != 0x00) {
Buffer = xtoi(InputStr);
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 {
WriteMem (Width, Address, 1, &Buffer);
}
}
Address += Size;
Print (L"\n");
} while (!Done);
return EFI_SUCCESS;
UsageError:
Print (L"\n%Hmm%N %HAddress%N [%HWidth%N 1|2|4|8] [%H;MMIO | ;MEM | ;IO | ;PCI%N] [%H:Value%N] [%H-n%N]\n");
Print (L" Default access is %HMEM%N of width 1 byte with interactive mode off\n");
Print (L" Address must be aligned on a %HWidth%N boundary\n");
Print (L" %HMEM%N - Memory Address 0 - 0xffffffff_ffffffff\n");
Print (L" %HMMIO%N - Memory Mapped IO Address 0 - 0xffffffff_ffffffff\n");
Print (L" %HIO%N - IO Address 0 - 0xffff\n");
Print (L" %HPCI%N - PCI Config Address 0x000000%Hss%Nbb%Hdd%Nff%Hrr%N\n");
Print (L" %Hss%N-> _SEG bb-> bus %Hdd%N-> Device ff-> Func %Hrr%N-> Register\n");
Print (L" [%H-n%N] - Interactive Mode Off\n");
return EFI_SUCCESS;
}
VOID
ReadMem (
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Size,
IN VOID *Buffer
)
{
do {
if (Width == IO_UINT8) {
*(UINT8 *)Buffer = *(UINT8 *)Address;
Address -= 1;
} else if (Width == IO_UINT16) {
*(UINT16 *)Buffer = *(UINT16 *)Address;
Address -= 2;
} else if (Width == IO_UINT32) {
*(UINT32 *)Buffer = *(UINT32 *)Address;
Address -= 4;
} else if (Width == IO_UINT64) {
*(UINT64 *)Buffer = *(UINT64 *)Address;
Address -= 8;
} else {
ASSERT(FALSE);
}
Size--;
} while (Size > 0);
}
VOID
WriteMem (
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Size,
IN VOID *Buffer
)
{
do {
if (Width == IO_UINT8) {
*(UINT8 *)Address = *(UINT8 *)Buffer;
Address += 1;
} else if (Width == IO_UINT16) {
*(UINT16 *)Address = *(UINT16 *)Buffer;
Address += 2;
} else if (Width == IO_UINT32) {
*(UINT32 *)Address = *(UINT32 *)Buffer;
Address += 4;
} else if (Width == IO_UINT64) {
*(UINT64 *)Address = *(UINT64 *)Buffer;
Address += 8;
} else {
ASSERT(FALSE);
}
Size--;
} while (Size > 0);
}