|
|
/*++
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); }
|