352 lines
10 KiB
C
352 lines
10 KiB
C
/*++
|
|
|
|
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);
|
|
}
|
|
|