/** @file\r
Add custom commands for BeagleBoard development.\r
\r
- Copyright (c) 2008-2009, Apple Inc. All rights reserved.\r
+ Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
#include <Library/PcdLib.h>\r
#include <Library/EfiFileLib.h>\r
#include <Library/ArmDisassemblerLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/TimerLib.h>\r
\r
-//PcdEmbeddedFdBaseAddress\r
+#include <Guid/DebugImageInfoTable.h>\r
+\r
+#include <Protocol/DebugSupport.h>\r
+#include <Protocol/LoadedImage.h>\r
\r
/**\r
- Fill Me In\r
+ Simple arm disassembler via a library\r
\r
- Argv[0] - "%CommandName%"\r
+ Argv[0] - symboltable\r
+ Argv[1] - Optional qoted format string \r
+ Argv[2] - Optional flag\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 comamnd name\r
+\r
+ @return EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EblSymbolTable (\r
+ IN UINTN Argc,\r
+ IN CHAR8 **Argv\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugImageTableHeader = NULL;\r
+ EFI_DEBUG_IMAGE_INFO *DebugTable;\r
+ UINTN Entry;\r
+ CHAR8 *Format;\r
+ CHAR8 *Pdb;\r
+ UINT32 PeCoffSizeOfHeaders;\r
+ UINT32 ImageBase;\r
+ BOOLEAN Elf;\r
+ \r
+ // Need to add lots of error checking on the passed in string\r
+ // Default string is for RealView debugger\r
+ Format = (Argc > 1) ? Argv[1] : "load /a /ni /np %a &0x%x";\r
+ Elf = (Argc > 2) ? FALSE : TRUE;\r
+ \r
+ Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&DebugImageTableHeader);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ DebugTable = DebugImageTableHeader->EfiDebugImageInfoTable;\r
+ if (DebugTable == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ for (Entry = 0; Entry < DebugImageTableHeader->TableSize; Entry++, DebugTable++) {\r
+ if (DebugTable->NormalImage != NULL) {\r
+ if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {\r
+ ImageBase = (UINT32)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;\r
+ PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)ImageBase);\r
+ Pdb = PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);\r
+ if (Pdb != NULL) {\r
+ if (Elf) {\r
+ // ELF and Mach-O images don't include the header so the linked address does not include header\r
+ ImageBase += PeCoffSizeOfHeaders;\r
+ } \r
+ AsciiPrint (Format, Pdb, ImageBase);\r
+ AsciiPrint ("\n");\r
+ } else {\r
+ }\r
+ }\r
+ } \r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Simple arm disassembler via a library\r
+\r
+ Argv[0] - disasm\r
+ Argv[1] - Address to start disassembling from\r
+ ARgv[2] - Number of instructions to disassembly (optional)\r
\r
@param Argc Number of command arguments in Argv\r
@param Argv Array of strings that represent the parsed command line. \r
IN CHAR8 **Argv\r
)\r
{\r
- UINT8 *Ptr;\r
+ UINT8 *Ptr, *CurrentAddress;\r
UINT32 Address;\r
UINT32 Count;\r
CHAR8 Buffer[80];\r
+ UINT32 ItBlock;\r
\r
if (Argc < 2) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
Address = AsciiStrHexToUintn (Argv[1]);\r
- Count = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 10;\r
+ Count = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 20;\r
\r
Ptr = (UINT8 *)(UINTN)Address; \r
- while (Count-- > 0) {\r
- DisassembleInstruction (&Ptr, TRUE, TRUE, Buffer, sizeof (Buffer));\r
- AsciiPrint ("0x%08x: %a", Address, Buffer);\r
+ ItBlock = 0;\r
+ do {\r
+ CurrentAddress = Ptr;\r
+ DisassembleInstruction (&Ptr, TRUE, TRUE, &ItBlock, Buffer, sizeof (Buffer));\r
+ AsciiPrint ("0x%08x: %a\n", CurrentAddress, Buffer);\r
+ } while (Count-- > 0);\r
+ \r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+CHAR8 *\r
+ImageHandleToPdbFileName (\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
+\r
+ Status = gBS->HandleProtocol (Handle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);\r
+ if (EFI_ERROR (Status)) {\r
+ return "";\r
}\r
\r
+ return PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);\r
+}\r
+\r
+CHAR8 *mTokenList[] = {\r
+ "SEC",\r
+ "PEI",\r
+ "DXE",\r
+ "BDS",\r
+ NULL\r
+};\r
+\r
+/**\r
+ Simple arm disassembler via a library\r
+\r
+ Argv[0] - disasm\r
+ Argv[1] - Address to start disassembling from\r
+ ARgv[2] - Number of instructions to disassembly (optional)\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 comamnd name\r
+\r
+ @return EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EblPerformance (\r
+ IN UINTN Argc,\r
+ IN CHAR8 **Argv\r
+ )\r
+{\r
+ UINTN Key;\r
+ CONST VOID *Handle;\r
+ CONST CHAR8 *Token, *Module;\r
+ UINT64 Start, Stop, TimeStamp;\r
+ UINT64 Delta, TicksPerSecond, Milliseconds, Microseconds;\r
+ UINTN Index;\r
+\r
+ TicksPerSecond = GetPerformanceCounterProperties (NULL, NULL);\r
+\r
+ Key = 0;\r
+ do {\r
+ Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);\r
+ if (Key != 0) {\r
+ if (AsciiStriCmp ("StartImage:", Token) == 0) {\r
+ if (Stop == 0) {\r
+ // The entry for EBL is still running so the stop time will be zero. Skip it\r
+ AsciiPrint (" running %a\n", ImageHandleToPdbFileName ((EFI_HANDLE)Handle));\r
+ } else {\r
+ Delta = Stop - Start;\r
+ Microseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000000), TicksPerSecond, NULL);\r
+ AsciiPrint ("%10ld us %a\n", Microseconds, ImageHandleToPdbFileName ((EFI_HANDLE)Handle));\r
+ }\r
+ }\r
+ }\r
+ } while (Key != 0);\r
+\r
+ AsciiPrint ("\n");\r
+\r
+ TimeStamp = 0;\r
+ Key = 0;\r
+ do {\r
+ Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);\r
+ if (Key != 0) {\r
+ for (Index = 0; mTokenList[Index] != NULL; Index++) {\r
+ if (AsciiStriCmp (mTokenList[Index], Token) == 0) {\r
+ Delta = Stop - Start;\r
+ TimeStamp += Delta;\r
+ Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);\r
+ AsciiPrint ("%6a %6ld ms\n", Token, Milliseconds);\r
+ break;\r
+ }\r
+ } \r
+ }\r
+ } while (Key != 0);\r
+\r
+ AsciiPrint ("Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));\r
+\r
return EFI_SUCCESS;\r
}\r
\r
" disassemble count instructions",\r
NULL,\r
EblDisassembler\r
+ },\r
+ {\r
+ "performance",\r
+ " Display boot performance info",\r
+ NULL,\r
+ EblPerformance\r
+ },\r
+ {\r
+ "symboltable [\"format string\"] [PECOFF]",\r
+ " show symbol table commands for debugger",\r
+ NULL,\r
+ EblSymbolTable\r
}\r
};\r
\r