Move ARM disassembler into a library.
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 1 Feb 2010 18:25:18 +0000 (18:25 +0000)
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 1 Feb 2010 18:25:18 +0000 (18:25 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9902 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/ArmPkg.dec
ArmPkg/ArmPkg.dsc
ArmPkg/Include/Library/ArmDisassemblerLib.h [new file with mode: 0644]
ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c [new file with mode: 0644]
ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf [new file with mode: 0644]
ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c [new file with mode: 0644]
ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c [deleted file]
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c [deleted file]
BeagleBoardPkg/BeagleBoardPkg.dsc

index 67c729d..8f5d696 100644 (file)
@@ -36,7 +36,8 @@
   SemihostLib|Include/Library/Semihosting.h\r
   UncachedMemoryAllocationLib|Include/Library/UncachedMemoryAllocationLib.h\r
   DefaultExceptioHandlerLib|Include/Library/DefaultExceptioHandlerLib.h\r
-\r
+  ArmDisassemblerLib|Include/Library/ArmDisassemblerLib.h\r
+  \r
 [Guids.common]\r
   gArmTokenSpaceGuid       = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }\r
 \r
index 12dd519..b0d2c8f 100644 (file)
@@ -52,6 +52,7 @@
 
   ArmLib|ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
   CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
 
 [LibraryClasses.ARM]
   NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
