/** @file\r
Default exception handler\r
\r
- Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
+ Copyright (c) 2012, ARM Ltd. All rights reserved.<BR>\r
\r
- All rights reserved. This program and the accompanying materials\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
\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