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
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
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
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
#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
# ExceptionSupport.ARMv6.S | GCC\r
Mmu.c\r
\r
+\r
[Packages]\r
ArmPkg/ArmPkg.dec\r
EmbeddedPkg/EmbeddedPkg.dec\r
PeCoffGetEntryPointLib\r
UefiLib\r
CpuLib\r
+ DefaultExceptioHandlerLib\r
\r
[Protocols]\r
gEfiCpuArchProtocolGuid\r
\r
#include "CpuDxe.h" \r
\r
-EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;\r
\r
VOID\r
ExceptionHandlersStart (\r
\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
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
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
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
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
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
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
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
)\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
\r
VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages = {\r
CpuConvertPagesToUncachedVirtualAddress,\r
- CpuReconvertPagesPages\r
+ CpuReconvertPages\r
};\r
\r
\r
VOID
);
+VOID
+EFIAPI
+ArmUpdateTranslationTableEntry (
+ IN UINTN Mva
+ );
+
VOID
EFIAPI
ArmSetDomainAccessControl (
--- /dev/null
+/** @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
--- /dev/null
+/** @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
--- /dev/null
+/** @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
--- /dev/null
+#/** @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
--- /dev/null
+/** @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
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+ DefaultExceptioHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
SerialPortLib|BeagleBoardPkg/Library/SerialPortLib/SerialPortLib.inf
#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)
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
{
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();
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;
}
//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 (
#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;
#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
#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
};
CARD_INFO *gCardInfo;
-EMBEDDED_EXTERNAL_DEVICE *gTPS65950;
+EMBEDDED_EXTERNAL_DEVICE *gTPS65950;
//
// Internal Functions
\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
)\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
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