diff --git a/ArmPkg/Include/Library/ArmDisassemblerLib.h b/ArmPkg/Include/Library/ArmDisassemblerLib.h
new file mode 100644 (file)
index 0000000..6ba270f
--- /dev/null
@@ -0,0 +1,39 @@
+/** @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 __ARM_DISASSEBLER_LIB_H__
+#define __ARM_DISASSEBLER_LIB_H__
+
+/**
+  Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to 
+  point to next instructin. 
+  
+  We cheat and only decode instructions that access 
+  memory. If the instruction is not found we dump the instruction in hex.
+   
+  @param  OpCodePtrPtr  Pointer to pointer of ARM Thumb instruction to disassemble.  
+  @param  Thumb         TRUE for Thumb(2), FALSE for ARM instruction stream
+  @param  Buf           Buffer to sprintf disassembly into.
+  @param  Size          Size of Buf in bytes. 
+  
+**/
+VOID
+DisassembleInstruction (
+  IN  UINT8     **OpCodePtr,
+  IN  BOOLEAN   Thumb,
+  OUT CHAR8     *Buf,
+  OUT UINTN     Size
+  );
+  
+#endif 
diff --git a/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c b/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
new file mode 100644 (file)
index 0000000..5b43f55
--- /dev/null
@@ -0,0 +1,448 @@
+/** @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
+#include <Library/ArmDisassemblerLib.h>\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
+  Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r
+  point to next instructin. \r
+  \r
+  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  OpCodePtr   Pointer to pointer of ARM instruction to disassemble.  \r
+  @param  Buf         Buffer to sprintf disassembly into.\r
+  @param  Size        Size of Buf in bytes. \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
+  \r
+  *OpCodePtr += 1;\r
+  return;\r
+}\r
+\r
diff --git a/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf b/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
new file mode 100644 (file)
index 0000000..4cbf461
--- /dev/null
@@ -0,0 +1,40 @@
+#/** @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                      = 7ACEC173-F15D-426C-8F2F-BD86B4183EF1\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ArmDisassemblerLib\r
+\r
+\r
+[Sources.common]\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/ArmDisassemblerLib/ThumbDisassembler.c b/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c
new file mode 100644 (file)
index 0000000..d59d103
--- /dev/null
@@ -0,0 +1,462 @@
+/** @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 gOpThumb[] = {\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
+\r
+#if 0  \r
+THUMB_INSTRUCTIONS gOpThumb2[] = {\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
+};\r
+#endif\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
+  Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r
+  point to next instructin. \r
+  \r
+  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  OpCodePtrPtr  Pointer to pointer of ARM Thumb instruction to disassemble.  \r
+  @param  Buf           Buffer to sprintf disassembly into.\r
+  @param  Size          Size of Buf in bytes. \r
+  \r
+**/\r
+VOID\r
+DisassembleThumbInstruction (\r
+  IN  UINT16    **OpCodePtrPtr,\r
+  OUT CHAR8     *Buf,\r
+  OUT UINTN     Size\r
+  )\r
+{\r
+  UINT16  *OpCodePtr;\r
+  UINT16  OpCode;\r
+  UINT16  OpCode32;\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
+  OpCodePtr = *OpCodePtrPtr;\r
+  OpCode = **OpCodePtrPtr;\r
+  \r
+  // Thumb2 is a stream of 16-bit instructions not a 32-bit instruction.\r
+  OpCode32 = (OpCode << 16) | *(OpCodePtr + 1);\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
+  // Increment by the minimum instruction size, Thumb2 could be bigger\r
+  *OpCodePtrPtr += 1;\r
+  \r
+  for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
+    if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) {\r
+      Offset = AsciiSPrint (Buf, Size, "%a", gOpThumb[Index].Start);   \r
+      switch (gOpThumb[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
+#if 0  \r
+  // Thumb2 are 32-bit instructions\r
+  *OpCodePtrPtr += 1;\r
+  for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
+    if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) {\r
+    }\r
+  }\r
+#endif\r
+  // Unknown instruction is 16-bits\r
+  *OpCodePtrPtr -= 1;\r
+  AsciiSPrint (Buf, Size, "0x%04x", OpCode);\r
+}\r
+\r
+\r
+\r
+VOID\r
+DisassembleArmInstruction (\r
+  IN  UINT32    **OpCodePtr,\r
+  OUT CHAR8     *Buf,\r
+  OUT UINTN     Size\r
+  );\r
+\r
+\r
+/**\r
+  Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r
+  point to next instructin. \r
+  \r
+  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  OpCodePtrPtr  Pointer to pointer of ARM Thumb instruction to disassemble.  \r
+  @param  Thumb         TRUE for Thumb(2), FALSE for ARM instruction stream\r
+  @param  Buf           Buffer to sprintf disassembly into.\r
+  @param  Size          Size of Buf in bytes. \r
+  \r
+**/\r
+VOID\r
+DisassembleInstruction (\r
+  IN  UINT8     **OpCodePtr,\r
+  IN  BOOLEAN   Thumb,\r
+  OUT CHAR8     *Buf,\r
+  OUT UINTN     Size\r
+  )\r
+{\r
+  if (Thumb) {\r
+    DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size);\r
+  } else {\r
+    DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size);\r
+  }\r
+}\r
\r
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c
deleted file mode 100644 (file)
index 034236b..0000000
+++ /dev/null
@@ -1,442 +0,0 @@
-/** @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
index 8180c42..b6fbb19 100644 (file)
 #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
@@ -248,6 +234,7 @@ 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
     \r
     CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);\r
     DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));\r
@@ -268,15 +255,10 @@ DefaultExceptionHandler (
       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
-      }\r
+      DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;\r
+      DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, Buffer, sizeof (Buffer));\r
+      DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\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
index a989895..94009ed 100644 (file)
@@ -15,7 +15,7 @@
 \r
 [Defines]\r
   INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = SemiHostingSerialPortLib\r
+  BASE_NAME                      = DefaultExceptionHandlerLib\r
   FILE_GUID                      = EACDB354-DF1A-4AF9-A171-499737ED818F\r
   MODULE_TYPE                    = UEFI_DRIVER\r
   VERSION_STRING                 = 1.0\r
@@ -25,8 +25,6 @@
 \r
 [Sources.common]\r
   DefaultExceptionHandler.c\r
-  ArmDisassembler.c\r
-  ThumbDisassembler.c\r
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
@@ -38,5 +36,6 @@
   PrintLib\r
   DebugLib\r
   PeCoffGetEntryPointLib\r
+  ArmDisassemblerLib\r
 \r
 \r
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c
deleted file mode 100644 (file)
index b021e78..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-/** @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 f9b1d2e..cf49203 100644 (file)
   EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
   
   GdbSerialLib|Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
 
 
 [LibraryClasses.common.SEC]