Move ARM disassembler into a library and out of the exception handler. Add a hook to call the lib from a platform specific EBL command on BeagleBoard.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9903 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
andrewfish 2010-02-01 18:59:27 +00:00
parent 097bd461c4
commit f9f937d243
6 changed files with 61 additions and 13 deletions

View File

@ -24,6 +24,7 @@
@param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
@param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream
@param Extended TRUE dump hex for instruction too.
@param Buf Buffer to sprintf disassembly into. @param Buf Buffer to sprintf disassembly into.
@param Size Size of Buf in bytes. @param Size Size of Buf in bytes.
@ -32,6 +33,7 @@ VOID
DisassembleInstruction ( DisassembleInstruction (
IN UINT8 **OpCodePtr, IN UINT8 **OpCodePtr,
IN BOOLEAN Thumb, IN BOOLEAN Thumb,
IN BOOLEAN Extended,
OUT CHAR8 *Buf, OUT CHAR8 *Buf,
OUT UINTN Size OUT UINTN Size
); );

View File

@ -154,13 +154,15 @@ RotateRight (
@param OpCodePtr Pointer to pointer of ARM instruction to disassemble. @param OpCodePtr Pointer to pointer of ARM instruction to disassemble.
@param Buf Buffer to sprintf disassembly into. @param Buf Buffer to sprintf disassembly into.
@param Size Size of Buf in bytes. @param Size Size of Buf in bytes.
@param Extended TRUE dump hex for instruction too.
**/ **/
VOID VOID
DisassembleArmInstruction ( DisassembleArmInstruction (
IN UINT32 **OpCodePtr, IN UINT32 **OpCodePtr,
OUT CHAR8 *Buf, OUT CHAR8 *Buf,
OUT UINTN Size OUT UINTN Size,
IN BOOLEAN Extended
) )
{ {
UINT32 OpCode = **OpCodePtr; UINT32 OpCode = **OpCodePtr;
@ -183,6 +185,13 @@ DisassembleArmInstruction (
Rd = (OpCode >> 12) & 0xf; Rd = (OpCode >> 12) & 0xf;
Rm = (OpCode & 0xf); Rm = (OpCode & 0xf);
if (Extended) {
Index = AsciiSPrint (Buf, Size, "0x%08x ", OpCode);
Buf += Index;
Size -= Index;
}
// LDREX, STREX // LDREX, STREX
if ((OpCode & 0x0fe000f0) == 0x01800090) { if ((OpCode & 0x0fe000f0) == 0x01800090) {
if (L) { if (L) {

View File

@ -263,13 +263,15 @@ SignExtend (
@param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
@param Buf Buffer to sprintf disassembly into. @param Buf Buffer to sprintf disassembly into.
@param Size Size of Buf in bytes. @param Size Size of Buf in bytes.
@param Extended TRUE dump hex for instruction too.
**/ **/
VOID VOID
DisassembleThumbInstruction ( DisassembleThumbInstruction (
IN UINT16 **OpCodePtrPtr, IN UINT16 **OpCodePtrPtr,
OUT CHAR8 *Buf, OUT CHAR8 *Buf,
OUT UINTN Size OUT UINTN Size,
IN BOOLEAN Extended
) )
{ {
UINT16 *OpCodePtr; UINT16 *OpCodePtr;
@ -302,7 +304,11 @@ DisassembleThumbInstruction (
for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) { for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) {
if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) { if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) {
Offset = AsciiSPrint (Buf, Size, "%a", gOpThumb[Index].Start); if (Extended) {
Offset = AsciiSPrint (Buf, Size, "0x%04x %a", OpCode, gOpThumb[Index].Start);
} else {
Offset = AsciiSPrint (Buf, Size, "%a", gOpThumb[Index].Start);
}
switch (gOpThumb[Index].AddressMode) { switch (gOpThumb[Index].AddressMode) {
case LOAD_STORE_FORMAT1: case LOAD_STORE_FORMAT1:
// A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>] // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]
@ -414,12 +420,21 @@ DisassembleThumbInstruction (
*OpCodePtrPtr += 1; *OpCodePtrPtr += 1;
for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) { for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) {
if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) { if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) {
if (Extended) {
Offset = AsciiSPrint (Buf, Size, "0x%04x %a", OpCode32, gOpThumb2[Index].Start);
} else {
Offset = AsciiSPrint (Buf, Size, "%a", gOpThumb2[Index].Start);
}
switch (gOpThumb2[Index].AddressMode) {
}
} }
} }
#endif #endif
// Unknown instruction is 16-bits // Unknown instruction is 16-bits
*OpCodePtrPtr -= 1; *OpCodePtrPtr -= 1;
AsciiSPrint (Buf, Size, "0x%04x", OpCode); if (!Extended) {
AsciiSPrint (Buf, Size, "0x%04x", OpCode);
}
} }
@ -428,7 +443,8 @@ VOID
DisassembleArmInstruction ( DisassembleArmInstruction (
IN UINT32 **OpCodePtr, IN UINT32 **OpCodePtr,
OUT CHAR8 *Buf, OUT CHAR8 *Buf,
OUT UINTN Size OUT UINTN Size,
IN BOOLEAN Extended
); );
@ -441,6 +457,7 @@ DisassembleArmInstruction (
@param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
@param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream
@param Extended TRUE dump hex for instruction too.
@param Buf Buffer to sprintf disassembly into. @param Buf Buffer to sprintf disassembly into.
@param Size Size of Buf in bytes. @param Size Size of Buf in bytes.
@ -449,14 +466,15 @@ VOID
DisassembleInstruction ( DisassembleInstruction (
IN UINT8 **OpCodePtr, IN UINT8 **OpCodePtr,
IN BOOLEAN Thumb, IN BOOLEAN Thumb,
IN BOOLEAN Extended,
OUT CHAR8 *Buf, OUT CHAR8 *Buf,
OUT UINTN Size OUT UINTN Size
) )
{ {
if (Thumb) { if (Thumb) {
DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size); DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size, Extended);
} else { } else {
DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size); DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size, Extended);
} }
} }

View File

@ -256,7 +256,7 @@ DefaultExceptionHandler (
// If we come from an image it is safe to show the instruction. We know it should not fault // If we come from an image it is safe to show the instruction. We know it should not fault
DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC; DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;
DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, Buffer, sizeof (Buffer)); DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, TRUE, Buffer, sizeof (Buffer));
DEBUG ((EFI_D_ERROR, "\n%a", Buffer)); DEBUG ((EFI_D_ERROR, "\n%a", Buffer));
} }

View File

@ -25,7 +25,7 @@
#include <Library/UefiLib.h> #include <Library/UefiLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Library/EfiFileLib.h> #include <Library/EfiFileLib.h>
#include <Library/ArmDisassemblerLib.h>
//PcdEmbeddedFdBaseAddress //PcdEmbeddedFdBaseAddress
@ -42,11 +42,29 @@
**/ **/
EFI_STATUS EFI_STATUS
EblEdk2Cmd ( EblDisassembler (
IN UINTN Argc, IN UINTN Argc,
IN CHAR8 **Argv IN CHAR8 **Argv
) )
{ {
UINT8 *Ptr;
UINT32 Address;
UINT32 Count;
CHAR8 Buffer[80];
if (Argc < 2) {
return EFI_INVALID_PARAMETER;
}
Address = AsciiStrHexToUintn (Argv[1]);
Count = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 10;
Ptr = (UINT8 *)(UINTN)Address;
while (Count-- > 0) {
DisassembleInstruction (&Ptr, TRUE, TRUE, Buffer, sizeof (Buffer));
AsciiPrint ("0x%08x: %a", Address, Buffer);
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -54,10 +72,10 @@ EblEdk2Cmd (
GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mLibCmdTemplate[] = GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mLibCmdTemplate[] =
{ {
{ {
"edk2", "disasm address [count]",
" filename ; Load FD into memory and boot from it", " disassemble count instructions",
NULL, NULL,
EblEdk2Cmd EblDisassembler
} }
}; };

View File

@ -40,6 +40,7 @@
[LibraryClasses] [LibraryClasses]
BaseLib BaseLib
DebugLib DebugLib
ArmDisassemblerLib
[Protocols] [Protocols]