]> git.proxmox.com Git - mirror_edk2.git/blob - BeagleBoardPkg/Library/EblCmdLib/EblCmdLib.c
Add some ldm/vldm optimized CopyMem routines. Add performance macros to BDS
[mirror_edk2.git] / BeagleBoardPkg / Library / EblCmdLib / EblCmdLib.c
1 /** @file
2 Add custom commands for BeagleBoard development.
3
4 Copyright (c) 2008-2010, Apple Inc. All rights reserved.
5
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <PiDxe.h>
17 #include <Library/ArmLib.h>
18 #include <Library/CacheMaintenanceLib.h>
19 #include <Library/EblCmdLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/UefiRuntimeServicesTableLib.h>
24 #include <Library/MemoryAllocationLib.h>
25 #include <Library/UefiLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/EfiFileLib.h>
28 #include <Library/ArmDisassemblerLib.h>
29 #include <Library/PeCoffGetEntryPointLib.h>
30 #include <Library/PerformanceLib.h>
31 #include <Library/TimerLib.h>
32
33 #include <Guid/DebugImageInfoTable.h>
34
35 #include <Protocol/DebugSupport.h>
36 #include <Protocol/LoadedImage.h>
37
38 /**
39 Simple arm disassembler via a library
40
41 Argv[0] - symboltable
42 Argv[1] - Optional qoted format string
43 Argv[2] - Optional flag
44
45 @param Argc Number of command arguments in Argv
46 @param Argv Array of strings that represent the parsed command line.
47 Argv[0] is the comamnd name
48
49 @return EFI_SUCCESS
50
51 **/
52 EFI_STATUS
53 EblSymbolTable (
54 IN UINTN Argc,
55 IN CHAR8 **Argv
56 )
57 {
58 EFI_STATUS Status;
59 EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugImageTableHeader = NULL;
60 EFI_DEBUG_IMAGE_INFO *DebugTable;
61 UINTN Entry;
62 CHAR8 *Format;
63 CHAR8 *Pdb;
64 UINT32 PeCoffSizeOfHeaders;
65 UINT32 ImageBase;
66 BOOLEAN Elf;
67
68 // Need to add lots of error checking on the passed in string
69 // Default string is for RealView debugger
70 Format = (Argc > 1) ? Argv[1] : "load /a /ni /np %a &0x%x";
71 Elf = (Argc > 2) ? FALSE : TRUE;
72
73 Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&DebugImageTableHeader);
74 if (EFI_ERROR (Status)) {
75 return Status;
76 }
77
78 DebugTable = DebugImageTableHeader->EfiDebugImageInfoTable;
79 if (DebugTable == NULL) {
80 return EFI_SUCCESS;
81 }
82
83 for (Entry = 0; Entry < DebugImageTableHeader->TableSize; Entry++, DebugTable++) {
84 if (DebugTable->NormalImage != NULL) {
85 if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
86 ImageBase = (UINT32)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
87 PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)ImageBase);
88 Pdb = PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
89 if (Pdb != NULL) {
90 if (Elf) {
91 // ELF and Mach-O images don't include the header so the linked address does not include header
92 ImageBase += PeCoffSizeOfHeaders;
93 }
94 AsciiPrint (Format, Pdb, ImageBase);
95 AsciiPrint ("\n");
96 } else {
97 }
98 }
99 }
100 }
101
102 return EFI_SUCCESS;
103 }
104
105
106 /**
107 Simple arm disassembler via a library
108
109 Argv[0] - disasm
110 Argv[1] - Address to start disassembling from
111 ARgv[2] - Number of instructions to disassembly (optional)
112
113 @param Argc Number of command arguments in Argv
114 @param Argv Array of strings that represent the parsed command line.
115 Argv[0] is the comamnd name
116
117 @return EFI_SUCCESS
118
119 **/
120 EFI_STATUS
121 EblDisassembler (
122 IN UINTN Argc,
123 IN CHAR8 **Argv
124 )
125 {
126 UINT8 *Ptr, *CurrentAddress;
127 UINT32 Address;
128 UINT32 Count;
129 CHAR8 Buffer[80];
130 UINT32 ItBlock;
131
132 if (Argc < 2) {
133 return EFI_INVALID_PARAMETER;
134 }
135
136 Address = AsciiStrHexToUintn (Argv[1]);
137 Count = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 20;
138
139 Ptr = (UINT8 *)(UINTN)Address;
140 ItBlock = 0;
141 do {
142 CurrentAddress = Ptr;
143 DisassembleInstruction (&Ptr, TRUE, TRUE, &ItBlock, Buffer, sizeof (Buffer));
144 AsciiPrint ("0x%08x: %a\n", CurrentAddress, Buffer);
145 } while (Count-- > 0);
146
147
148 return EFI_SUCCESS;
149 }
150
151
152 CHAR8 *
153 ImageHandleToPdbFileName (
154 IN EFI_HANDLE Handle
155 )
156 {
157 EFI_STATUS Status;
158 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
159 CHAR8 *Pdb;
160 CHAR8 *StripLeading;
161
162 Status = gBS->HandleProtocol (Handle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
163 if (EFI_ERROR (Status)) {
164 return "";
165 }
166
167 Pdb = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
168 StripLeading = AsciiStrStr (Pdb, "\\ARM\\");
169 if (StripLeading == NULL) {
170 StripLeading = AsciiStrStr (Pdb, "/ARM/");
171 if (StripLeading == NULL) {
172 return Pdb;
173 }
174 }
175 // Hopefully we hacked off the unneeded part
176 return (StripLeading + 5);
177 }
178
179
180 CHAR8 *mTokenList[] = {
181 "SEC",
182 "PEI",
183 "DXE",
184 "BDS",
185 NULL
186 };
187
188 /**
189 Simple arm disassembler via a library
190
191 Argv[0] - disasm
192 Argv[1] - Address to start disassembling from
193 ARgv[2] - Number of instructions to disassembly (optional)
194
195 @param Argc Number of command arguments in Argv
196 @param Argv Array of strings that represent the parsed command line.
197 Argv[0] is the comamnd name
198
199 @return EFI_SUCCESS
200
201 **/
202 EFI_STATUS
203 EblPerformance (
204 IN UINTN Argc,
205 IN CHAR8 **Argv
206 )
207 {
208 UINTN Key;
209 CONST VOID *Handle;
210 CONST CHAR8 *Token, *Module;
211 UINT64 Start, Stop, TimeStamp;
212 UINT64 Delta, TicksPerSecond, Milliseconds, Microseconds;
213 UINTN Index;
214
215 TicksPerSecond = GetPerformanceCounterProperties (NULL, NULL);
216
217 Key = 0;
218 do {
219 Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
220 if (Key != 0) {
221 if (AsciiStriCmp ("StartImage:", Token) == 0) {
222 if (Stop == 0) {
223 // The entry for EBL is still running so the stop time will be zero. Skip it
224 AsciiPrint (" running %a\n", ImageHandleToPdbFileName ((EFI_HANDLE)Handle));
225 } else {
226 Delta = Stop - Start;
227 Microseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000000), TicksPerSecond, NULL);
228 AsciiPrint ("%10ld us %a\n", Microseconds, ImageHandleToPdbFileName ((EFI_HANDLE)Handle));
229 }
230 }
231 }
232 } while (Key != 0);
233
234 AsciiPrint ("\n");
235
236 TimeStamp = 0;
237 Key = 0;
238 do {
239 Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
240 if (Key != 0) {
241 for (Index = 0; mTokenList[Index] != NULL; Index++) {
242 if (AsciiStriCmp (mTokenList[Index], Token) == 0) {
243 Delta = Stop - Start;
244 TimeStamp += Delta;
245 Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);
246 AsciiPrint ("%6a %6ld ms\n", Token, Milliseconds);
247 break;
248 }
249 }
250 }
251 } while (Key != 0);
252
253 AsciiPrint ("Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));
254
255 return EFI_SUCCESS;
256 }
257
258
259 GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mLibCmdTemplate[] =
260 {
261 {
262 "disasm address [count]",
263 " disassemble count instructions",
264 NULL,
265 EblDisassembler
266 },
267 {
268 "performance",
269 " Display boot performance info",
270 NULL,
271 EblPerformance
272 },
273 {
274 "symboltable [\"format string\"] [PECOFF]",
275 " show symbol table commands for debugger",
276 NULL,
277 EblSymbolTable
278 }
279 };
280
281
282 VOID
283 EblInitializeExternalCmd (
284 VOID
285 )
286 {
287 EblAddCommands (mLibCmdTemplate, sizeof (mLibCmdTemplate)/sizeof (EBL_COMMAND_TABLE));
288 return;
289 }