REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ShellPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			673 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			673 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Main file for Mm shell Debug1 function.
 | |
| 
 | |
|   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
 | |
|   Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "UefiShellDebug1CommandsLib.h"
 | |
| #include <Library/ShellLib.h>
 | |
| #include <Library/IoLib.h>
 | |
| #include <Protocol/PciRootBridgeIo.h>
 | |
| #include <Protocol/DeviceIo.h>
 | |
| 
 | |
| typedef enum {
 | |
|   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  },
 | |
|   { L"-mem",  TypeFlag  },
 | |
|   { L"-io",   TypeFlag  },
 | |
|   { L"-pci",  TypeFlag  },
 | |
|   { L"-pcie", TypeFlag  },
 | |
|   { L"-n",    TypeFlag  },
 | |
|   { L"-w",    TypeValue },
 | |
|   { NULL,     TypeMax   }
 | |
| };
 | |
| 
 | |
| 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
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Extract the PCI segment, bus, device, function, register from
 | |
|   from a PCI or PCIE format of address..
 | |
| 
 | |
|   @param[in]  PciFormat      Whether the address is of PCI format of PCIE format.
 | |
|   @param[in]  Address        PCI or 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
 | |
| ShellMmDecodePciAddress (
 | |
|   IN BOOLEAN  PciFormat,
 | |
|   IN UINT64   Address,
 | |
|   OUT UINT32  *Segment,
 | |
|   OUT UINT8   *Bus,
 | |
|   OUT UINT8   *Device    OPTIONAL,
 | |
|   OUT UINT8   *Function  OPTIONAL,
 | |
|   OUT UINT32  *Register  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   if (PciFormat) {
 | |
|     //
 | |
|     // PCI Configuration Space.The address will have the format ssssbbddffrr,
 | |
|     // where ssss = Segment, bb = Bus, dd = Device, ff = Function and rr = Register.
 | |
|     //
 | |
|     *Segment = (UINT32)(RShiftU64 (Address, 32) & 0xFFFF);
 | |
|     *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 {
 | |
|     //
 | |
|     // PCI Express Configuration Space.The address will have the format ssssssbbddffrrr,
 | |
|     // where ssss = Segment, bb = Bus, dd = Device, ff = Function and rrr = Register.
 | |
|     //
 | |
|     *Segment = (UINT32)(RShiftU64 (Address, 36) & 0xFFFF);
 | |
|     *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;
 | |
|     }
 | |
| 
 | |
|     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);
 | |
|     }
 | |
| 
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       if (AccessType == ShellMmIo) {
 | |
|         switch (Size) {
 | |
|           case 1:
 | |
|             if (Read) {
 | |
|               *(UINT8 *)Buffer = IoRead8 ((UINTN)Address);
 | |
|             } else {
 | |
|               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;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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]  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  There are PciRootBridgeIo instances in the platform.
 | |
|   @retval FALSE There isn't PciRootBridgeIo instance in the platform.
 | |
| **/
 | |
| BOOLEAN
 | |
| ShellMmLocateIoProtocol (
 | |
|   IN SHELL_MM_ACCESS_TYPE              AccessType,
 | |
|   IN UINT64                            Address,
 | |
|   OUT EFI_CPU_IO2_PROTOCOL             **CpuIo,
 | |
|   OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  **PciRootBridgeIo
 | |
|   )
 | |
| {
 | |
|   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;
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)CpuIo);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     *CpuIo = NULL;
 | |
|   }
 | |
| 
 | |
|   *PciRootBridgeIo = NULL;
 | |
|   HandleBuffer     = NULL;
 | |
|   Status           = gBS->LocateHandleBuffer (
 | |
|                             ByProtocol,
 | |
|                             &gEfiPciRootBridgeIoProtocolGuid,
 | |
|                             NULL,
 | |
|                             &HandleCount,
 | |
|                             &HandleBuffer
 | |
|                             );
 | |
|   if (EFI_ERROR (Status) || (HandleCount == 0) || (HandleBuffer == NULL)) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   Segment = 0;
 | |
|   Bus     = 0;
 | |
|   if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) {
 | |
|     ShellMmDecodePciAddress ((BOOLEAN)(AccessType == ShellMmPci), Address, &Segment, &Bus, NULL, NULL, NULL);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // 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;
 | |
|     }
 | |
| 
 | |
|     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;
 | |
| 
 | |
|             //
 | |
|             // 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;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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  *PciRootBridgeIo;
 | |
|   EFI_CPU_IO2_PROTOCOL             *CpuIo;
 | |
|   UINT64                           Address;
 | |
|   UINT64                           Value;
 | |
|   SHELL_MM_ACCESS_TYPE             AccessType;
 | |
|   UINT64                           Buffer;
 | |
|   UINTN                            Index;
 | |
|   UINTN                            Size;
 | |
|   BOOLEAN                          Complete;
 | |
|   CHAR16                           *InputStr;
 | |
|   BOOLEAN                          Interactive;
 | |
|   LIST_ENTRY                       *Package;
 | |
|   CHAR16                           *ProblemParam;
 | |
|   SHELL_STATUS                     ShellStatus;
 | |
|   CONST CHAR16                     *Temp;
 | |
|   BOOLEAN                          HasPciRootBridgeIo;
 | |
| 
 | |
|   Value       = 0;
 | |
