]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c
Arm Packages: Fixed coding style/Line endings to follow EDK2 coding convention
[mirror_edk2.git] / ArmPkg / Library / DefaultExceptionHandlerLib / DefaultExceptionHandler.c
index 8180c42cabdce4b5840a19b34f6e3639e9c44c73..07e31ea597b5b995290e0696c3537d42a1eae19a 100644 (file)
@@ -1,9 +1,9 @@
 /** @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
   \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
 #include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/ArmDisassemblerLib.h>\r
 \r
 #include <Guid/DebugImageInfoTable.h>\r
 #include <Protocol/DebugSupport.h>\r
 #include <Protocol/LoadedImage.h>\r
 \r
 \r
-VOID\r
-DisassembleArmInstruction (\r
-  IN  UINT32    *OpCodePtr,\r
-  OUT CHAR8     *Buf,\r
-  OUT UINTN     Size\r
-  );\r
-\r
-VOID\r
-DisassembleThumbInstruction (\r
-  IN  UINT16    *OpCodePtr,\r
-  OUT CHAR8     *Buf,\r
-  OUT UINTN     Size\r
-  );\r
-\r
-\r
 EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;\r
 \r
 \r
@@ -47,8 +33,6 @@ typedef struct {
   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
@@ -75,7 +59,6 @@ GetImageName (
   UINTN                 Entry;\r
   CHAR8                 *Address;\r
 \r
-  \r
   DebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;\r
   if (DebugTable == NULL) {\r
     return NULL;\r
@@ -116,9 +99,9 @@ CpsrString (
   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
@@ -133,6 +116,8 @@ CpsrString (
     { 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
@@ -208,8 +193,7 @@ FaultStatusToString (
   return FaultSource;\r
 }\r
 \r
-\r
-CHAR8 *gExceptionTypeString[] = {\r
+STATIC CHAR8 *gExceptionTypeString[] = {\r
   "Reset",\r
   "Undefined OpCode",\r
   "SWI",\r
@@ -220,7 +204,6 @@ CHAR8 *gExceptionTypeString[] = {
   "FIQ"\r
 };\r
 \r
-\r
 /**\r
   This is the default action to take on an unexpected exception\r
   \r
@@ -238,9 +221,11 @@ DefaultExceptionHandler (
   )\r
 {\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
+  Print(L"\n%a Exception PC at 0x%08x  CPSR 0x%08x ", gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR);\r
   DEBUG_CODE_BEGIN ();\r
     CHAR8   *Pdb;\r
     UINT32  ImageBase;\r
@@ -248,6 +233,8 @@ DefaultExceptionHandler (
     UINT32  Offset;\r
     CHAR8   CpsrStr[32];  // char per bit. Lower 5-bits are mode that is a 3 char string\r
     CHAR8   Buffer[80];\r
+    UINT8   *DisAsm;\r
+    UINT32  ItBlock;\r
     \r
     CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);\r
     DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));\r
@@ -259,24 +246,33 @@ DefaultExceptionHandler (
 \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
       \r
       // If we come from an image it is safe to show the instruction. We know it should not fault\r
-      if ((SystemContext.SystemContextArm->CPSR & 0x20) == 0) {\r
-        // ARM\r
-        DisassembleArmInstruction ((UINT32 *)(UINTN)SystemContext.SystemContextArm->PC, Buffer, sizeof (Buffer));\r
-        DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\r
-      } else {\r
-        // Thumb\r
-        DisassembleThumbInstruction ((UINT16 *)(UINTN)SystemContext.SystemContextArm->PC, Buffer, sizeof (Buffer));\r
-        DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\r
+      DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;\r
+      ItBlock = 0;\r
+      DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, TRUE, &ItBlock, Buffer, sizeof (Buffer));\r
+      DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\r
+      \r
+      switch (ExceptionType) {\r
+      case EXCEPT_ARM_UNDEFINED_INSTRUCTION:\r
+      case EXCEPT_ARM_SOFTWARE_INTERRUPT:\r
+      case EXCEPT_ARM_PREFETCH_ABORT:\r
+      case EXCEPT_ARM_DATA_ABORT:\r
+        // advance PC past the faulting instruction\r
+        PcAdjust = (UINTN)DisAsm - SystemContext.SystemContextArm->PC;\r
+        break;\r
+      \r
+      default:\r
+        break;\r
       }\r
+\r
     }\r
   DEBUG_CODE_END ();\r
   DEBUG ((EFI_D_ERROR, "\n  R0 0x%08x   R1 0x%08x   R2 0x%08x   R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));\r
@@ -291,12 +287,21 @@ DefaultExceptionHandler (
   if (DfsrStatus != 0x00) {\r
     DEBUG ((EFI_D_ERROR, " %a: %a 0x%08x\n", FaultStatusToString (DfsrStatus), DfsrWrite ? "write to" : "read from", SystemContext.SystemContextArm->DFAR));\r
   }\r
-  if ((SystemContext.SystemContextArm->IFSR & 0xf) != 0x00) {\r
-    DEBUG ((EFI_D_ERROR, "Instruction %a at 0x%08x, \n", FaultStatusToString (SystemContext.SystemContextArm->IFSR & 0xf), SystemContext.SystemContextArm->IFAR));\r
+\r
+  IfsrStatus = (SystemContext.SystemContextArm->IFSR & 0xf) | ((SystemContext.SystemContextArm->IFSR >> 6) & 0x10);\r
+  if (IfsrStatus != 0) {\r
+    DEBUG ((EFI_D_ERROR, " Instruction %a at 0x%08x\n", FaultStatusToString (SystemContext.SystemContextArm->IFSR & 0xf), SystemContext.SystemContextArm->IFAR));\r
   }\r
 \r
   DEBUG ((EFI_D_ERROR, "\n"));\r
   ASSERT (FALSE);\r
+  \r
+  // Clear the error registers that we have already displayed incase some one wants to keep going\r
+  SystemContext.SystemContextArm->DFSR = 0;\r
+  SystemContext.SystemContextArm->IFSR = 0;\r
+\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