Added a library for the default exception handler and started to add a dissasembler...
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 27 Jan 2010 02:47:47 +0000 (02:47 +0000)
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 27 Jan 2010 02:47:47 +0000 (02:47 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9830 6f19259b-4bc3-4df7-8a09-765794883524

22 files changed:
ArmPkg/ArmPkg.dec
ArmPkg/ArmPkg.dsc
ArmPkg/Drivers/CpuDxe/CpuDxe.c
ArmPkg/Drivers/CpuDxe/CpuDxe.h
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
ArmPkg/Drivers/CpuDxe/Exception.c
ArmPkg/Drivers/CpuDxe/ExceptionSupport.ARMv6.asm
ArmPkg/Drivers/CpuDxe/Mmu.c
ArmPkg/Include/Library/ArmLib.h
ArmPkg/Include/Library/DefaultExceptionHandlerLib.h [new file with mode: 0644]
ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c [new file with mode: 0644]
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c [new file with mode: 0644]
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf [new file with mode: 0644]
ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c [new file with mode: 0644]
BeagleBoardPkg/BeagleBoardPkg.dsc
BeagleBoardPkg/BeagleBoardPkg.fdf
BeagleBoardPkg/Flash/Flash.c
BeagleBoardPkg/Flash/Flash.h
BeagleBoardPkg/Library/EblCmdLib/EblCmdLib.c
BeagleBoardPkg/MMCHSDxe/MMCHS.c
BeagleBoardPkg/Sec/Arm/ModuleEntryPoint.asm
EmbeddedPkg/Ebl/EfiDevice.c

index 5509b4e..67c729d 100644 (file)
@@ -35,6 +35,7 @@
   ArmLib|Include/Library/ArmLib.h\r
   SemihostLib|Include/Library/Semihosting.h\r
   UncachedMemoryAllocationLib|Include/Library/UncachedMemoryAllocationLib.h\r
+  DefaultExceptioHandlerLib|Include/Library/DefaultExceptioHandlerLib.h\r
 \r
 [Guids.common]\r
   gArmTokenSpaceGuid       = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }\r
index 5925466..f28af29 100644 (file)
@@ -48,6 +48,7 @@
   SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
   UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
   DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  DefaultExceptioHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
 
   ArmLib|ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
   CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
@@ -83,7 +84,8 @@
   ArmPkg/Library/SemihostLib/SemihostLib.inf
   ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
   ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
-  ArmPkg/Library/RviPeCoffExtraActionLib/RviPeCoffExtraActionLib.inf
+  ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
+  ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
 
   ArmPkg/Drivers/CpuDxe/CpuDxe.inf
   ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf
index a4ac97c..b51867f 100644 (file)
@@ -53,7 +53,6 @@ CpuFlushCpuDataCache (
   IN EFI_CPU_FLUSH_TYPE              FlushType\r
   )\r
 {\r
-  DEBUG ((EFI_D_ERROR, "CpuFlushCpuDataCache (%lx, %lx, %x)\n", Start, Length, FlushType));\r
 \r
   switch (FlushType) {\r
     case EfiCpuFlushTypeWriteBack:\r
index 8a71075..c8cba81 100644 (file)
@@ -27,6 +27,7 @@
 #include <Library/PeCoffGetEntryPointLib.h>\r
 #include <Library/UefiLib.h>\r
 #include <Library/CpuLib.h>\r
+#include <Library/DefaultExceptionHandlerLib.h>\r
 \r
 #include <Guid/DebugImageInfoTable.h>\r
 #include <Protocol/Cpu.h>\r
index d4b4945..99d52f9 100644 (file)
@@ -41,6 +41,7 @@
 #  ExceptionSupport.ARMv6.S   | GCC\r
   Mmu.c\r
 \r
+\r
 [Packages]\r
   ArmPkg/ArmPkg.dec\r
   EmbeddedPkg/EmbeddedPkg.dec\r
@@ -55,6 +56,7 @@
   PeCoffGetEntryPointLib\r
   UefiLib\r
   CpuLib\r
+  DefaultExceptioHandlerLib\r
 \r
 [Protocols]\r
   gEfiCpuArchProtocolGuid\r
index d46971b..e313cf3 100644 (file)
@@ -14,7 +14,6 @@
 \r
 #include "CpuDxe.h" \r
 \r
-EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;\r
 \r
 VOID\r
 ExceptionHandlersStart (\r
@@ -123,125 +122,6 @@ RegisterDebuggerInterruptHandler (
 \r
 \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
-typedef struct {\r
-  UINT32  Bit;\r
-  CHAR8   Char;\r
-} CPSR_CHAR;\r
-\r
-\r
-VOID\r
-CpsrString (\r
-  IN  UINT32  Cpsr,\r
-  OUT CHAR8   *ReturnStr\r
-  )\r
-{\r
-  UINTN Index;\r
-  CHAR8 *Str = ReturnStr;\r
-  CHAR8 *ModeStr;\r
-  CPSR_CHAR CpsrChar[] = {\r
-    { 31, 'n' },\r
-    { 30, 'z' },\r
-    { 29, 'c' },\r
-    { 28, 'v' },\r
-\r
-    { 9,  'e' },\r
-    { 8,  'a' },\r
-    { 7,  'i' },\r
-    { 6,  'f' },\r
-    { 5,  't' },\r
-    { 0,  '?' }\r
-  };\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
-      // Concert to upper case if bit is set\r
-      *Str &= ~0x20;\r
-    }\r
-  }\r
-  \r
-  *Str++ = '_';\r
-  *Str = '\0';\r
-  \r
-  switch (Cpsr & 0x1f) {\r
-  case 0x17:\r
-    ModeStr = "abt";\r
-    break;\r
-  case 0x011:\r
-    ModeStr = "fiq";\r
-    break;\r
-  case 0x12:\r
-    ModeStr = "irq";\r
-    break;\r
-  case 0x13:\r
-    ModeStr = "svc";\r
-    break;\r
-  case 0x1f:\r
-    ModeStr = "sys";\r
-    break;\r
-  case 0x1b:\r
-    ModeStr = "und";\r
-    break;\r
-  case 0x10:\r
-    ModeStr = "usr";\r
-    break;\r
-  \r
-  default:\r
-    ModeStr = "???";\r
-    break;\r
-  }\r
-  \r
-  AsciiStrCat (Str, ModeStr);\r
-  return;\r
-}  \r
-  \r
-CHAR8 *gExceptionTypeString[] = {\r
-  "Reset",\r
-  "Undefined Instruction",\r
-  "SWI",\r
-  "Prefetch Abort",\r
-  "Data Abort",\r
-  "Undefined",\r
-  "IRQ",\r
-  "FIQ"\r
-};\r
-\r
 VOID\r
 EFIAPI\r
 CommonCExceptionHandler (\r
@@ -284,52 +164,7 @@ CommonCExceptionHandler (
     return;\r
   }\r
 \r
-  //\r
-  // Code after here is the default exception handler... Dump the context\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
-  DEBUG_CODE_BEGIN ();\r
-    CHAR8   *Pdb;\r
-    UINT32  ImageBase;\r
-    UINT32  PeCoffSizeOfHeader;\r
-    UINT32  Offset;\r
-    CHAR8   CpsrStr[32];  // char per bit. Lower 5-bits are mode that is a 3 char string\r
-    \r
-    CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);\r
-    DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));\r
-  \r
-    Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);\r
-    Offset = SystemContext.SystemContextArm->PC - ImageBase;\r
-    if (Pdb != NULL) {\r
-      DEBUG ((EFI_D_ERROR, "%a\n", Pdb));\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
-      // 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
-      // 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
-        DEBUG ((EFI_D_ERROR, "\nFaulting Instruction 0x%08x", *(UINT32 *)(UINTN)SystemContext.SystemContextArm->PC));\r
-      } else {\r
-        // Thumb\r
-        DEBUG ((EFI_D_ERROR, "\nFaulting Instruction 0x%04x", *(UINT16 *)(UINTN)SystemContext.SystemContextArm->PC));\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
-  DEBUG ((EFI_D_ERROR, "  R4 0x%08x   R5 0x%08x   R6 0x%08x   R7 0x%08x\n", SystemContext.SystemContextArm->R4, SystemContext.SystemContextArm->R5, SystemContext.SystemContextArm->R6, SystemContext.SystemContextArm->R7));\r
-  DEBUG ((EFI_D_ERROR, "  R8 0x%08x   R9 0x%08x  R10 0x%08x  R11 0x%08x\n", SystemContext.SystemContextArm->R8, SystemContext.SystemContextArm->R9, SystemContext.SystemContextArm->R10, SystemContext.SystemContextArm->R11));\r
-  DEBUG ((EFI_D_ERROR, " R12 0x%08x   SP 0x%08x   LR 0x%08x   PC 0x%08x\n", SystemContext.SystemContextArm->R12, SystemContext.SystemContextArm->SP, SystemContext.SystemContextArm->LR, SystemContext.SystemContextArm->PC));\r
-  DEBUG ((EFI_D_ERROR, "DFSR 0x%08x DFAR 0x%08x IFSR 0x%08x IFAR 0x%08x\n\n", SystemContext.SystemContextArm->DFSR, SystemContext.SystemContextArm->DFAR, SystemContext.SystemContextArm->IFSR, SystemContext.SystemContextArm->IFAR));\r
-\r
-  ASSERT (FALSE);\r
+  DefaultExceptionHandler (ExceptionType, SystemContext);\r
 }\r
 \r
 \r
