+++ /dev/null
-/** @file\r
- Basic command line parser for EBL (Embedded Boot Loader)\r
-\r
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
- (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
- Module Name: HwDebug.c\r
-\r
- Commands useful for debugging hardware.\r
-\r
-**/\r
-\r
-#include "Ebl.h"\r
-\r
-\r
-/**\r
- Dump memory\r
-\r
- Argv[0] - "md"[.#] # is optional width 1, 2, 4, or 8. Default 1\r
- Argv[1] - Hex Address to dump\r
- Argv[2] - Number of hex bytes to dump (0x20 is default)\r
-\r
- md.4 0x123445678 50 ; Dump 0x50 4 byte quantities starting at 0x123445678\r
- md 0x123445678 40 ; Dump 0x40 1 byte quantities starting at 0x123445678\r
- md 0x123445678 ; Dump 0x20 1 byte quantities starting at 0x123445678\r
-\r
- @param Argc Number of command arguments in Argv\r
- @param Argv Array of strings that represent the parsed command line.\r
- Argv[0] is the command name\r
-\r
- @return EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EblMdCmd (\r
- IN UINTN Argc,\r
- IN CHAR8 **Argv\r
- )\r
-{\r
- STATIC UINT8 *Address = NULL;\r
- STATIC UINTN Length = 0x20;\r
- STATIC UINTN Width;\r
-\r
- Width = WidthFromCommandName (Argv[0], 1);\r
-\r
- switch (Argc) {\r
- case 3:\r
- Length = AsciiStrHexToUintn(Argv[2]);\r
- case 2:\r
- Address = (UINT8 *)AsciiStrHexToUintn (Argv[1]);\r
- default:\r
- break;\r
- }\r
-\r
- OutputData (Address, Length, Width, (UINTN)Address);\r
-\r
- Address += Length;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Fill Memory with data\r
-\r
- Argv[0] - "mfill"[.#] # is optional width 1, 2, 4, or 8. Default 4\r
- Argv[1] - Hex Address to fill\r
- Argv[2] - Data to write (0x00 is default)\r
- Argv[3] - Number of units to dump.\r
-\r
- mf.1 0x123445678 aa 100 ; Start at 0x123445678 and write aa (1 byte) to the next 100 bytes\r
- mf.4 0x123445678 aa 100 ; Start at 0x123445678 and write aa (4 byte) to the next 400 bytes\r
- mf 0x123445678 aa ; Start at 0x123445678 and write aa (4 byte) to the next 1 byte\r
- mf 0x123445678 ; Start at 0x123445678 and write 00 (4 byte) to the next 1 byte\r
-\r
- @param Argc Number of command arguments in Argv\r
- @param Argv Array of strings that represent the parsed command line.\r
- Argv[0] is the command name\r
-\r
- @return EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EblMfillCmd (\r
- IN UINTN Argc,\r
- IN CHAR8 **Argv\r
- )\r
-{\r
- UINTN Address;\r
- UINTN EndAddress;\r
- UINT32 Data;\r
- UINTN Length;\r
- UINTN Width;\r
-\r
- if (Argc < 2) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Width = WidthFromCommandName (Argv[0], 4);\r
-\r
- Address = AsciiStrHexToUintn (Argv[1]);\r
- Data = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 0;\r
- Length = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1;\r
-\r
- for (EndAddress = Address + (Length * Width); Address < EndAddress; Address += Width) {\r
- if (Width == 4) {\r
- MmioWrite32 (Address, Data);\r
- } else if (Width == 2) {\r
- MmioWrite16 (Address, (UINT16)Data);\r
- } else {\r
- MmioWrite8 (Address, (UINT8)Data);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-//\r
-// Strings for PCI Class code [2]\r
-//\r
-CHAR8 *gPciDevClass[] = {\r
- "Old Device ",\r
- "Mass storage ",\r
- "Network ",\r
- "Display ",\r
- "Multimedia ",\r
- "Memory controller ",\r
- "Bridge device ",\r
- "simple communications ",\r
- "base system peripherals",\r
- "Input devices ",\r
- "Docking stations ",\r
- "Processors ",\r
- "serial bus ",\r
-};\r
-\r
-\r
-CHAR8 *gPciSerialClassCodes[] = {\r
- "Mass storage ",\r
- "Firewire ",\r
- "ACCESS bus ",\r
- "SSA ",\r
- "USB "\r
-};\r
-\r
-\r
-/**\r
- PCI Dump\r
-\r
- Argv[0] - "pci"\r
- Argv[1] - bus\r
- Argv[2] - dev\r
- Argv[3] - func\r
-\r
- @param Argc Number of command arguments in Argv\r
- @param Argv Array of strings that represent the parsed command line.\r
- Argv[0] is the command name\r
-\r
- @return EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EblPciCmd (\r
- IN UINTN Argc,\r
- IN CHAR8 **Argv\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *Pci;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN Seg;\r
- UINTN Bus;\r
- UINTN Dev;\r
- UINTN Func;\r
- UINTN BusArg;\r
- UINTN DevArg;\r
- UINTN FuncArg;\r
- UINTN Index;\r
- UINTN Count;\r
- PCI_TYPE_GENERIC PciHeader;\r
- PCI_TYPE_GENERIC *Header;\r
- PCI_BRIDGE_CONTROL_REGISTER *Bridge;\r
- PCI_DEVICE_HEADER_TYPE_REGION *Device;\r
- PCI_DEVICE_INDEPENDENT_REGION *Hdr;\r
- CHAR8 *Str;\r
- UINTN ThisBus;\r
-\r
-\r
- BusArg = (Argc > 1) ? AsciiStrDecimalToUintn (Argv[1]) : 0;\r
- DevArg = (Argc > 2) ? AsciiStrDecimalToUintn (Argv[2]) : 0;\r
- FuncArg = (Argc > 3) ? AsciiStrDecimalToUintn (Argv[3]) : 0;\r
-\r
- Header = &PciHeader;\r
-\r
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPciIoProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
- if (EFI_ERROR (Status)) {\r
- AsciiPrint ("No PCI devices found in the system\n");\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (Argc == 1) {\r
- // Dump all PCI devices\r
- AsciiPrint ("BusDevFun VendorId DeviceId Device Class Sub-Class\n");\r
- AsciiPrint ("_____________________________________________________________");\r
- for (ThisBus = 0; ThisBus <= PCI_MAX_BUS; ThisBus++) {\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&Pci);\r
- if (!EFI_ERROR (Status)) {\r
- Pci->GetLocation (Pci, &Seg, &Bus, &Dev, &Func);\r
- if (ThisBus != Bus) {\r
- continue;\r
- }\r
- AsciiPrint ("\n%03d.%02d.%02d", Bus, Dev, Func);\r
- Status = Pci->Pci.Read (Pci, EfiPciIoWidthUint32, 0, sizeof (PciHeader)/sizeof (UINT32), &PciHeader);\r
- if (!EFI_ERROR (Status)) {\r
- Hdr = &PciHeader.Bridge.Hdr;\r
-\r
- if (Hdr->ClassCode[2] < sizeof (gPciDevClass)/sizeof (VOID *)) {\r
- Str = gPciDevClass[Hdr->ClassCode[2]];\r
- if (Hdr->ClassCode[2] == PCI_CLASS_SERIAL) {\r
- if (Hdr->ClassCode[1] < sizeof (gPciSerialClassCodes)/sizeof (VOID *)) {\r
- // print out Firewire or USB inplace of Serial Bus controllers\r
- Str = gPciSerialClassCodes[Hdr->ClassCode[1]];\r
- }\r
- }\r
- } else {\r
- Str = "Unknown device ";\r
- }\r
- AsciiPrint (" 0x%04x 0x%04x %a 0x%02x", Hdr->VendorId, Hdr->DeviceId, Str, Hdr->ClassCode[1]);\r
- }\r
- if (Seg != 0) {\r
- // Only print Segment if it is non zero. If you only have one PCI segment it is\r
- // redundent to print it out\r
- AsciiPrint (" Seg:%d", Seg);\r
- }\r
- }\r
- }\r
- }\r
- AsciiPrint ("\n");\r
- } else {\r
- // Dump specific PCI device\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&Pci);\r
- if (!EFI_ERROR (Status)) {\r
- Pci->GetLocation (Pci, &Seg, &Bus, &Dev, &Func);\r
- if ((Bus == BusArg) && (Dev == DevArg) && (Func == FuncArg)) {\r
- // Only print Segment if it is non zero. If you only have one PCI segment it is\r
- // redundant to print it out\r
- if (Seg != 0) {\r
- AsciiPrint ("Seg:%d ", Seg);\r
- }\r
- AsciiPrint ("Bus:%d Dev:%d Func:%d ", Bus, Dev, Func);\r
-\r
- Status = Pci->Pci.Read (Pci, EfiPciIoWidthUint32, 0, sizeof (PciHeader)/sizeof (UINT32), Header);\r
- if (!EFI_ERROR (Status)) {\r
- Hdr = &PciHeader.Bridge.Hdr;\r
- if (IS_PCI_BRIDGE (&PciHeader.Bridge)) {\r
- Bridge = &PciHeader.Bridge.Bridge;\r
- AsciiPrint (\r
- "PCI Bridge. Bus Primary %d Secondary %d Subordinate %d\n",\r
- Bridge->PrimaryBus, Bridge->SecondaryBus, Bridge->SubordinateBus\r
- );\r
- AsciiPrint (" Bar 0: 0x%08x Bar 1: 0x%08x\n", Bridge->Bar[0], Bridge->Bar[1]);\r
- } else {\r
- Device = &PciHeader.Device.Device;\r
- AsciiPrint (\r
- "VendorId: 0x%04x DeviceId: 0x%04x SubSusVendorId: 0x%04x SubSysDeviceId: 0x%04x\n",\r
- Hdr->VendorId, Hdr->DeviceId, Device->SubsystemVendorID, Device->SubsystemID\r
- );\r
- AsciiPrint (" Class Code: 0x%02x 0x%02x 0x%02x\n", Hdr->ClassCode[2], Hdr->ClassCode[1], Hdr->ClassCode[0]);\r
- for (Count = 0; Count < 6; Count++) {\r
- AsciiPrint (" Bar %d: 0x%08x\n", Count, Device->Bar[Count]);\r
- }\r
- }\r
- }\r
-\r
- AsciiPrint ("\n");\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- FreePool (HandleBuffer);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdPciDebugTemplate[] = {\r
- {\r
- "pci",\r
- " [bus] [dev] [func]; Dump PCI",\r
- NULL,\r
- EblPciCmd\r
- }\r
-};\r
-\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwDebugTemplate[] =\r
-{\r
- {\r
- "md",\r
- "[.{1|2|4}] [Addr] [Len] [1|2|4]; Memory Dump from Addr Len bytes",\r
- NULL,\r
- EblMdCmd\r
- },\r
- {\r
- "mfill",\r
- "[.{1|2|4}] Addr Len [data]; Memory Fill Addr Len*(1|2|4) bytes of data(0)",\r
- NULL,\r
- EblMfillCmd\r
- },\r
-};\r
-\r
-\r
-\r
-/**\r
- Initialize the commands in this in this file\r
-**/\r
-VOID\r
-EblInitializemdHwDebugCmds (\r
- VOID\r
- )\r
-{\r
- if (FeaturePcdGet (PcdEmbeddedHwDebugCmd)) {\r
- EblAddCommands (mCmdHwDebugTemplate, sizeof (mCmdHwDebugTemplate)/sizeof (EBL_COMMAND_TABLE));\r
- }\r
- if (FeaturePcdGet (PcdEmbeddedPciDebugCmd)) {\r
- EblAddCommands (mCmdPciDebugTemplate, sizeof (mCmdPciDebugTemplate)/sizeof (EBL_COMMAND_TABLE));\r
- }\r
-}\r
-\r