|   Address     = 0;
 | |
|   ShellStatus = SHELL_SUCCESS;
 | |
|   InputStr    = NULL;
 | |
|   Size        = 1;
 | |
|   AccessType  = ShellMmMemory;
 | |
| 
 | |
|   //
 | |
|   // Parse arguments
 | |
|   //
 | |
|   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, L"mm", ProblemParam);
 | |
|       FreePool (ProblemParam);
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       goto Done;
 | |
|     } else {
 | |
|       ASSERT (FALSE);
 | |
|     }
 | |
|   } else {
 | |
|     if (ShellCommandLineGetCount (Package) < 2) {
 | |
|       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"mm");
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       goto Done;
 | |
|     } else if (ShellCommandLineGetCount (Package) > 3) {
 | |
|       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       goto Done;
 | |
|     } else if (ShellCommandLineGetFlag (Package, L"-w") && (ShellCommandLineGetValue (Package, L"-w") == NULL)) {
 | |
|       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"mm", L"-w");
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       goto Done;
 | |
|     } else {
 | |
|       if (ShellCommandLineGetFlag (Package, L"-mmio")) {
 | |
|         AccessType = ShellMmMemoryMappedIo;
 | |
|         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, L"mm");
 | |
|           ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|           goto Done;
 | |
|         }
 | |
|       } else if (ShellCommandLineGetFlag (Package, L"-mem")) {
 | |
|         AccessType = ShellMmMemory;
 | |
|         if (  ShellCommandLineGetFlag (Package, L"-io")
 | |
|            || ShellCommandLineGetFlag (Package, L"-pci")
 | |
|            || ShellCommandLineGetFlag (Package, L"-pcie")
 | |
|               )
 | |
|         {
 | |
|           ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
 | |
|           ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|           goto Done;
 | |
|         }
 | |
|       } else if (ShellCommandLineGetFlag (Package, L"-io")) {
 | |
|         AccessType = ShellMmIo;
 | |
|         if (  ShellCommandLineGetFlag (Package, L"-pci")
 | |
|            || ShellCommandLineGetFlag (Package, L"-pcie")
 | |
|               )
 | |
|         {
 | |
|           ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
 | |
|           ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|           goto Done;
 | |
|         }
 | |
|       } else if (ShellCommandLineGetFlag (Package, L"-pci")) {
 | |
|         AccessType = ShellMmPci;
 | |
|         if (ShellCommandLineGetFlag (Package, L"-pcie")
 | |
|             )
 | |
|         {
 | |
|           ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");
 | |
|           ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|           goto Done;
 | |
|         }
 | |
|       } else if (ShellCommandLineGetFlag (Package, L"-pcie")) {
 | |
|         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) {
 | |
|       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);
 | |
|     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;
 | |
|     }
 | |
| 
 | |
|     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;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // locate IO protocol interface
 | |
|     //
 | |
|     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;
 | |
|       }
 | |
| 
 | |
|       if (PciRootBridgeIo == NULL) {
 | |
|         ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE_ADDRESS_RANGE), gShellDebug1HiiHandle, L"mm", Address);
 | |
|         ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|         goto Done;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Mode 1: Directly set a value
 | |
|     //
 | |
|     Temp = ShellCommandLineGetRawValue (Package, 2);
 | |
|     if (Temp != NULL) {
 | |
|       Status = ShellConvertStringToUint64 (Temp, &Value, 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;
 | |
|       }
 | |
| 
 | |
|       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;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Mode 2: Directly show a value
 | |
|     //
 | |
|     if (!Interactive) {
 | |
|       if (!gEfiShellProtocol->BatchIsActive ()) {
 | |
|         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);
 | |
|       }
 | |
| 
 | |
|       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);
 | |
|       ShellPrintEx (-1, -1, L"\r\n");
 | |
|       goto Done;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Mode 3: Show or set values in interactive mode
 | |
|     //
 | |
|     Complete = FALSE;
 | |
|     do {
 | |
|       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);
 | |
|       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);
 | |
|       ShellPrintEx (-1, -1, L" > ");
 | |
|       //
 | |
|       // wait user input to modify
 | |
|       //
 | |
|       if (InputStr != NULL) {
 | |
|         FreePool (InputStr);
 | |
|         InputStr = NULL;
 | |
|       }
 | |
| 
 | |
|       ShellPromptForResponse (ShellPromptResponseTypeFreeform, NULL, (VOID **)&InputStr);
 | |
| 
 | |
|       if (InputStr != NULL) {
 | |
|         //
 | |
|         // skip space characters
 | |
|         //
 | |
|         for (Index = 0; InputStr[Index] == ' '; Index++) {
 | |
|         }
 | |
| 
 | |
|         if (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;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       Address += Size;
 | |
|       ShellPrintEx (-1, -1, L"\r\n");
 | |
|     } while (!Complete);
 | |
|   }
 | |
| 
 | |
|   ASSERT (ShellStatus == SHELL_SUCCESS);
 | |
| 
 | |
| Done:
 | |
|   if (InputStr != NULL) {
 | |
|     FreePool (InputStr);
 | |
|   }
 | |
| 
 | |
|   if (Package != NULL) {
 | |
|     ShellCommandLineFreeVarList (Package);
 | |
|   }
 | |
| 
 | |
|   return ShellStatus;
 | |
| }
 |