Trailing spaces create issue/warning when generating/applying patches. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ronald Cron <ronald.cron@arm.com> Reviewed-By: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15833 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			343 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			343 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Basic command line parser for EBL (Embedded Boot Loader)
 | 
						|
 | 
						|
  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
 | 
						|
  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
 | 
						|
 | 
						|
  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.
 | 
						|
 | 
						|
  Module Name:  HwDebug.c
 | 
						|
 | 
						|
  Commands useful for debugging hardware.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "Ebl.h"
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Dump memory
 | 
						|
 | 
						|
  Argv[0] - "md"[.#] # is optional width 1, 2, 4, or 8. Default 1
 | 
						|
  Argv[1] - Hex Address to dump
 | 
						|
  Argv[2] - Number of hex bytes to dump (0x20 is default)
 | 
						|
 | 
						|
  md.4 0x123445678 50 ; Dump 0x50 4 byte quantities starting at 0x123445678
 | 
						|
  md   0x123445678 40 ; Dump 0x40 1 byte quantities starting at 0x123445678
 | 
						|
  md   0x123445678    ; Dump 0x20 1 byte quantities starting at 0x123445678
 | 
						|
 | 
						|
  @param  Argc   Number of command arguments in Argv
 | 
						|
  @param  Argv   Array of strings that represent the parsed command line.
 | 
						|
                 Argv[0] is the command name
 | 
						|
 | 
						|
  @return EFI_SUCCESS
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EblMdCmd (
 | 
						|
  IN UINTN  Argc,
 | 
						|
  IN CHAR8  **Argv
 | 
						|
  )
 | 
						|
{
 | 
						|
  STATIC UINT8  *Address = NULL;
 | 
						|
  STATIC UINTN  Length   = 0x20;
 | 
						|
  STATIC UINTN  Width;
 | 
						|
 | 
						|
  Width = WidthFromCommandName (Argv[0], 1);
 | 
						|
 | 
						|
  switch (Argc) {
 | 
						|
    case 3:
 | 
						|
      Length = AsciiStrHexToUintn(Argv[2]);
 | 
						|
    case 2:
 | 
						|
      Address = (UINT8 *)AsciiStrHexToUintn (Argv[1]);
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  OutputData (Address, Length, Width, (UINTN)Address);
 | 
						|
 | 
						|
  Address += Length;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Fill Memory with data
 | 
						|
 | 
						|
  Argv[0] - "mfill"[.#] # is optional width 1, 2, 4, or 8. Default 4
 | 
						|
  Argv[1] - Hex Address to fill
 | 
						|
  Argv[2] - Data to write (0x00 is default)
 | 
						|
  Argv[3] - Number of units to dump.
 | 
						|
 | 
						|
  mf.1 0x123445678 aa 100 ; Start at 0x123445678 and write aa (1 byte) to the next 100 bytes
 | 
						|
  mf.4 0x123445678 aa 100 ; Start at 0x123445678 and write aa (4 byte) to the next 400 bytes
 | 
						|
  mf 0x123445678 aa       ; Start at 0x123445678 and write aa (4 byte) to the next 1 byte
 | 
						|
  mf 0x123445678          ; Start at 0x123445678 and write 00 (4 byte) to the next 1 byte
 | 
						|
 | 
						|
  @param  Argc   Number of command arguments in Argv
 | 
						|
  @param  Argv   Array of strings that represent the parsed command line.
 | 
						|
                 Argv[0] is the command name
 | 
						|
 | 
						|
  @return EFI_SUCCESS
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EblMfillCmd (
 | 
						|
  IN UINTN  Argc,
 | 
						|
  IN CHAR8  **Argv
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN   Address;
 | 
						|
  UINTN   EndAddress;
 | 
						|
  UINT32  Data;
 | 
						|
  UINTN   Length;
 | 
						|
  UINTN   Width;
 | 
						|
 | 
						|
  if (Argc < 2) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Width = WidthFromCommandName (Argv[0], 4);
 | 
						|
 | 
						|
  Address = AsciiStrHexToUintn (Argv[1]);
 | 
						|
  Data    = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 0;
 | 
						|
  Length  = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1;
 | 
						|
 | 
						|
  for (EndAddress = Address + (Length * Width); Address < EndAddress; Address += Width) {
 | 
						|
    if (Width == 4) {
 | 
						|
      MmioWrite32 (Address, Data);
 | 
						|
    } else if (Width == 2) {
 | 
						|
      MmioWrite16 (Address, (UINT16)Data);
 | 
						|
    } else {
 | 
						|
      MmioWrite8 (Address, (UINT8)Data);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
// Strings for PCI Class code [2]
 | 
						|
//
 | 
						|
CHAR8 *gPciDevClass[] = {
 | 
						|
  "Old Device             ",
 | 
						|
  "Mass storage           ",
 | 
						|
  "Network                ",
 | 
						|
  "Display                ",
 | 
						|
  "Multimedia             ",
 | 
						|
  "Memory controller      ",
 | 
						|
  "Bridge device          ",
 | 
						|
  "simple communications  ",
 | 
						|
  "base system peripherals",
 | 
						|
  "Input devices          ",
 | 
						|
  "Docking stations       ",
 | 
						|
  "Processors             ",
 | 
						|
  "serial bus             ",
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
CHAR8 *gPciSerialClassCodes[] = {
 | 
						|
  "Mass storage           ",
 | 
						|
  "Firewire               ",
 | 
						|
  "ACCESS bus             ",
 | 
						|
  "SSA                    ",
 | 
						|
  "USB                     "
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  PCI Dump
 | 
						|
 | 
						|
  Argv[0] - "pci"
 | 
						|
  Argv[1] - bus
 | 
						|
  Argv[2] - dev
 | 
						|
  Argv[3] - func
 | 
						|
 | 
						|
  @param  Argc   Number of command arguments in Argv
 | 
						|
  @param  Argv   Array of strings that represent the parsed command line.
 | 
						|
                 Argv[0] is the command name
 | 
						|
 | 
						|
  @return EFI_SUCCESS
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EblPciCmd (
 | 
						|
  IN UINTN  Argc,
 | 
						|
  IN CHAR8  **Argv
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  EFI_PCI_IO_PROTOCOL           *Pci;
 | 
						|
  UINTN                         HandleCount;
 | 
						|
  EFI_HANDLE                    *HandleBuffer;
 | 
						|
  UINTN                         Seg;
 | 
						|
  UINTN                         Bus;
 | 
						|
  UINTN                         Dev;
 | 
						|
  UINTN                         Func;
 | 
						|
  UINTN                         BusArg;
 | 
						|
  UINTN                         DevArg;
 | 
						|
  UINTN                         FuncArg;
 | 
						|
  UINTN                         Index;
 | 
						|
  UINTN                         Count;
 | 
						|
  PCI_TYPE_GENERIC              PciHeader;
 | 
						|
  PCI_TYPE_GENERIC              *Header;
 | 
						|
  PCI_BRIDGE_CONTROL_REGISTER   *Bridge;
 | 
						|
  PCI_DEVICE_HEADER_TYPE_REGION *Device;
 | 
						|
  PCI_DEVICE_INDEPENDENT_REGION *Hdr;
 | 
						|
  CHAR8                         *Str;
 | 
						|
  UINTN                         ThisBus;
 | 
						|
 | 
						|
 | 
						|
  BusArg  = (Argc > 1) ? AsciiStrDecimalToUintn (Argv[1]) : 0;
 | 
						|
  DevArg  = (Argc > 2) ? AsciiStrDecimalToUintn (Argv[2]) : 0;
 | 
						|
  FuncArg = (Argc > 3) ? AsciiStrDecimalToUintn (Argv[3]) : 0;
 | 
						|
 | 
						|
  Header = &PciHeader;
 | 
						|
 | 
						|
  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPciIoProtocolGuid, NULL, &HandleCount, &HandleBuffer);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    AsciiPrint ("No PCI devices found in the system\n");
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Argc == 1) {
 | 
						|
    // Dump all PCI devices
 | 
						|
    AsciiPrint ("BusDevFun  VendorId DeviceId  Device Class          Sub-Class\n");
 | 
						|
    AsciiPrint ("_____________________________________________________________");
 | 
						|
    for (ThisBus = 0; ThisBus <= PCI_MAX_BUS; ThisBus++) {
 | 
						|
      for (Index = 0; Index < HandleCount; Index++) {
 | 
						|
        Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&Pci);
 | 
						|
        if (!EFI_ERROR (Status)) {
 | 
						|
          Pci->GetLocation (Pci, &Seg, &Bus, &Dev, &Func);
 | 
						|
          if (ThisBus != Bus) {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
          AsciiPrint ("\n%03d.%02d.%02d", Bus, Dev, Func);
 | 
						|
          Status = Pci->Pci.Read (Pci, EfiPciIoWidthUint32, 0, sizeof (PciHeader)/sizeof (UINT32), &PciHeader);
 | 
						|
          if (!EFI_ERROR (Status)) {
 | 
						|
            Hdr = &PciHeader.Bridge.Hdr;
 | 
						|
 | 
						|
            if (Hdr->ClassCode[2] < sizeof (gPciDevClass)/sizeof (VOID *)) {
 | 
						|
              Str = gPciDevClass[Hdr->ClassCode[2]];
 | 
						|
              if (Hdr->ClassCode[2] == PCI_CLASS_SERIAL) {
 | 
						|
                if (Hdr->ClassCode[1] < sizeof (gPciSerialClassCodes)/sizeof (VOID *)) {
 | 
						|
                  // print out Firewire or USB inplace of Serial Bus controllers
 | 
						|
                  Str = gPciSerialClassCodes[Hdr->ClassCode[1]];
 | 
						|
                }
 | 
						|
              }
 | 
						|
            } else {
 | 
						|
              Str = "Unknown device         ";
 | 
						|
            }
 | 
						|
            AsciiPrint ("  0x%04x   0x%04x    %a 0x%02x", Hdr->VendorId, Hdr->DeviceId, Str, Hdr->ClassCode[1]);
 | 
						|
          }
 | 
						|
          if (Seg != 0) {
 | 
						|
            // Only print Segment if it is non zero. If you only have one PCI segment it is
 | 
						|
            // redundent to print it out
 | 
						|
            AsciiPrint (" Seg:%d", Seg);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    AsciiPrint ("\n");
 | 
						|
  } else {
 | 
						|
    // Dump specific PCI device
 | 
						|
    for (Index = 0; Index < HandleCount; Index++) {
 | 
						|
      Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&Pci);
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        Pci->GetLocation (Pci, &Seg, &Bus, &Dev, &Func);
 | 
						|
        if ((Bus == BusArg) && (Dev == DevArg) && (Func == FuncArg)) {
 | 
						|
          // Only print Segment if it is non zero. If you only have one PCI segment it is
 | 
						|
          // redundant to print it out
 | 
						|
          if (Seg != 0) {
 | 
						|
            AsciiPrint ("Seg:%d ", Seg);
 | 
						|
          }
 | 
						|
          AsciiPrint ("Bus:%d Dev:%d Func:%d ", Bus, Dev, Func);
 | 
						|
 | 
						|
          Status = Pci->Pci.Read (Pci, EfiPciIoWidthUint32, 0, sizeof (PciHeader)/sizeof (UINT32), Header);
 | 
						|
          if (!EFI_ERROR (Status)) {
 | 
						|
            Hdr = &PciHeader.Bridge.Hdr;
 | 
						|
            if (IS_PCI_BRIDGE (&PciHeader.Bridge)) {
 | 
						|
              Bridge = &PciHeader.Bridge.Bridge;
 | 
						|
              AsciiPrint (
 | 
						|
                "PCI Bridge. Bus Primary %d Secondary %d Subordinate %d\n",
 | 
						|
                Bridge->PrimaryBus, Bridge->SecondaryBus, Bridge->SubordinateBus
 | 
						|
                );
 | 
						|
              AsciiPrint ("  Bar 0: 0x%08x  Bar 1: 0x%08x\n", Bridge->Bar[0], Bridge->Bar[1]);
 | 
						|
            } else {
 | 
						|
              Device = &PciHeader.Device.Device;
 | 
						|
              AsciiPrint (
 | 
						|
                "VendorId: 0x%04x DeviceId: 0x%04x SubSusVendorId: 0x%04x SubSysDeviceId: 0x%04x\n",
 | 
						|
                Hdr->VendorId, Hdr->DeviceId, Device->SubsystemVendorID, Device->SubsystemID
 | 
						|
                );
 | 
						|
              AsciiPrint ("  Class Code: 0x%02x 0x%02x 0x%02x\n", Hdr->ClassCode[2], Hdr->ClassCode[1], Hdr->ClassCode[0]);
 | 
						|
              for (Count = 0; Count < 6; Count++) {
 | 
						|
                AsciiPrint ("  Bar %d: 0x%08x\n", Count, Device->Bar[Count]);
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
 | 
						|
          AsciiPrint ("\n");
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (HandleBuffer);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdPciDebugTemplate[] = {
 | 
						|
  {
 | 
						|
    "pci",
 | 
						|
    " [bus] [dev] [func]; Dump PCI",
 | 
						|
    NULL,
 | 
						|
    EblPciCmd
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwDebugTemplate[] =
 | 
						|
{
 | 
						|
  {
 | 
						|
    "md",
 | 
						|
    "[.{1|2|4}] [Addr] [Len] [1|2|4]; Memory Dump from Addr Len bytes",
 | 
						|
    NULL,
 | 
						|
    EblMdCmd
 | 
						|
  },
 | 
						|
  {
 | 
						|
    "mfill",
 | 
						|
    "[.{1|2|4}] Addr Len [data]; Memory Fill Addr Len*(1|2|4) bytes of data(0)",
 | 
						|
    NULL,
 | 
						|
    EblMfillCmd
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize the commands in this in this file
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EblInitializemdHwDebugCmds (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (FeaturePcdGet (PcdEmbeddedHwDebugCmd)) {
 | 
						|
    EblAddCommands (mCmdHwDebugTemplate, sizeof (mCmdHwDebugTemplate)/sizeof (EBL_COMMAND_TABLE));
 | 
						|
  }
 | 
						|
  if (FeaturePcdGet (PcdEmbeddedPciDebugCmd)) {
 | 
						|
    EblAddCommands (mCmdPciDebugTemplate, sizeof (mCmdPciDebugTemplate)/sizeof (EBL_COMMAND_TABLE));
 | 
						|
  }
 | 
						|
}
 | 
						|
 |