Default exception handler\r
\r
Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
+ Copyright (c) 2012, ARM Ltd. All rights reserved.<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
**/\r
\r
#include <Uefi.h>\r
-#include <Library/UefiLib.h>\r
#include <Library/BaseLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/PrintLib.h>\r
#include <Library/ArmDisassemblerLib.h>\r
+#include <Library/SerialPortLib.h>\r
\r
#include <Guid/DebugImageInfoTable.h>\r
-#include <Protocol/DebugSupport.h>\r
-#include <Protocol/LoadedImage.h>\r
\r
+#include <Protocol/DebugSupport.h>\r
+#include <Library/DefaultExceptionHandlerLib.h>\r
\r
EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;\r
\r
-\r
typedef struct {\r
UINT32 BIT;\r
CHAR8 Char;\r
} CPSR_CHAR;\r
\r
-\r
-\r
- \r
-/**\r
- Use the EFI Debug Image Table to lookup the FaultAddress and find which PE/COFF image \r
- it came from. As long as the PE/COFF image contains a debug directory entry a \r
- string can be returned. For ELF and Mach-O images the string points to the Mach-O or ELF\r
- image. Microsoft tools contain a pointer to the PDB file that contains the debug information.\r
-\r
- @param FaultAddress Address to find PE/COFF image for. \r
- @param ImageBase Return load address of found image\r
- @param PeCoffSizeOfHeaders Return the size of the PE/COFF header for the image that was found\r
-\r
- @retval NULL FaultAddress not in a loaded PE/COFF image.\r
- @retval Path and file name of PE/COFF image.\r
- \r
-**/\r
CHAR8 *\r
GetImageName (\r
IN UINT32 FaultAddress,\r
OUT UINT32 *ImageBase,\r
OUT UINT32 *PeCoffSizeOfHeaders\r
- )\r
-{\r
- EFI_DEBUG_IMAGE_INFO *DebugTable;\r
- UINTN Entry;\r
- CHAR8 *Address;\r
-\r
- \r
- DebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;\r
- if (DebugTable == NULL) {\r
- return NULL;\r
- }\r
-\r
- Address = (CHAR8 *)(UINTN)FaultAddress;\r
- for (Entry = 0; Entry < gDebugImageTableHeader->TableSize; Entry++, DebugTable++) {\r
- if (DebugTable->NormalImage != NULL) {\r
- if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && \r
- (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {\r
- if ((Address >= (CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) &&\r
- (Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize))) {\r
- *ImageBase = (UINT32)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;\r
- *PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase);\r
- return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);\r
- } \r
- }\r
- } \r
- }\r
-\r
- return NULL;\r
-}\r
-\r
+ );\r
\r
/**\r
Convert the Current Program Status Register (CPSR) to a string. The string is \r
OUT CHAR8 *ReturnStr\r
)\r
{\r
- UINTN Index;\r
- CHAR8 *Str = ReturnStr;\r
- CHAR8 *ModeStr;\r
+ UINTN Index;\r
+ CHAR8* Str;\r
+ CHAR8* ModeStr;\r
CPSR_CHAR CpsrChar[] = {\r
{ 31, 'n' },\r
{ 30, 'z' },\r
{ 0, '?' }\r
};\r
\r
+ Str = ReturnStr;\r
+\r
for (Index = 0; CpsrChar[Index].BIT != 0; Index++, Str++) {\r
*Str = CpsrChar[Index].Char;\r
if ((Cpsr & (1 << CpsrChar[Index].BIT)) != 0) {\r
return FaultSource;\r
}\r
\r
-\r
-CHAR8 *gExceptionTypeString[] = {\r
+STATIC CHAR8 *gExceptionTypeString[] = {\r
"Reset",\r
"Undefined OpCode",\r
- "SWI",\r
+ "SVC",\r
"Prefetch Abort",\r
"Data Abort",\r
"Undefined",\r
"FIQ"\r
};\r
\r
-\r
/**\r
This is the default action to take on an unexpected exception\r
\r
IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
)\r
{\r
+ CHAR8 Buffer[100];\r
+ UINTN CharCount;\r
UINT32 DfsrStatus;\r
UINT32 IfsrStatus;\r
BOOLEAN DfsrWrite;\r
UINT32 PcAdjust = 0;\r
\r
- DEBUG ((EFI_D_ERROR, "\n%a Exception PC at 0x%08x CPSR 0x%08x ", gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR));\r
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n%a Exception PC at 0x%08x CPSR 0x%08x ",\r
+ gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR);\r
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
+\r
DEBUG_CODE_BEGIN ();\r
CHAR8 *Pdb;\r
UINT32 ImageBase;\r
\r
//\r
// A PE/COFF image loads its headers into memory so the headers are \r
- // included in the linked addressess. ELF and Mach-O images do not\r
+ // included in the linked addresses. ELF and Mach-O images do not\r
// include the headers so the first byte of the image is usually\r
// text (code). If you look at link maps from ELF or Mach-O images\r
- // you need to subtact out the size of the PE/COFF header to get\r
+ // you need to subtract out the size of the PE/COFF header to get\r
// get the offset that matches the link map. \r
//\r
DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader));\r
// If some one is stepping past the exception handler adjust the PC to point to the next instruction \r
SystemContext.SystemContextArm->PC += PcAdjust;\r
}\r
-\r
-\r
-\r
-\r
-/**\r
- The constructor function caches EFI Debug table information for use in the exception handler.\r
- \r
-\r
- @param ImageHandle The firmware allocated handle for the EFI image.\r
- @param SystemTable A pointer to the EFI System Table.\r
- \r
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DefaultExceptionHandlerConstructor (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- \r
- \r
- Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);\r
- if (EFI_ERROR (Status)) {\r
- gDebugImageTableHeader = NULL;\r
- }\r
- return Status;\r
-}\r