@@ -346,11 +181,6 @@ InitializeExceptions (
   BOOLEAN              Enabled;\r
   EFI_PHYSICAL_ADDRESS Base;\r
 \r
-  Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);\r
-  if (EFI_ERROR (Status)) {\r
-    gDebugImageTableHeader = NULL;\r
-  }\r
-\r
   //\r
   // Disable interrupts\r
   //\r
index 6162e1b..7411762 100755 (executable)
@@ -101,6 +101,7 @@ ResetEntry
   bx        R1
 
 UndefinedInstructionEntry
+  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry
   srsfd     #0x13!                    ; Store return state on SVC stack
   cps       #0x13                     ; Switch to SVC for common stack
   stmfd     SP!,{LR}                  ; Store the link register for the current mode
@@ -112,6 +113,7 @@ UndefinedInstructionEntry
   bx        R1
 
 SoftwareInterruptEntry
+  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry
   srsfd     #0x13!                    ; Store return state on SVC stack
                                       ; We are already in SVC mode
   stmfd     SP!,{LR}                  ; Store the link register for the current mode
@@ -211,15 +213,26 @@ AsmCommonExceptionEntry
   str       R1, [SP, #0x40]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
 
   add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
-  and       R1, R1, #0x1f           ; Check CPSR to see if User or System Mode
-  cmp       R1, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1df))
-  cmpne     R1, #0x10               ;   
+  and       R3, R1, #0x1f           ; Check CPSR to see if User or System Mode
+  cmp       R3, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1df))
+  cmpne     R3, #0x10               ;   
   stmeqed   R2, {lr}^               ;   save unbanked lr
                                     ; else 
   stmneed   R2, {lr}                ;   save SVC lr
 
