]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c
ARM Packages: Removed trailing spaces
[mirror_edk2.git] / ArmPlatformPkg / Library / EblCmdLib / EblCmdLib.c
CommitLineData
1d5d0ae9 1/** @file\r
2*\r
d5cd447b 3* Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
1d5d0ae9 4*\r
3402aac7
RC
5* This program and the accompanying materials\r
6* are licensed and made available under the terms and conditions of the BSD License\r
7* which accompanies this distribution. The full text of the license may be found at\r
8* http://opensource.org/licenses/bsd-license.php\r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
1d5d0ae9 12*\r
13**/\r
14\r
15#include <PiDxe.h>\r
16#include <Library/ArmLib.h>\r
17#include <Library/CacheMaintenanceLib.h>\r
18#include <Library/EblCmdLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/DxeServicesTableLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Library/UefiBootServicesTableLib.h>\r
23#include <Library/UefiRuntimeServicesTableLib.h>\r
24#include <Library/MemoryAllocationLib.h>\r
25#include <Library/UefiLib.h>\r
26#include <Library/PcdLib.h>\r
27#include <Library/EfiFileLib.h>\r
28#include <Library/ArmDisassemblerLib.h>\r
29#include <Library/PeCoffGetEntryPointLib.h>\r
30#include <Library/PerformanceLib.h>\r
31#include <Library/TimerLib.h>\r
6a15908f 32#include <Library/BdsLib.h>\r
1d5d0ae9 33\r
34#include <Guid/DebugImageInfoTable.h>\r
35\r
36#include <Protocol/DebugSupport.h>\r
37#include <Protocol/LoadedImage.h>\r
6a15908f 38#include <Protocol/DevicePathToText.h>\r
1d5d0ae9 39\r
40EFI_STATUS\r
41EblDumpMmu (\r
42 IN UINTN Argc,\r
43 IN CHAR8 **Argv\r
44 );\r
3402aac7 45\r
145292e4 46EFI_STATUS\r
47EblDumpFdt (\r
48 IN UINTN Argc,\r
49 IN CHAR8 **Argv\r
50 );\r
1d5d0ae9 51\r
52/**\r
53 Simple arm disassembler via a library\r
54\r
55 Argv[0] - symboltable\r
3402aac7 56 Argv[1] - Optional qoted format string\r
1d5d0ae9 57 Argv[2] - Optional flag\r
58\r
59 @param Argc Number of command arguments in Argv\r
3402aac7 60 @param Argv Array of strings that represent the parsed command line.\r
96a8bc11 61 Argv[0] is the command name\r
1d5d0ae9 62\r
63 @return EFI_SUCCESS\r
64\r
65**/\r
66EFI_STATUS\r
67EblSymbolTable (\r
68 IN UINTN Argc,\r
69 IN CHAR8 **Argv\r
70 )\r
71{\r
72 EFI_STATUS Status;\r
73 EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugImageTableHeader = NULL;\r
74 EFI_DEBUG_IMAGE_INFO *DebugTable;\r
75 UINTN Entry;\r
76 CHAR8 *Format;\r
77 CHAR8 *Pdb;\r
78 UINT32 PeCoffSizeOfHeaders;\r
79 UINT32 ImageBase;\r
80 BOOLEAN Elf;\r
3402aac7 81\r
1d5d0ae9 82 // Need to add lots of error checking on the passed in string\r
83 // Default string is for RealView debugger\r
96a8bc11 84#if (__ARMCC_VERSION < 500000)\r
1d5d0ae9 85 Format = (Argc > 1) ? Argv[1] : "load /a /ni /np %a &0x%x";\r
96a8bc11 86#else\r
87 Format = (Argc > 1) ? Argv[1] : "add-symbol-file %a 0x%x";\r
88#endif\r
1d5d0ae9 89 Elf = (Argc > 2) ? FALSE : TRUE;\r
3402aac7 90\r
1d5d0ae9 91 Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&DebugImageTableHeader);\r
92 if (EFI_ERROR (Status)) {\r
93 return Status;\r
94 }\r
3402aac7 95\r
1d5d0ae9 96 DebugTable = DebugImageTableHeader->EfiDebugImageInfoTable;\r
97 if (DebugTable == NULL) {\r
98 return EFI_SUCCESS;\r
99 }\r
100\r
101 for (Entry = 0; Entry < DebugImageTableHeader->TableSize; Entry++, DebugTable++) {\r
102 if (DebugTable->NormalImage != NULL) {\r
103 if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {\r
d5cd447b 104 ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;\r
1d5d0ae9 105 PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)ImageBase);\r
106 Pdb = PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);\r
107 if (Pdb != NULL) {\r
108 if (Elf) {\r
109 // ELF and Mach-O images don't include the header so the linked address does not include header\r
110 ImageBase += PeCoffSizeOfHeaders;\r
3402aac7 111 }\r
1d5d0ae9 112 AsciiPrint (Format, Pdb, ImageBase);\r
113 AsciiPrint ("\n");\r
114 } else {\r
115 }\r
116 }\r
3402aac7 117 }\r
1d5d0ae9 118 }\r
119\r
120 return EFI_SUCCESS;\r
121}\r
122\r
123\r
124/**\r
125 Simple arm disassembler via a library\r
126\r
127 Argv[0] - disasm\r
128 Argv[1] - Address to start disassembling from\r
129 ARgv[2] - Number of instructions to disassembly (optional)\r
130\r
131 @param Argc Number of command arguments in Argv\r
3402aac7 132 @param Argv Array of strings that represent the parsed command line.\r
886f97c8 133 Argv[0] is the command name\r
1d5d0ae9 134\r
135 @return EFI_SUCCESS\r
136\r
137**/\r
138EFI_STATUS\r
139EblDisassembler (\r
140 IN UINTN Argc,\r
141 IN CHAR8 **Argv\r
142 )\r
143{\r
144 UINT8 *Ptr, *CurrentAddress;\r
145 UINT32 Address;\r
146 UINT32 Count;\r
147 CHAR8 Buffer[80];\r
148 UINT32 ItBlock;\r
3402aac7 149\r
1d5d0ae9 150 if (Argc < 2) {\r
151 return EFI_INVALID_PARAMETER;\r
152 }\r
3402aac7 153\r
1d5d0ae9 154 Address = AsciiStrHexToUintn (Argv[1]);\r
155 Count = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 20;\r
156\r
3402aac7 157 Ptr = (UINT8 *)(UINTN)Address;\r
1d5d0ae9 158 ItBlock = 0;\r
159 do {\r
160 CurrentAddress = Ptr;\r
161 DisassembleInstruction (&Ptr, TRUE, TRUE, &ItBlock, Buffer, sizeof (Buffer));\r
162 AsciiPrint ("0x%08x: %a\n", CurrentAddress, Buffer);\r
163 } while (Count-- > 0);\r
3402aac7 164\r
1d5d0ae9 165\r
166 return EFI_SUCCESS;\r
167}\r
168\r
169\r
170CHAR8 *\r
171ImageHandleToPdbFileName (\r
172 IN EFI_HANDLE Handle\r
173 )\r
174{\r
175 EFI_STATUS Status;\r
176 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
177 CHAR8 *Pdb;\r
178 CHAR8 *StripLeading;\r
179\r
180 Status = gBS->HandleProtocol (Handle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);\r
181 if (EFI_ERROR (Status)) {\r
182 return "";\r
183 }\r
184\r
185 Pdb = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);\r
186 StripLeading = AsciiStrStr (Pdb, "\\ARM\\");\r
187 if (StripLeading == NULL) {\r
188 StripLeading = AsciiStrStr (Pdb, "/ARM/");\r
189 if (StripLeading == NULL) {\r
190 return Pdb;\r
191 }\r
192 }\r
193 // Hopefully we hacked off the unneeded part\r
194 return (StripLeading + 5);\r
195}\r
196\r
197\r
6a15908f 198STATIC CHAR8 *mTokenList[] = {\r
1d5d0ae9 199 /*"SEC",*/\r
200 "PEI",\r
201 "DXE",\r
202 /*"BDS",*/\r
203 NULL\r
204};\r
205\r
206/**\r
207 Simple arm disassembler via a library\r
208\r
209 Argv[0] - disasm\r
210 Argv[1] - Address to start disassembling from\r
211 ARgv[2] - Number of instructions to disassembly (optional)\r
212\r
213 @param Argc Number of command arguments in Argv\r
3402aac7 214 @param Argv Array of strings that represent the parsed command line.\r
886f97c8 215 Argv[0] is the command name\r
1d5d0ae9 216\r
217 @return EFI_SUCCESS\r
218\r
219**/\r
220EFI_STATUS\r
221EblPerformance (\r
222 IN UINTN Argc,\r
223 IN CHAR8 **Argv\r
224 )\r
225{\r
226 UINTN Key;\r
227 CONST VOID *Handle;\r
228 CONST CHAR8 *Token, *Module;\r
229 UINT64 Start, Stop, TimeStamp;\r
230 UINT64 Delta, TicksPerSecond, Milliseconds, Microseconds;\r
231 UINTN Index;\r
68978a52 232 BOOLEAN CountUp;\r
1d5d0ae9 233\r
68978a52 234 TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop);\r
235 if (Start < Stop) {\r
236 CountUp = TRUE;\r
237 } else {\r
238 CountUp = FALSE;\r
239 }\r
1d5d0ae9 240\r
241 Key = 0;\r
242 do {\r
243 Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);\r
244 if (Key != 0) {\r
245 if (AsciiStriCmp ("StartImage:", Token) == 0) {\r
246 if (Stop == 0) {\r
247 // The entry for EBL is still running so the stop time will be zero. Skip it\r
248 AsciiPrint (" running %a\n", ImageHandleToPdbFileName ((EFI_HANDLE)Handle));\r
249 } else {\r
68978a52 250 Delta = CountUp?(Stop - Start):(Start - Stop);\r
1d5d0ae9 251 Microseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000000), TicksPerSecond, NULL);\r
252 AsciiPrint ("%10ld us %a\n", Microseconds, ImageHandleToPdbFileName ((EFI_HANDLE)Handle));\r
253 }\r
254 }\r
255 }\r
256 } while (Key != 0);\r
257\r
258 AsciiPrint ("\n");\r
259\r
260 TimeStamp = 0;\r
261 Key = 0;\r
262 do {\r
263 Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);\r
264 if (Key != 0) {\r
265 for (Index = 0; mTokenList[Index] != NULL; Index++) {\r
266 if (AsciiStriCmp (mTokenList[Index], Token) == 0) {\r
68978a52 267 Delta = CountUp?(Stop - Start):(Start - Stop);\r
1d5d0ae9 268 TimeStamp += Delta;\r
269 Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);\r
270 AsciiPrint ("%6a %6ld ms\n", Token, Milliseconds);\r
271 break;\r
272 }\r
3402aac7 273 }\r
1d5d0ae9 274 }\r
275 } while (Key != 0);\r
276\r
277 AsciiPrint ("Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));\r
278\r
279 return EFI_SUCCESS;\r
280}\r
281\r
282#define EFI_MEMORY_PORT_IO 0x4000000000000000ULL\r
283\r
284EFI_STATUS\r
285EblDumpGcd (\r
286 IN UINTN Argc,\r
287 IN CHAR8 **Argv\r
288 )\r
289{\r
6a15908f 290 EFI_STATUS Status;\r
291 UINTN NumberOfDescriptors;\r
292 UINTN i;\r
293 EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;\r
294 EFI_GCD_IO_SPACE_DESCRIPTOR *IoSpaceMap;\r
1d5d0ae9 295\r
6a15908f 296 Status = gDS->GetMemorySpaceMap(&NumberOfDescriptors,&MemorySpaceMap);\r
297 if (EFI_ERROR (Status)) {\r
298 return Status;\r
299 }\r
300 AsciiPrint (" Address Range Image Device Attributes\n");\r
301 AsciiPrint ("__________________________________________________________\n");\r
302 for (i=0; i < NumberOfDescriptors; i++) {\r
303 AsciiPrint ("MEM %016lx - %016lx",(UINT64)MemorySpaceMap[i].BaseAddress,MemorySpaceMap[i].BaseAddress+MemorySpaceMap[i].Length-1);\r
304 AsciiPrint (" %08x %08x",MemorySpaceMap[i].ImageHandle,MemorySpaceMap[i].DeviceHandle);\r
305\r
306 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_RUNTIME)\r
307 AsciiPrint (" RUNTIME");\r
308 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_PORT_IO)\r
309 AsciiPrint (" PORT_IO");\r
310\r
311 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_UC)\r
312 AsciiPrint (" MEM_UC");\r
313 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_WC)\r
314 AsciiPrint (" MEM_WC");\r
315 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_WT)\r
316 AsciiPrint (" MEM_WT");\r
317 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_WB)\r
318 AsciiPrint (" MEM_WB");\r
319 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_UCE)\r
320 AsciiPrint (" MEM_UCE");\r
321 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_WP)\r
322 AsciiPrint (" MEM_WP");\r
323 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_RP)\r
324 AsciiPrint (" MEM_RP");\r
325 if (MemorySpaceMap[i].Attributes & EFI_MEMORY_XP)\r
326 AsciiPrint (" MEM_XP");\r
327\r
328 if (MemorySpaceMap[i].GcdMemoryType & EfiGcdMemoryTypeNonExistent)\r
329 AsciiPrint (" TYPE_NONEXISTENT");\r
330 if (MemorySpaceMap[i].GcdMemoryType & EfiGcdMemoryTypeReserved)\r
331 AsciiPrint (" TYPE_RESERVED");\r
332 if (MemorySpaceMap[i].GcdMemoryType & EfiGcdMemoryTypeSystemMemory)\r
333 AsciiPrint (" TYPE_SYSMEM");\r
334 if (MemorySpaceMap[i].GcdMemoryType & EfiGcdMemoryTypeMemoryMappedIo)\r
335 AsciiPrint (" TYPE_MEMMAP");\r
336\r
337 AsciiPrint ("\n");\r
338 }\r
339\r
5b53eaff
OM
340 FreePool (MemorySpaceMap);\r
341\r
6a15908f 342 Status = gDS->GetIoSpaceMap(&NumberOfDescriptors,&IoSpaceMap);\r
343 if (EFI_ERROR (Status)) {\r
344 return Status;\r
345 }\r
346 for (i=0; i < NumberOfDescriptors; i++) {\r
347 AsciiPrint ("IO %08lx - %08lx",IoSpaceMap[i].BaseAddress,IoSpaceMap[i].BaseAddress+IoSpaceMap[i].Length);\r
348 AsciiPrint ("\t%08x %08x",IoSpaceMap[i].ImageHandle,IoSpaceMap[i].DeviceHandle);\r
349\r
350 if (IoSpaceMap[i].GcdIoType & EfiGcdMemoryTypeNonExistent)\r
351 AsciiPrint (" TYPE_NONEXISTENT");\r
352 if (IoSpaceMap[i].GcdIoType & EfiGcdMemoryTypeReserved)\r
353 AsciiPrint (" TYPE_RESERVED");\r
354 if (IoSpaceMap[i].GcdIoType & EfiGcdIoTypeIo)\r
355 AsciiPrint (" TYPE_IO");\r
356\r
357 AsciiPrint ("\n");\r
358 }\r
1d5d0ae9 359\r
5b53eaff
OM
360 FreePool (IoSpaceMap);\r
361\r
6a15908f 362 return EFI_SUCCESS;\r
363}\r
364\r
365EFI_STATUS\r
366EblDevicePaths (\r
367 IN UINTN Argc,\r
368 IN CHAR8 **Argv\r
369 )\r
370{\r
371 EFI_STATUS Status;\r
372 UINTN HandleCount;\r
373 EFI_HANDLE *HandleBuffer;\r
374 UINTN Index;\r
375 CHAR16* String;\r
376 EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
377 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;\r
378\r
379 BdsConnectAllDrivers();\r
380\r
381 Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);\r
382 if (EFI_ERROR (Status)) {\r
383 AsciiPrint ("Did not find the DevicePathToTextProtocol.\n");\r
384 return EFI_SUCCESS;\r
385 }\r
386\r
387 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
388 if (EFI_ERROR (Status)) {\r
389 AsciiPrint ("No device path found\n");\r
1d5d0ae9 390 return EFI_SUCCESS;\r
6a15908f 391 }\r
392\r
393 for (Index = 0; Index < HandleCount; Index++) {\r
394 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
395 String = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathProtocol,TRUE,TRUE);\r
d5cd447b 396 Print (L"[0x%X] %s\n",(UINTN)HandleBuffer[Index], String);\r
6a15908f 397 }\r
398\r
399 return EFI_SUCCESS;\r
1d5d0ae9 400}\r
401\r
402GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mLibCmdTemplate[] =\r
403{\r
404 {\r
405 "disasm address [count]",\r
406 " disassemble count instructions",\r
407 NULL,\r
408 EblDisassembler\r
409 },\r
410 {\r
411 "performance",\r
412 " Display boot performance info",\r
413 NULL,\r
414 EblPerformance\r
415 },\r
416 {\r
417 "symboltable [\"format string\"] [PECOFF]",\r
418 " show symbol table commands for debugger",\r
419 NULL,\r
420 EblSymbolTable\r
421 },\r
422 {\r
423 "dumpgcd",\r
424 " dump Global Coherency Domain",\r
425 NULL,\r
426 EblDumpGcd\r
427 },\r
428 {\r
429 "dumpmmu",\r
430 " dump MMU Table",\r
431 NULL,\r
432 EblDumpMmu\r
6a15908f 433 },\r
434 {\r
435 "devicepaths",\r
436 " list all the Device Paths",\r
437 NULL,\r
438 EblDevicePaths\r
145292e4 439 },\r
440 {\r
441 "dumpfdt",\r
442 " dump the current fdt or the one defined in the arguments",\r
443 NULL,\r
444 EblDumpFdt\r
1d5d0ae9 445 }\r
446};\r
447\r
448\r
449VOID\r
450EblInitializeExternalCmd (\r
451 VOID\r
452 )\r
453{\r
454 EblAddCommands (mLibCmdTemplate, sizeof (mLibCmdTemplate)/sizeof (EBL_COMMAND_TABLE));\r
455 return;\r
456}\r