-  ldr       R1, [SP, #0x58]         ; PC is the LR pushed by srsfd 
-  str       R1, [SP, #0x3c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+
+  ldr       R5, [SP, #0x58]         ; PC is the LR pushed by srsfd 
+                                    ; Check to see if we have to adjust for Thumb entry
+  sub       r4, r0, #1              ; if (ExceptionType == 1 || ExceptionType ==2)) {
+  cmp       r4, #1                  ;   // UND & SVC have differnt LR adjust for Thumb 
+  bhi       NoAdjustNeeded
+  
+  tst       r1, #0x20               ;   if ((CPSR & T)) == T) {  // Thumb Mode on entry 
+  addne     R5, R5, #2              ;     PC += 2;
+  
+NoAdjustNeeded
+
+  str       R5, [SP, #0x3c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
   
   sub       R1, SP, #0x60           ; We pused 0x60 bytes on the stack 
   str       R1, [SP, #0x34]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
@@ -228,12 +241,13 @@ AsmCommonExceptionEntry
   mov       R1,SP                   ; R1 is SystemContext 
 
 /* 
-VOID\r
-EFIAPI\r
-CommonCExceptionHandler (\r
-  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0\r
-  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1\r
-  )\r
+VOID
+EFIAPI
+CommonCExceptionHandler (
+  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0
+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1
+  )
+
 */
   blx       CommonCExceptionHandler ; Call exception handler
   
index f2669fc..e81e58a 100644 (file)
@@ -848,13 +848,15 @@ CpuConvertPagesToUncachedVirtualAddress (
     Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);\r
   }\r
 \r
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "ConvertPagesToUncachedVirtualAddress()\n    Unmapped 0x%08lx Mapped 0x%08lx 0x%x bytes\n", Address, Address | VirtualMask, Length));\r
+\r
   return Status;\r
 }\r
 \r
 \r
 EFI_STATUS\r
 EFIAPI\r
-CpuReconvertPagesPages (\r
+CpuReconvertPages (\r
   IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL   *This,\r
   IN  EFI_PHYSICAL_ADDRESS              Address,\r
   IN  UINTN                             Length,\r
@@ -863,9 +865,10 @@ CpuReconvertPagesPages (
   )\r
 {\r
   EFI_STATUS      Status;\r
-DEBUG ((EFI_D_ERROR, "CpuReconvertPagesPages(%lx, %x, %lx, %lx)\n", Address, Length, VirtualMask, Attributes));\r
-ASSERT (FALSE);\r
-//\r
+\r
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuReconvertPages(%lx, %x, %lx, %lx)\n", Address, Length, VirtualMask, Attributes));\r
+  \r
+  //\r
   // Unmap the alaised Address\r
   //\r
   Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_WP, 0);\r
@@ -882,7 +885,7 @@ ASSERT (FALSE);
 \r
 VIRTUAL_UNCACHED_PAGES_PROTOCOL  gVirtualUncachedPages = {\r
   CpuConvertPagesToUncachedVirtualAddress,\r
-  CpuReconvertPagesPages\r
+  CpuReconvertPages\r
 };\r
 \r
 \r
index 371075b..da28c34 100644 (file)
@@ -248,6 +248,12 @@ ArmInvalidateTlb (
   VOID
   );
   
+VOID
+EFIAPI
+ArmUpdateTranslationTableEntry (
+  IN  UINTN    Mva
+  );
+  
 VOID
 EFIAPI
 ArmSetDomainAccessControl (
diff --git a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h
new file mode 100644 (file)
index 0000000..58c6cfc
--- /dev/null
@@ -0,0 +1,31 @@
+/** @file
+
+  Copyright (c) 2008-2010 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DEFAULT_EXCEPTION_HANDLER_LIB_H__
+#define __DEFAULT_EXCEPTION_HANDLER_LIB_H__
+
+/**
+  This is the default action to take on an unexpected exception
+
+  @param  ExceptionType    Type of the exception
+  @param  SystemContext    Register state at the time of the Exception
+
+**/
+VOID
+DefaultExceptionHandler (
+  IN     EFI_EXCEPTION_TYPE           ExceptionType,
+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext
+  );
+  
+#endif 
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c
new file mode 100644 (file)
index 0000000..034236b
--- /dev/null
@@ -0,0 +1,442 @@
+/** @file\r
+  Default exception handler\r
+\r
+  Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
+  \r
+  All rights reserved. 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
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+\r
+CHAR8 *gCondition[] = {\r
+  "EQ",\r
+  "NE",\r
+  "CS",\r
+  "CC",\r
+  "MI",\r
+  "PL",\r
+  "VS",\r
+  "VC",\r
+  "HI",\r
+  "LS",\r
+  "GE",\r
+  "LT",\r
+  "GT",\r
+  "LE",\r
+  "",\r
+  "2"\r
+};\r
+\r
+#define COND(_a)  gCondition[(_a) >> 28]\r
+\r
+CHAR8 *gReg[] = {\r
+  "r0",\r
+  "r1",\r
+  "r2",\r
+  "r3",\r
+  "r4",\r
+  "r5",\r
+  "r6",\r
+  "r7",\r
+  "r8",\r
+  "r9",\r
+  "r10",\r
+  "r11",\r
+  "r12",\r
+  "sp",\r
+  "lr",\r
+  "pc"\r
+};\r
+\r
+CHAR8 *gLdmAdr[] = {\r
+  "DA",\r
+  "IA",\r
+  "DB",\r
+  "IB"\r
+};\r
+\r
+CHAR8 *gLdmStack[] = {\r
+  "FA",\r
+  "FD",\r
+  "EA",\r
+  "ED"\r
+};\r
+\r
+#define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])\r
+\r
+\r
+#define SIGN(_U)  ((_U) ? "" : "-")\r
+#define WRITE(_W) ((_W) ? "!" : "")\r
+#define BYTE(_B)  ((_B) ? "B":"")\r
+#define USER(_B)  ((_B) ? "^" : "")\r
+\r
+CHAR8 mMregListStr[4*15 + 1];\r
+\r
+CHAR8 *\r
+MRegList (\r
+  UINT32  OpCode\r
+  )\r
+{\r
+  UINTN     Index, Start, End;\r
+  CHAR8     *Str;\r
+  BOOLEAN   First;\r
\r
+  Str = mMregListStr;\r
+  *Str = '\0';\r
+  AsciiStrCat  (Str, "{");\r
+  for (Index = 0, First = TRUE; Index <= 15; Index++) {\r
+    if ((OpCode & (1 << Index)) != 0) {\r
+      Start = End = Index;\r
+      for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {\r
+        End = Index;\r
+      }\r
+      \r
+      if (!First) {\r
+        AsciiStrCat  (Str, ",");\r
+      } else {\r
+        First = FALSE;\r
+      }\r
+      \r
+      if (Start == End) {\r
+        AsciiStrCat  (Str, gReg[Start]);\r
+        AsciiStrCat  (Str, ", ");\r
+      } else {\r
+        AsciiStrCat  (Str, gReg[Start]);\r
+        AsciiStrCat  (Str, "-");\r
+        AsciiStrCat  (Str, gReg[End]);\r
+      }\r
+    }\r
+  }\r
+  if (First) {\r
+    AsciiStrCat  (Str, "ERROR");\r
+  }\r
+  AsciiStrCat  (Str, "}");\r
+  \r
+  // BugBug: Make caller pass in buffer it is cleaner\r
+  return mMregListStr;\r
+}\r
+\r
+CHAR8 *\r
+FieldMask (\r
+  IN  UINT32  Mask\r
+  )\r
+{\r
+  return "";\r
+}\r
+\r
+UINT32\r
+RotateRight (\r
+  IN UINT32 Op,\r
+  IN UINT32 Shift\r
+  )\r
+{\r
+  return (Op >> Shift) | (Op << (32 - Shift));\r
+}\r
+\r
+\r
+/**\r
+  DEBUG print the faulting instruction. We cheat and only decode instructions that access \r
+  memory. If the instruction is not found we dump the instruction in hex.\r
+   \r
+  @param  Insturction   ARM instruction to disassemble.  \r
+  \r
+**/\r
+VOID\r
+DisassembleArmInstruction (\r
+  IN  UINT32    *OpCodePtr,\r
+  OUT CHAR8     *Buf,\r
+  OUT UINTN     Size\r
+  )\r
+{\r
+  UINT32    OpCode = *OpCodePtr;\r
+  CHAR8     *Type, *Root;\r
+  BOOLEAN   I, P, U, B, W, L, S, H;\r
+  UINT32    Rn, Rd, Rm;\r
+  UINT32    imode, offset_8, offset_12;\r
+  UINT32    Index;\r
+  UINT32    shift_imm, shift;\r
+\r
+  I = (OpCode & BIT25) == BIT25;\r
+  P = (OpCode & BIT24) == BIT24;\r
+  U = (OpCode & BIT23) == BIT23;\r
+  B = (OpCode & BIT22) == BIT22;  // Also called S\r
+  W = (OpCode & BIT21) == BIT21;  \r
+  L = (OpCode & BIT20) == BIT20;\r
+  S = (OpCode & BIT6) == BIT6;\r
+  H = (OpCode & BIT5) == BIT5;\r
+  Rn = (OpCode >> 16) & 0xf;\r
+  Rd = (OpCode >> 12) & 0xf;\r
+  Rm = (OpCode & 0xf);\r
+\r
+  // LDREX, STREX\r
+  if ((OpCode  & 0x0fe000f0) == 0x01800090) {\r
+    if (L) {\r
+      // A4.1.27  LDREX{<cond>} <Rd>, [<Rn>] \r
+      AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]);   \r
+    } else {\r
+     // A4.1.103  STREX{<cond>} <Rd>, <Rm>, [<Rn>]\r
+      AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]);   \r
+    } \r
+    return;\r
+  }\r
+  \r
+  // LDM/STM\r
+  if ((OpCode  & 0x0e000000) == 0x08000000) {\r
+    if (L) {\r
+      // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>\r
+      // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^\r
+      // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^\r
+      AsciiSPrint (Buf, Size, "LDM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (W), MRegList (OpCode), USER (B));   \r
+    } else {\r
+      // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>\r
+      // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^\r
+      AsciiSPrint (Buf, Size, "STM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (W), MRegList (OpCode), USER (B));   \r
+    }   \r
+    return;\r
+  }\r
+\r
+  // LDR/STR Address Mode 2\r
+  if ( ((OpCode  & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000 ) == 0xf550f000) ) {\r
+    offset_12 = OpCode & 0xfff;\r
+    if ((OpCode & 0xfd70f000 ) == 0xf550f000) {\r
+      Index = AsciiSPrint (Buf, Size, "PLD");\r
+    } else {\r
+      Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", L ? "LDR" : "STR", COND (OpCode), BYTE (B), (!P & W) ? "T":"", gReg[Rd]); \r
+    }\r
+    if (P) {\r
+      if (!I) {\r
+        // A5.2.2 [<Rn>, #+/-<offset_12>]\r
+        // A5.2.5 [<Rn>, #+/-<offset_12>]\r
+        AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x]%a", gReg[Rn], SIGN (U), offset_12, WRITE (W));\r
+      } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r
+        // A5.2.3 [<Rn>, +/-<Rm>]\r
+        // A5.2.6 [<Rn>, +/-<Rm>]!\r
+        AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a]%a", gReg[Rn], SIGN (U), WRITE (W));\r
+      } else {\r
+        // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]\r
+        // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!\r
+        shift_imm = (OpCode >> 7) & 0x1f;\r
+        shift = (OpCode >> 5) & 0x3;\r
+        if (shift == 0x0) {\r
+          Type = "LSL";\r
+        } else if (shift == 0x1) {\r
+          Type = "LSR";\r
+          if (shift_imm == 0) {\r
+            shift_imm = 32;\r
+          }\r
+        } else if (shift == 0x12) {\r
+          Type = "ASR";\r
+        } else if (shift_imm == 0) {\r
+          AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));\r
+          return;\r
+        } else {\r
+          Type = "ROR";\r
+        }\r
+          \r
+        AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm, WRITE (W));\r
+      }\r
+    } else {  // !P\r
+      if (!I) {\r
+        // A5.2.8  [<Rn>], #+/-<offset_12>\r
+        AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (U), offset_12);\r
+      } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r
+        // A5.2.9  [<Rn>], +/-<Rm>\r
+        AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);\r
+      } else {\r
+        // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>\r
+        shift_imm = (OpCode >> 7) & 0x1f;\r
+        shift = (OpCode >> 5) & 0x3;\r
+\r
+        if (shift == 0x0) {\r
+          Type = "LSL";\r
+        } else if (shift == 0x1) {\r
+          Type = "LSR";\r
+          if (shift_imm == 0) {\r
+            shift_imm = 32;\r
+          }\r
+        } else if (shift == 0x12) {\r
+          Type = "ASR";\r
+        } else if (shift_imm == 0) {\r
+          AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (U), gReg[Rm]);\r
+          // FIx me\r
+          return;\r
+        } else {\r
+          Type = "ROR";\r
+        }\r
+          \r
+        AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm);\r
+      }\r
+    }\r
+    return;  \r
+  }\r
+  \r
+  if ((OpCode  & 0x0e000000) == 0x00000000) {\r
+    // LDR/STR address mode 3\r
+    // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>\r
+    if (L) {\r
+      if (!S) {\r
+        Root = "LDR%aH %a, ";\r
+      } else if (!H) {\r
+        Root = "LDR%aSB %a, ";\r
+      } else {\r
+        Root = "LDR%aSH %a, ";\r
+      }\r
+    } else {\r
+      if (!S) {\r
+        Root = "STR%aH %a ";\r
+      } else if (!H) {\r
+        Root = "LDR%aD %a ";\r
+      } else {\r
+        Root = "STR%aD %a ";\r
+      }\r
+    }\r
+  \r
+    Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]); \r
+\r
+    S = (OpCode & BIT6) == BIT6;\r
+    H = (OpCode & BIT5) == BIT5;\r
+    offset_8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;\r
+    if (P & !W) {\r
+      // Immediate offset/index\r
+      if (B) {\r
+        // A5.3.2  [<Rn>, #+/-<offset_8>]\r
+        // A5.3.4  [<Rn>, #+/-<offset_8>]!\r
+        AsciiSPrint  (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (U), offset_8, WRITE (W));\r
+      } else {\r
+        // A5.3.3  [<Rn>, +/-<Rm>]\r
+        // A5.3.5  [<Rn>, +/-<Rm>]!\r
+        AsciiSPrint  (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));\r
+      }\r
+    } else {\r
+      // Register offset/index\r
+      if (B) {\r
+        // A5.3.6 [<Rn>], #+/-<offset_8>\r
+        AsciiSPrint  (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (U), offset_8);\r
+      } else {\r
+        // A5.3.7 [<Rn>], +/-<Rm>\r
+        AsciiSPrint  (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);\r
+      }\r
+    }\r
+    return;\r
+  }\r
+\r
+  if ((OpCode  & 0x0fb000f0) == 0x01000050) {\r
+    // A4.1.108  SWP   SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r
+    // A4.1.109  SWPB  SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r
+    AsciiSPrint (Buf, Size, "SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (B), gReg[Rd], gReg[Rm], gReg[Rn]);\r
+    return;\r
+  }\r
+  \r
+  if ((OpCode  & 0xfe5f0f00) == 0xf84d0500) {\r
+    // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}\r
+    AsciiSPrint (Buf, Size, "SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (W));\r
+    return;\r
+  }\r
+\r
+  if ((OpCode  & 0xfe500f00) == 0xf8100500) {\r
+    // A4.1.59 RFE<addressing_mode> <Rn>{!}\r
+    AsciiSPrint (Buf, Size, "RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (W));\r
+    return;\r
+  }\r
+  \r
+  if ((OpCode  & 0xfff000f0) == 0xe1200070) {\r
+    // A4.1.7 BKPT <immed_16>\r
+    AsciiSPrint (Buf, Size, "BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);\r
+    return;\r
+  }  \r
+  \r
+  if ((OpCode  & 0xfff10020) == 0xf1000000) {\r
+    // A4.1.16 CPS<effect> <iflags> {, #<mode>}\r
+    if (((OpCode >> 6) & 0x7) == 0) {\r
+      AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));\r
+    } else {\r
+      imode = (OpCode >> 18) & 0x3;\r
+      Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a", (imode == 3) ? "ID":"IE", (OpCode & BIT8) ? "A":"", (OpCode & BIT7) ? "I":"", (OpCode & BIT6) ? "F":"");\r
+      if ((OpCode & BIT17) != 0) {\r
+        AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);\r
+      }\r
+    }\r
+    return;\r
+  }  \r
+    \r
+  if ((OpCode  & 0x0f000000) == 0x0f000000) {\r
+    // A4.1.107 SWI{<cond>} <immed_24>\r
+    AsciiSPrint (Buf, Size, "SWI%a %x", COND (OpCode), OpCode & 0x00ffffff);\r
+    return;\r
+  }  \r
+\r
+  if ((OpCode  & 0x0fb00000) == 0x01000000) {\r
+    // A4.1.38 MRS{<cond>} <Rd>, CPSR  MRS{<cond>} <Rd>, SPSR\r
+    AsciiSPrint (Buf, Size, "MRS%a %a, %a", COND (OpCode), gReg[Rd], B ? "SPSR" : "CPSR");\r
+    return;\r
+  }  \r
+\r
+\r
+  if ((OpCode  & 0x0db00000) == 0x03200000) {\r
+    // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>\r
+    if (I) {\r
+      // MSR{<cond>} CPSR_<fields>, #<immediate>\r
+      AsciiSPrint (Buf, Size, "MRS%a %a_%a, #0x%x", COND (OpCode),  B ? "SPSR" : "CPSR", FieldMask ((OpCode >> 16) & 0xf), RotateRight (OpCode & 0xf, ((OpCode >> 8) & 0xf) *2));\r
+    } else {\r
+      // MSR{<cond>} CPSR_<fields>, <Rm>\r
+      AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), B ? "SPSR" : "CPSR", gReg[Rd]);\r
+    }\r
+    return;\r
+  }  \r
+\r
+  if ((OpCode  & 0xff000010) == 0xfe000000) {\r
+    // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>\r
+    AsciiSPrint (Buf, Size, "CDP%a 0x%x, 0x%x, CR%d, CR%d, CR%d, 0x%x", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, Rn, Rd, Rm, (OpCode >> 5) &0x7);\r
+    return;\r
+  }\r
+  \r
+  if ((OpCode  & 0x0e000000) == 0x0c000000) {\r
+    // A4.1.19 LDC and A4.1.96 SDC\r
+    if ((OpCode & 0xf0000000) == 0xf0000000) {\r
+      Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", L ? "LDC":"SDC", (OpCode >> 8) & 0xf, Rd);\r
+    } else {\r
+      Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ",  L ? "LDC":"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);\r
+    }\r
+    \r
+    if (!P) {\r
+      if (!W) { \r
+        // A5.5.5.5 [<Rn>], <option>\r
+      AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff); \r
+      } else {\r
+        // A.5.5.4  [<Rn>], #+/-<offset_8>*4\r
+      AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (U), OpCode & 0xff); \r
+      }\r
+    } else {\r
+      // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!\r
+      AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (U), OpCode & 0xff, WRITE (W)); \r
+    }\r
+    \r
+  }\r
+  \r
+  if ((OpCode  & 0x0f000010) == 0x0e000010) {\r
+    // A4.1.32 MRC2, MCR2 \r
+    AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, CR%d, CR%d, 0x%x", L ? "MRC":"MCR", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], Rn, Rm, (OpCode >> 5) &0x7);\r
+    return;    \r
+  }\r
+\r
+  if ((OpCode  & 0x0ff00000) == 0x0c400000) {\r
+    // A4.1.33 MRRC2, MCRR2 \r
+    AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, %a, CR%d", L ? "MRRC":"MCRR", COND (OpCode), (OpCode >> 4) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], gReg[Rn], Rm);\r
+    return;    \r
+  }\r
+\r
+  AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);\r
+  return;\r
+}\r
+\r
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c
new file mode 100644 (file)
index 0000000..5650494
--- /dev/null
@@ -0,0 +1,286 @@
+/** @file\r
+  Default exception handler\r
+\r
+  Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
+  \r
+  All rights reserved. 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
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\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
+\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
+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
+  Convert the Current Program Status Register (CPSR) to a string. The string is \r
+  a defacto standard in the ARM world. \r
+  \r
+  It is possible to add extra bits by adding them to CpsrChar array.\r
+\r
+  @param  Cpsr         ARM CPSR register value\r
+  @param  ReturnStr    32 byte string that contains string version of CPSR\r
+\r
+**/\r
+VOID\r
+CpsrString (\r
+  IN  UINT32  Cpsr,\r
+  OUT CHAR8   *ReturnStr\r
+  )\r
+{\r
+  UINTN Index;\r
+  CHAR8 *Str = ReturnStr;\r
+  CHAR8 *ModeStr;\r
+  CPSR_CHAR CpsrChar[] = {\r
+    { 31, 'n' },\r
+    { 30, 'z' },\r
+    { 29, 'c' },\r
+    { 28, 'v' },\r
+\r
+    { 9,  'e' },\r
+    { 8,  'a' },\r
+    { 7,  'i' },\r
+    { 6,  'f' },\r
+    { 5,  't' },\r
+    { 0,  '?' }\r
+  };\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
+      // Concert to upper case if bit is set\r
+      *Str &= ~0x20;\r
+    }\r
+  }\r
+  \r
+  *Str++ = '_';\r
+  *Str = '\0';\r
+  \r
+  switch (Cpsr & 0x1f) {\r
+  case 0x10:\r
+    ModeStr = "usr";\r
+    break;\r
+  case 0x011:\r
+    ModeStr = "fiq";\r
+    break;\r
+  case 0x12:\r
+    ModeStr = "irq";\r
+    break;\r
+  case 0x13:\r
+    ModeStr = "svc";\r
+    break;\r
+  case 0x16:\r
+    ModeStr = "mon";\r
+    break;\r
+  case 0x17:\r
+    ModeStr = "abt";\r
+    break;\r
+  case 0x1b:\r
+    ModeStr = "und";\r
+    break;\r
+  case 0x1f:\r
+    ModeStr = "sys";\r
+    break;\r
+  \r
+  default:\r
+    ModeStr = "???";\r
+    break;\r
+  }\r
+  \r
+  AsciiStrCat (Str, ModeStr);\r
+  return;\r
+}  \r
+  \r
+CHAR8 *gExceptionTypeString[] = {\r
+  "Reset",\r
+  "Undefined OpCode",\r
+  "SWI",\r
+  "Prefetch Abort",\r
+  "Data Abort",\r
+  "Undefined",\r
+  "IRQ",\r
+  "FIQ"\r
+};\r
+\r
+\r
+/**\r
+  This is the default action to take on an unexpected exception\r
+  \r
+  Since this is exception context don't do anything crazy like try to allcoate memory.\r
+\r
+  @param  ExceptionType    Type of the exception\r
+  @param  SystemContext    Register state at the time of the Exception\r
+\r
+\r
+**/\r
+VOID\r
+DefaultExceptionHandler (\r
+  IN     EFI_EXCEPTION_TYPE           ExceptionType,\r
+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext\r
+  )\r
+{\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
+  DEBUG_CODE_BEGIN ();\r
+    CHAR8   *Pdb;\r
+    UINT32  ImageBase;\r
+    UINT32  PeCoffSizeOfHeader;\r
+    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
+    \r
+    CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);\r
+    DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));\r
+  \r
+    Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);\r
+    Offset = SystemContext.SystemContextArm->PC - ImageBase;\r
+    if (Pdb != NULL) {\r
+      DEBUG ((EFI_D_ERROR, "%a\n", Pdb));\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
+      // 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
+      // 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
+        DEBUG ((EFI_D_ERROR, "\nFaulting Instruction 0x%04x", (UINT16 *)(UINTN)SystemContext.SystemContextArm->PC));\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
+  DEBUG ((EFI_D_ERROR, "  R4 0x%08x   R5 0x%08x   R6 0x%08x   R7 0x%08x\n", SystemContext.SystemContextArm->R4, SystemContext.SystemContextArm->R5, SystemContext.SystemContextArm->R6, SystemContext.SystemContextArm->R7));\r
+  DEBUG ((EFI_D_ERROR, "  R8 0x%08x   R9 0x%08x  R10 0x%08x  R11 0x%08x\n", SystemContext.SystemContextArm->R8, SystemContext.SystemContextArm->R9, SystemContext.SystemContextArm->R10, SystemContext.SystemContextArm->R11));\r
+  DEBUG ((EFI_D_ERROR, " R12 0x%08x   SP 0x%08x   LR 0x%08x   PC 0x%08x\n", SystemContext.SystemContextArm->R12, SystemContext.SystemContextArm->SP, SystemContext.SystemContextArm->LR, SystemContext.SystemContextArm->PC));\r
+  DEBUG ((EFI_D_ERROR, "DFSR 0x%08x DFAR 0x%08x IFSR 0x%08x IFAR 0x%08x\n\n", SystemContext.SystemContextArm->DFSR, SystemContext.SystemContextArm->DFAR, SystemContext.SystemContextArm->IFSR, SystemContext.SystemContextArm->IFAR));\r
+\r
+  ASSERT (FALSE);\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
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
new file mode 100644 (file)
index 0000000..a989895
--- /dev/null
@@ -0,0 +1,42 @@
+#/** @file\r
+# Semihosting  serail port lib\r
+#\r
+# Copyright (c) 2008, Apple Inc.\r
+#\r
+#  All rights reserved. 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
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SemiHostingSerialPortLib\r
+  FILE_GUID                      = EACDB354-DF1A-4AF9-A171-499737ED818F\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = DefaultExceptionHandlerLib\r
+  CONSTRUCTOR                    = DefaultExceptionHandlerConstructor\r
+\r
+\r
+[Sources.common]\r
+  DefaultExceptionHandler.c\r
+  ArmDisassembler.c\r
+  ThumbDisassembler.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ArmPkg/ArmPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiLib\r
+  BaseLib\r
+  PrintLib\r
+  DebugLib\r
+  PeCoffGetEntryPointLib\r
+\r
+\r
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c
new file mode 100644 (file)
index 0000000..b021e78
--- /dev/null
@@ -0,0 +1,399 @@
+/** @file\r
+  Default exception handler\r
+\r
+  Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
+  \r
+  All rights reserved. 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
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+extern CHAR8 *gReg[];\r
+\r
+#define LOAD_STORE_FORMAT1            1\r
+#define LOAD_STORE_FORMAT2            2\r
+#define LOAD_STORE_FORMAT3            3\r
+#define LOAD_STORE_FORMAT4            4\r
+#define LOAD_STORE_MULTIPLE_FORMAT1   5 \r
+#define LOAD_STORE_MULTIPLE_FORMAT2   6 \r
+#define IMMED_8                       7\r
+#define CONDITIONAL_BRANCH            8\r
+#define UNCONDITIONAL_BRANCH          9\r
+#define UNCONDITIONAL_BRANCH_SHORT  109\r
+#define BRANCH_EXCHANGE              10\r
+#define DATA_FORMAT1                 11\r
+#define DATA_FORMAT2                 12\r
+#define DATA_FORMAT3                 13\r
+#define DATA_FORMAT4                 14\r
+#define DATA_FORMAT5                 15\r
+#define DATA_FORMAT6_SP              16\r
+#define DATA_FORMAT6_PC             116\r
+#define DATA_FORMAT7                 17\r
+#define DATA_FORMAT8                 19\r
+#define CPS_FORMAT                   20\r
+#define ENDIAN_FORMAT                21\r
+     \r
+\r
+typedef struct {\r
+  CHAR8   *Start;\r
+  UINT32  OpCode;\r
+  UINT32  Mask;\r
+  UINT32  AddressMode;\r
+} THUMB_INSTRUCTIONS;\r
+\r
+THUMB_INSTRUCTIONS gOp[] = {\r
+// Thumb 16-bit instrucitons\r
+//         Op      Mask    Format\r
+  { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },\r
+\r
+  { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 },\r
+  { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 },\r
+  { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 },\r
+  { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 },   // A8.6.9\r
+  { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC },\r
+  { "ADD" , 0xa100, 0xf100, DATA_FORMAT6_SP }, \r
+  { "ADD" , 0xb000, 0xff10, DATA_FORMAT7 },\r
+\r
+  { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 },\r
+\r
+  { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 },\r
+  { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 },\r
+\r
+  { "B"   , 0xd000, 0xf000, CONDITIONAL_BRANCH },\r
+  { "B"   , 0xe000, 0xf100, UNCONDITIONAL_BRANCH_SHORT },\r
+  { "BL"  , 0xf100, 0xf100, UNCONDITIONAL_BRANCH },\r
+  { "BLX" , 0xe100, 0xf100, UNCONDITIONAL_BRANCH },\r
+  { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE },\r
+  { "BX"  , 0x4700, 0xff80, BRANCH_EXCHANGE },\r
+\r
+  { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 },\r
+  { "BKPT", 0xdf00, 0xff00, IMMED_8 },\r
+  { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 },\r
+\r
+  { "CMP" , 0x2800, 0xf100, DATA_FORMAT3 },\r
+  { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 },\r
+  { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 },\r
+\r
+  { "CPS" , 0xb660, 0xffe8, CPS_FORMAT },\r
+  { "CPY" , 0x4600, 0xff00, DATA_FORMAT8 },\r
+  { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 },\r
+\r
+  { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
+  { "LDR"   , 0x6800, 0xf800, LOAD_STORE_FORMAT1 },\r
+  { "LDR"   , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "LDR"   , 0x4800, 0xf800, LOAD_STORE_FORMAT3 },\r
+  { "LDR"   , 0x9800, 0xf800, LOAD_STORE_FORMAT4 },\r
+  { "LDRB"  , 0x7800, 0xf800, LOAD_STORE_FORMAT1 },\r
+  { "LDRB"  , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "LDRH"  , 0x8800, 0xf800, LOAD_STORE_FORMAT1 },\r
+  { "LDRH"  , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 },\r
\r
+  { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 },\r
+  { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 },\r
+  { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 },\r
+  { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 },\r
+\r
+  { "MOV" , 0x2000, 0xf800, DATA_FORMAT3 },\r
+  { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 },\r
+  { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },\r
+\r
+  { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 },\r
+  { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
+  { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 },\r
+  { "ORR" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
+  { "POP" , 0xbc00, 0xfe00, LOAD_STORE_MULTIPLE_FORMAT2 },\r
+  { "POP" , 0xe400, 0xfe00, LOAD_STORE_MULTIPLE_FORMAT2 },\r
+  \r
+  { "REV"   , 0xba00, 0xffc0, DATA_FORMAT5 },\r
+  { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 },\r
+  { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 },\r
+\r
+  { "ROR"  , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
+  { "SBC"  , 0x4180, 0xffc0, DATA_FORMAT5 },\r
+  { "SETEND"  , 0xb650, 0xfff0, ENDIAN_FORMAT },\r
+\r
+  { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
+  { "STR"   , 0x6000, 0xf800, LOAD_STORE_FORMAT1 },\r
+  { "STR"   , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "STR"   , 0x4000, 0xf800, LOAD_STORE_FORMAT3 },\r
+  { "STR"   , 0x9000, 0xf800, LOAD_STORE_FORMAT4 },\r
+  { "STRB"  , 0x7000, 0xf800, LOAD_STORE_FORMAT1 },\r
+  { "STRB"  , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "STRH"  , 0x8000, 0xf800, LOAD_STORE_FORMAT1 },\r
+  { "STRH"  , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 },\r
+\r
+  { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 },\r
+  { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 },\r
+  { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 },\r
+  { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 },\r
+\r
+  { "SWI" , 0xdf00, 0xff00, IMMED_8 },\r
+  { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 },\r
+  { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 },\r
+  { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },\r
+  { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },\r
+  { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }\r
+  \r
+#if 0  \r
+  ,\r
+  \r
+  // 32-bit Thumb instructions  op1 01\r
+  \r
+  //  1110 100x x0xx xxxx xxxx xxxx xxxx xxxx Load/store multiple\r
+  { "SRSDB", 0xe80dc000, 0xffdffff0, SRS_FORMAT },       // SRSDB<c> SP{!},#<mode>\r
+  { "SRS"  , 0xe98dc000, 0xffdffff0, SRS_IA_FORMAT },    // SRS{IA}<c> SP{!},#<mode>\r
+  { "RFEDB", 0xe810c000, 0xffd0ffff, RFE_FORMAT },       // RFEDB<c> <Rn>{!}\r
+  { "RFE"  , 0xe990c000, 0xffd0ffff, RFE_IA_FORMAT },    // RFE{IA}<c> <Rn>{!}\r
+  \r
+  { "STM"  , 0xe8800000, 0xffd00000,  STM_FORMAT },      // STM<c>.W <Rn>{!},<registers>\r
+  { "LDM"  , 0xe8900000, 0xffd00000,  STM_FORMAT },      // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]\r
+  { "POP"  , 0xe8bd0000, 0xffff2000,  REGLIST_FORMAT },  // POP<c>.W <registers> >1 register\r
+  { "POP"  , 0xf85d0b04, 0xffff0fff,  RT_FORMAT },       // POP<c>.W <registers>  1 register\r
+\r
+  { "STMDB", 0xe9000000, 0xffd00000,  STM_FORMAT },      // STMDB\r
+  { "PUSH" , 0xe8bd0000, 0xffffa000,  REGLIST_FORMAT },  // PUSH<c>.W <registers>  >1 register\r
+  { "PUSH" , 0xf84d0b04, 0xffff0fff,  RT_FORMAT },       // PUSH<c>.W <registers>   1 register\r
+  { "LDMDB", 0xe9102000, 0xffd02000,  STM_FORMAT },      // LDMDB<c> <Rn>{!},<registers>\r
+\r
+  //  1110 100x x1xx xxxx xxxx xxxx xxxx xxxx Load/store dual,\r
+  { "STREX" , 0xe0400000, 0xfff000f0, 3REG_IMM8_FORMAT },  // STREX<c> <Rd>,<Rt>,[<Rn>{,#<imm>}]\r
+  { "STREXB", 0xe8c00f40, 0xfff00ff0, 3REG_FORMAT },       // STREXB<c> <Rd>,<Rt>,[<Rn>]\r
+  { "STREXD", 0xe8c00070, 0xfff000f0, 4REG_FORMAT },       // STREXD<c> <Rd>,<Rt>,<Rt2>,[<Rn>]\r
+  { "STREXH", 0xe8c00f70, 0xfff00ff0, 3REG_FORMAT },       // STREXH<c> <Rd>,<Rt>,[<Rn>]\r
+  { "STRH",   0xf8c00000, 0xfff00000, 2REG_IMM8_FORMAT },  // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]\r
+  { "STRH",   0xf8200000, 0xfff00000,  },                  // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]\r
+\r
+\r
+\r
+  //  1110 101x xxxx xxxx xxxx xxxx xxxx xxxx Data-processing\r
+  //  1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor\r
+  \r
+  //  1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx Data-processing modified immediate\r
+  //  1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx Data-processing plain immediate\r
+  //  1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx Branches\r
+  \r
+  //  1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx Store single data item\r
+  //  1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx SIMD or load/store\r
+  //  1111 100x x001 xxxx xxxx xxxx xxxx xxxx Load byte, memory hints \r
+  //  1111 100x x011 xxxx xxxx xxxx xxxx xxxx Load halfword, memory hints\r
+  //  1111 100x x101 xxxx xxxx xxxx xxxx xxxx Load word \r
+\r
+  //  1111 1 010 xxxx xxxx xxxx xxxx xxxx xxxx Data-processing register\r
+  //  1111 1 011 0xxx xxxx xxxx xxxx xxxx xxxx Multiply\r
+  //  1111 1 011 1xxx xxxx xxxx xxxx xxxx xxxx Long Multiply\r
+  //  1111 1 1xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor \r
+#endif\r
+};\r
+\r
+\r
+CHAR8 mThumbMregListStr[4*15 + 1];\r
+\r
+CHAR8 *\r
+ThumbMRegList (\r
+  UINT32  OpCode\r
+  )\r
+{\r
+  UINTN     Index, Start, End;\r
+  CHAR8     *Str;\r
+  BOOLEAN   First;\r
\r
+  Str = mThumbMregListStr;\r
+  *Str = '\0';\r
+  AsciiStrCat  (Str, "{");\r
+  // R0 - R7, PC\r
+  for (Index = 0, First = TRUE; Index <= 9; Index++) {\r
+    if ((OpCode & (1 << Index)) != 0) {\r
+      Start = End = Index;\r
+      for (Index++; ((OpCode & (1 << Index)) != 0) && (Index <= 9); Index++) {\r
+        End = Index;\r
+      }\r
+      \r
+      if (!First) {\r
+        AsciiStrCat  (Str, ",");\r
+      } else {\r
+        First = FALSE;\r
+      }\r
+      \r
+      if (Start == End) {\r
+        AsciiStrCat  (Str, gReg[(Start == 9)?15:Start]);\r
+        AsciiStrCat  (Str, ", ");\r
+      } else {\r
+        AsciiStrCat  (Str, gReg[Start]);\r
+        AsciiStrCat  (Str, "-");\r
+        AsciiStrCat  (Str, gReg[(End == 9)?15:End]);\r
+      }\r
+    }\r
+  }\r
+  if (First) {\r
+    AsciiStrCat  (Str, "ERROR");\r
+  }\r
+  AsciiStrCat  (Str, "}");\r
+  \r
+  // BugBug: Make caller pass in buffer it is cleaner\r
+  return mThumbMregListStr;\r
+}\r
+\r
+UINT32\r
+SignExtend (\r
+  IN  UINT32  Data\r
+  )\r
+{\r
+  return 0;\r
+}\r
+\r
+/**\r
+  DEBUG print the faulting instruction. We cheat and only decode instructions that access \r
+  memory. If the instruction is not found we dump the instruction in hex.\r
+   \r
+  @param  Insturction   ARM instruction to disassemble.  \r
+  \r
+**/\r
+VOID\r
+DisassembleThumbInstruction (\r
+  IN  UINT16    *OpCodePtr,\r
+  OUT CHAR8     *Buf,\r
+  OUT UINTN     Size\r
+  )\r
+{\r
+  UINT16  OpCode = *OpCodePtr;\r
+  UINT32  Index;\r
+  UINT32  Offset;\r
+  UINT16  Rd, Rn, Rm;\r
+  INT32   target_addr;\r
+  BOOLEAN H1, H2, imod;\r
+  UINT32  PC;\r
+\r
+  // These register names match branch form, but not others\r
+  Rd = OpCode & 0x7;\r
+  Rn = (OpCode >> 3) & 0x7;\r
+  Rm = (OpCode >> 6) & 0x7;\r
+  H1 = (OpCode & BIT7) != 0;\r
+  H2 = (OpCode & BIT6) != 0;\r
+  imod = (OpCode & BIT4) != 0;\r
+  PC = (UINT32)(UINTN)*OpCodePtr;\r
+\r
+  for (Index = 0; Index < sizeof (gOp)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
+    if ((OpCode & gOp[Index].Mask) == gOp[Index].OpCode) {\r
+      Offset = AsciiSPrint (Buf, Size, "%a", gOp[Index].Start);   \r
+      switch (gOp[Index].AddressMode) {\r
+      case LOAD_STORE_FORMAT1:\r
+        // A6.5.1  <Rd>, [<Rn>, #<5_bit_offset>]\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, (OpCode >> 7) & 7, (OpCode >> 6) & 0x1f);   \r
+        break;\r
+      case LOAD_STORE_FORMAT2:\r
+        // A6.5.1  <Rd>, [<Rn>, <Rm>]\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d, r%d]", Rd, (OpCode >> 3) & 7, Rm);   \r
+        break;\r
+      case LOAD_STORE_FORMAT3:\r
+        // A6.5.1 <Rd>, [PC, #<8_bit_offset>]\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [pc, #0x%x]", (OpCode >> 8) & 7, OpCode & 0xff);   \r
+        break;\r
+      case LOAD_STORE_FORMAT4:\r
+        // FIX ME!!!!!\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [sp, #0x%x]", (OpCode >> 8) & 7, OpCode & 0xff);   \r
+        break;\r
+      \r
+      case LOAD_STORE_MULTIPLE_FORMAT1:\r
+        // <Rn>!, <registers>  \r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (!BIT8 & OpCode));   \r
+        break;\r
+      case LOAD_STORE_MULTIPLE_FORMAT2:\r
+        // <Rn>!, <registers>  \r
+        // BIT8 is PC \r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (OpCode));   \r
+        break;\r
+      \r
+      case IMMED_8:\r
+        // A6.7 <immed_8>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%x", OpCode & 0xff);   \r
+        break;\r
+\r
+      case CONDITIONAL_BRANCH:\r
+        // A6.3.1 B<cond> <target_address>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, "%a 0x%04x", PC + 4 + SignExtend ((OpCode & 0xff) << 1));   \r
+        break;\r
+      case UNCONDITIONAL_BRANCH_SHORT:\r
+        // A6.3.2 B  <target_address>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend ((OpCode & 0x3ff) << 1));   \r
+        break;\r
+      case UNCONDITIONAL_BRANCH:\r
+        // A6.3.2 BL|BLX <target_address>  ; Produces two 16-bit instructions \r
+        target_addr = *(OpCodePtr - 1);\r
+        if ((target_addr & 0xf800) == 0xf000) {\r
+          target_addr = ((target_addr & 0x3ff) << 12) | (OpCode & 0x3ff);\r
+        } else {\r
+          target_addr = OpCode & 0x3ff;\r
+        }\r
+        // PC + 2 +/- target_addr\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 2 + SignExtend (target_addr));   \r
+        break;\r
+      case BRANCH_EXCHANGE:\r
+        // A6.3.3 BX|BLX <Rm>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d", gReg[Rn | (H2 ? 8:0)]);   \r
+        break;\r
+\r
+      case DATA_FORMAT1:\r
+        // A6.4.3  <Rd>, <Rn>, <Rm>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, r%d", Rd, Rn, Rm);   \r
+        break;\r
+      case DATA_FORMAT2:\r
+        // A6.4.3  <Rd>, <Rn>, #3_bit_immed\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rd, Rn, Rm);   \r
+        break;\r
+      case DATA_FORMAT3:\r
+        // A6.4.3  <Rd>|<Rn>, #8_bit_immed\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", (OpCode >> 8) & 0x7, OpCode & 0xff);   \r
+        break;\r
+      case DATA_FORMAT4:\r
+        // A6.4.3  <Rd>|<Rm>, #immed_5\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rn, Rd, (OpCode >> 6) & 0x1f);   \r
+        break;\r
+      case DATA_FORMAT5:\r
+        // A6.4.3  <Rd>|<Rm>, <Rm>|<Rs>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d", Rd, Rn);   \r
+        break;\r
+      case DATA_FORMAT6_SP:\r
+        // A6.4.3  <Rd>, <reg>, #<8_Bit_immed>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, sp, 0x%x", (OpCode >> 8) & 7, OpCode & 0xff);   \r
+        break;\r
+      case DATA_FORMAT6_PC:\r
+        // A6.4.3  <Rd>, <reg>, #<8_Bit_immed>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, pc, 0x%x", (OpCode >> 8) & 7, OpCode & 0xff);   \r
+        break;\r
+      case DATA_FORMAT7:\r
+        // A6.4.3  SP, SP, #<7_Bit_immed>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " sp, sp 0x%x", (OpCode & 0x7f)*4);   \r
+        break;\r
+      case DATA_FORMAT8:\r
+        // A6.4.3  <Rd>|<Rn>, <Rm>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd | (H1 ? 8:0)], gReg[Rn | (H2 ? 8:0)]);   \r
+        break;\r
+      \r
+      case CPS_FORMAT:\r
+        // A7.1.24\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, "%a %a%a%a", imod ? "ID":"IE", ((OpCode & BIT2) == 0) ? "":"a",  ((OpCode & BIT1) == 0) ? "":"i", ((OpCode & BIT0) == 0) ? "":"f");   \r
+        break;\r
+\r
+      case ENDIAN_FORMAT:\r
+        // A7.1.24\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", (OpCode & BIT3) == 0 ? "LE":"BE");   \r
+        break;\r
+      }\r
+    }\r
+  }\r
+      \r
+\r
+}\r
+\r
\r
index bed0753..5eb3fd8 100644 (file)
@@ -71,6 +71,7 @@
 
   
   CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  DefaultExceptioHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
   PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
   
   SerialPortLib|BeagleBoardPkg/Library/SerialPortLib/SerialPortLib.inf
index a131466..5211e09 100644 (file)
@@ -154,9 +154,9 @@ READ_LOCK_STATUS   = TRUE
 
   #NOTE: Open source EHCI stack doesn't work on Beagleboard.
   #NOTE: UsbBus and UsbMassStorage don't work using iPhond SDK tool chain.
-  INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
-  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
-  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+  #INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  #INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  #INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
 
   #
   # UEFI application (Shell Embedded Boot Loader) 
index 26a381a..698003b 100644 (file)
@@ -682,10 +682,25 @@ NandFlashFlushBlocks (
   return EFI_SUCCESS;
 }
 
+
+
+EFI_BLOCK_IO_MEDIA gNandFlashMedia = {
+  SIGNATURE_32('n','a','n','d'),            // MediaId
+  FALSE,                                    // RemovableMedia
+  TRUE,                                     // MediaPresent
+  FALSE,                                    // LogicalPartition
+  FALSE,                                    // ReadOnly
+  FALSE,                                    // WriteCaching
+  0,                                        // BlockSize
+  2,                                        // IoAlign
+  0,                                        // Pad
+  0                                         // LastBlock
+};
+
 EFI_BLOCK_IO_PROTOCOL BlockIo = 
 {
   EFI_BLOCK_IO_INTERFACE_REVISION,  // Revision
-  &NandFlashMedia,                  // *Media
+  &gNandFlashMedia,                  // *Media
   NandFlashReset,                   // Reset
   NandFlashReadBlocks,              // ReadBlocks
   NandFlashWriteBlocks,             // WriteBlocks
@@ -700,7 +715,7 @@ NandFlashInitialize (
 {
   EFI_STATUS  Status;
   
-  gNandFlashInfo = (NAND_FLASH_INFO *)AllocateZeroPool(sizeof(NAND_FLASH_INFO));
+  gNandFlashInfo = (NAND_FLASH_INFO *)AllocateZeroPool (sizeof(NAND_FLASH_INFO));
 
   //Initialize GPMC module.
   GpmcInit();
@@ -709,7 +724,7 @@ NandFlashInitialize (
   NandFlashReset(&BlockIo, FALSE);
 
   //Detect NAND part and populate gNandFlashInfo structure
-  Status = NandDetectPart();
+  Status = NandDetectPart ();
   if (EFI_ERROR(Status)) {
     DEBUG((EFI_D_ERROR, "Nand part id detection failure: Status: %x\n", Status));
     return Status;
@@ -730,11 +745,11 @@ NandFlashInitialize (
   }
 
   //Configure ECC
-  NandConfigureEcc();
+  NandConfigureEcc ();
 
   //Patch EFI_BLOCK_IO_MEDIA structure.
-  NandFlashMedia.BlockSize = gNandFlashInfo->BlockSize;
-  NandFlashMedia.LastBlock = LAST_BLOCK;
+  gNandFlashMedia.BlockSize = gNandFlashInfo->BlockSize;
+  gNandFlashMedia.LastBlock = LAST_BLOCK;
 
   //Publish BlockIO.
   Status = gBS->InstallMultipleProtocolInterfaces (
index 533e416..2e95b96 100644 (file)
 
 #define MAX_RETRY_COUNT          1500
 
-EFI_BLOCK_IO_MEDIA NandFlashMedia = {
-  SIGNATURE_32('n','a','n','d'),  // MediaId
-  FALSE,                                    // RemovableMedia
-  TRUE,                                     // MediaPresent
-  TRUE,                                     // LogicalPartition
-  FALSE,                                    // ReadOnly
-  FALSE,                                    // WriteCaching
-  0,                                        // BlockSize
-  2,                                        // IoAlign
-  0,                                        // Pad
-  0                                         // LastBlock
-};
 
 typedef struct {
   UINT8 ManufactureId;
index 93164d6..b101049 100644 (file)
 #include <Library/EfiFileLib.h>\r
 \r
 \r
+//PcdEmbeddedFdBaseAddress\r
+\r
+/**\r
+  Fill Me In\r
+\r
+  Argv[0] - "%CommandName%"\r
+\r
+  @param  Argc   Number of command arguments in Argv\r
+  @param  Argv   Array of strings that represent the parsed command line. \r
+                 Argv[0] is the comamnd name\r
+\r
+  @return EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EblEdk2Cmd (\r
+  IN UINTN  Argc,\r
+  IN CHAR8  **Argv\r
+  )\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mLibCmdTemplate[] =\r
 {\r
+  {\r
+    "edk2",\r
+    " filename ; Load FD into memory and boot from it",\r
+    NULL,\r
+    EblEdk2Cmd\r
+  }\r
 };\r
 \r
 \r
index 77c5fbd..763e1e9 100644 (file)
 #include "MMCHS.h"
 
 EFI_BLOCK_IO_MEDIA MMCHSMedia = {
-  SIGNATURE_32('s','d','i','o'),  // MediaId
-  FALSE,                                    // RemovableMedia
+  SIGNATURE_32('s','d','i','o'),            // MediaId
+  TRUE,                                     // RemovableMedia
   TRUE,                                     // MediaPresent
-  TRUE,                                     // LogicalPartition
+  FALSE,                                    // LogicalPartition
   FALSE,                                    // ReadOnly
   FALSE,                                    // WriteCaching
   512,                                      // BlockSize
@@ -52,7 +52,7 @@ MMCHS_DEVICE_PATH gMmcHsDevicePath =
 };
 
 CARD_INFO                  *gCardInfo;
-EMBEDDED_EXTERNAL_DEVICE *gTPS65950;
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
 
 //
 // Internal Functions
index 411e3c1..71e60b7 100755 (executable)
@@ -60,7 +60,7 @@ stack_pointer_setup
 \r
   // Call C entry point\r
   mov     r0, #0x80000000   /* memory base arg0          */\r
-  mov     r1, #0x08000000   /* memory size arg1          */\r
+  mov     r1, #0x10000000   /* memory size arg1          */\r
   blx     CEntryPoint       /* Assume C code is thumb    */\r
 \r
 ShouldNeverGetHere\r
index 7633d66..e129a3c 100644 (file)
@@ -81,13 +81,33 @@ EblPrintBlkIoInfo (
   )\r
 {\r
   UINT64                    DeviceSize;\r
-\r
+  UINTN                     Index;\r
+  UINTN                     Max;\r
+  EFI_OPEN_FILE             *FsFile;\r
 \r
   if (File == NULL) {\r
     return;\r
   }\r
 \r
   AsciiPrint ("  %a: ", File->DeviceName);\r
+\r
+  // print out name of file system, if any, on this block device\r
+  Max = EfiGetDeviceCounts (EfiOpenFileSystem);\r
+  if (Max != 0) {\r
+    for (Index = 0; Index < Max; Index++) {\r
+      FsFile = EfiDeviceOpenByType (EfiOpenFileSystem, Index);\r
+      if (FsFile != NULL) {\r
+        if (FsFile->EfiHandle == File->EfiHandle) {\r
+          AsciiPrint ("fs%d: ", Index);\r
+          EfiClose (FsFile);\r
+          break;\r
+        }\r
+      }\r
+      EfiClose (FsFile);\r
+    }\r
+  }\r
+\r
+  // Print out useful Block IO media properties\r
   if (File->FsBlockIoMedia.RemovableMedia) {\r
     AsciiPrint ("Removable ");\r
   }\r
@@ -103,7 +123,6 @@ EblPrintBlkIoInfo (
   EfiClose (File);\r
 }\r
 \r
-\r
  /**\r
   Print information about the Load File devices.\r
   If the device supports PXE dump out extra information\r