From db5d39e5c33381ec23702226473a6b6b7d5a415d Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sat, 9 Oct 2021 12:18:50 +0200 Subject: armdebug: remove commented code from eCos This code was included as a reference but not used. --- AT91SAM7S256/armdebug/Debugger/debug_opcodes.S | 468 ------------------------- 1 file changed, 468 deletions(-) (limited to 'AT91SAM7S256') diff --git a/AT91SAM7S256/armdebug/Debugger/debug_opcodes.S b/AT91SAM7S256/armdebug/Debugger/debug_opcodes.S index 307da8b..c264338 100644 --- a/AT91SAM7S256/armdebug/Debugger/debug_opcodes.S +++ b/AT91SAM7S256/armdebug/Debugger/debug_opcodes.S @@ -13,474 +13,6 @@ * */ -/* WARNING: The following excepted code from eCos arm_stub.c has bugs in - * the next instruction address calculation logic. The C code has not been - * updated since it is only used for documentation purposes. - * - * Correct code behavior should be determined from the ARMDEBUG source code - * whenever there is conflict in the algorithms. - * - * Of note: ARM and Thumb mode BX PC handling (missing PC+8/PC+4 adjustment). - * LDM PC handling (missing Pre/Post Incr/Decr adjustment). - */ -/**************************************************************************** -// Selected Routines from the eCos arm_stub.c related to next instruction address -// determination in ARM processors. - -//======================================================================== -// -// arm_stub.c -// -// Helper functions for stub, generic to all ARM processors -// -//======================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//======================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): Red Hat, gthomas -// Contributors: Red Hat, gthomas, jskov -// Date: 1998-11-26 -// Purpose: -// Description: Helper functions for stub, generic to all ARM processors -// Usage: -// -//####DESCRIPTIONEND#### -// -//======================================================================== - - -static int -ins_will_execute(unsigned long ins) -{ - unsigned long psr = get_register(PS); // condition codes - int res = 0; - switch ((ins & 0xF0000000) >> 28) { - case 0x0: // EQ - res = (psr & PS_Z) != 0; - break; - case 0x1: // NE - res = (psr & PS_Z) == 0; - break; - case 0x2: // CS - res = (psr & PS_C) != 0; - break; - case 0x3: // CC - res = (psr & PS_C) == 0; - break; - case 0x4: // MI - res = (psr & PS_N) != 0; - break; - case 0x5: // PL - res = (psr & PS_N) == 0; - break; - case 0x6: // VS - res = (psr & PS_V) != 0; - break; - case 0x7: // VC - res = (psr & PS_V) == 0; - break; - case 0x8: // HI - res = ((psr & PS_C) != 0) && ((psr & PS_Z) == 0); - break; - case 0x9: // LS - res = ((psr & PS_C) == 0) || ((psr & PS_Z) != 0); - break; - case 0xA: // GE - res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) || - ((psr & (PS_N|PS_V)) == 0); - break; - case 0xB: // LT - res = ((psr & (PS_N|PS_V)) == PS_N) || - ((psr & (PS_N|PS_V)) == PS_V); - break; - case 0xC: // GT - res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) || - ((psr & (PS_N|PS_V)) == 0); - res = ((psr & PS_Z) == 0) && res; - break; - case 0xD: // LE - res = ((psr & (PS_N|PS_V)) == PS_N) || - ((psr & (PS_N|PS_V)) == PS_V); - res = ((psr & PS_Z) == PS_Z) || res; - break; - case 0xE: // AL - res = TRUE; - break; - case 0xF: // NV - if (((ins & 0x0E000000) >> 24) == 0xA) - res = TRUE; - else - res = FALSE; - break; - } - return res; -} - -static unsigned long -RmShifted(int shift) -{ - unsigned long Rm = get_register(shift & 0x00F); - int shift_count; - if ((shift & 0x010) == 0) { - shift_count = (shift & 0xF80) >> 7; - } else { - shift_count = get_register((shift & 0xF00) >> 8); - } - switch ((shift & 0x060) >> 5) { - case 0x0: // Logical left - Rm <<= shift_count; - break; - case 0x1: // Logical right - Rm >>= shift_count; - break; - case 0x2: // Arithmetic right - Rm = (unsigned long)((long)Rm >> shift_count); - break; - case 0x3: // Rotate right - if (shift_count == 0) { - // Special case, RORx - Rm >>= 1; - if (get_register(PS) & PS_C) Rm |= 0x80000000; - } else { - Rm = (Rm >> shift_count) | (Rm << (32-shift_count)); - } - break; - } - return Rm; -} - -// Decide the next instruction to be executed for a given instruction -static unsigned long * -target_ins(unsigned long *pc, unsigned long ins) -{ - unsigned long new_pc, offset, op2; - unsigned long Rn; - int i, reg_count, c; - - switch ((ins & 0x0C000000) >> 26) { - case 0x0: - // BX or BLX - if ((ins & 0x0FFFFFD0) == 0x012FFF10) { - new_pc = (unsigned long)get_register(ins & 0x0000000F); - return ((unsigned long *)new_pc); - } - // Data processing - new_pc = (unsigned long)(pc+1); - if ((ins & 0x0000F000) == 0x0000F000) { - // Destination register is PC - if ((ins & 0x0FBF0000) != 0x010F0000) { - Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); - if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch! - if ((ins & 0x02000000) == 0) { - op2 = RmShifted(ins & 0x00000FFF); - } else { - op2 = ins & 0x000000FF; - i = (ins & 0x00000F00) >> 8; // Rotate count - op2 = (op2 >> (i*2)) | (op2 << (32-(i*2))); - } - switch ((ins & 0x01E00000) >> 21) { - case 0x0: // AND - new_pc = Rn & op2; - break; - case 0x1: // EOR - new_pc = Rn ^ op2; - break; - case 0x2: // SUB - new_pc = Rn - op2; - break; - case 0x3: // RSB - new_pc = op2 - Rn; - break; - case 0x4: // ADD - new_pc = Rn + op2; - break; - case 0x5: // ADC - c = (get_register(PS) & PS_C) != 0; - new_pc = Rn + op2 + c; - break; - case 0x6: // SBC - c = (get_register(PS) & PS_C) != 0; - new_pc = Rn - op2 + c - 1; - break; - case 0x7: // RSC - c = (get_register(PS) & PS_C) != 0; - new_pc = op2 - Rn +c - 1; - break; - case 0x8: // TST - case 0x9: // TEQ - case 0xA: // CMP - case 0xB: // CMN - break; // PC doesn't change - case 0xC: // ORR - new_pc = Rn | op2; - break; - case 0xD: // MOV - new_pc = op2; - break; - case 0xE: // BIC - new_pc = Rn & ~op2; - break; - case 0xF: // MVN - new_pc = ~op2; - break; - } - } - } - return ((unsigned long *)new_pc); - case 0x1: - if ((ins & 0x02000010) == 0x02000010) { - // Undefined! - return (pc+1); - } else { - if ((ins & 0x00100000) == 0) { - // STR - return (pc+1); - } else { - // LDR - if ((ins & 0x0000F000) != 0x0000F000) { - // Rd not PC - return (pc+1); - } else { - Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); - if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch! - if (ins & 0x01000000) { - // Add/subtract offset before - if ((ins & 0x02000000) == 0) { - // Immediate offset - if (ins & 0x00800000) { - // Add offset - Rn += (ins & 0x00000FFF); - } else { - // Subtract offset - Rn -= (ins & 0x00000FFF); - } - } else { - // Offset is in a register - if (ins & 0x00800000) { - // Add offset - Rn += RmShifted(ins & 0x00000FFF); - } else { - // Subtract offset - Rn -= RmShifted(ins & 0x00000FFF); - } - } - } - return ((unsigned long *)*(unsigned long *)Rn); - } - } - } - return (pc+1); - case 0x2: // Branch, LDM/STM - if ((ins & 0x02000000) == 0) { - // LDM/STM - if ((ins & 0x00100000) == 0) { - // STM - return (pc+1); - } else { - // LDM - if ((ins & 0x00008000) == 0) { - // PC not in list - return (pc+1); - } else { - Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); - if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch! - offset = ins & 0x0000FFFF; - reg_count = 0; - for (i = 0; i < 15; i++) { - if (offset & (1<> 12) { - case 0x4: - // Check for BX or BLX - if ((ins & 0xff07) == 0x4700) - new_pc = (unsigned long)get_register((ins & 0x00078) >> 3); - break; - case 0xb: - // push/pop - // Look for "pop {...,pc}" - if ((ins & 0xf00) == 0xd00) { - // find PC - sp = (unsigned long)get_register(SP); - - for (offset = i = 0; i < 8; i++) - if (ins & (1 << i)) - offset += 4; - - new_pc = *(cyg_uint32 *)(sp + offset); - - if (!v5T_semantics()) - new_pc = MAKE_THUMB_ADDR(new_pc); - } - break; - case 0xd: - // Bcc | SWI - // Use ARM function to check condition - arm_ins = ((unsigned long)(ins & 0x0f00)) << 20; - if ((arm_ins & 0xF0000000) == 0xF0000000) { - // SWI - new_pc = CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT * 4; - } else if (ins_will_execute(arm_ins)) { - offset = (ins & 0x00FF) << 1; - if (ins & 0x0080) offset |= 0xFFFFFE00; // sign extend - new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset); - } - break; - case 0xe: - // check for B - if ((ins & 0x0800) == 0) { - offset = (ins & 0x07FF) << 1; - if (ins & 0x0400) offset |= 0xFFFFF800; // sign extend - new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset); - } - break; - case 0xf: - // BL/BLX (4byte instruction!) - // First instruction (bit 11 == 0) holds top-part of offset - if ((ins & 0x0800) == 0) { - offset = (ins & 0x07FF) << 12; - if (ins & 0x0400) offset |= 0xFF800000; // sign extend - // Get second instruction - // Second instruction (bit 11 == 1) holds bottom-part of offset - ins = *(unsigned short*)(pc+2); - // Check for BL/BLX - if ((ins & 0xE800) == 0xE800) { - offset |= (ins & 0x07ff) << 1; - new_pc = (unsigned long)(pc+4) + offset; - // If its BLX, force a full word alignment - // Otherwise, its a thumb address. - if (!(ins & 0x1000)) - new_pc &= ~3; - else - new_pc = MAKE_THUMB_ADDR(new_pc); - } - } - break; - } - - return new_pc; -} - -void __single_step (void) -{ - unsigned long pc = get_register(PC); - unsigned long cpsr = get_register(PS); - - // Calculate address of next instruction to be executed - if (cpsr & CPSR_THUMB_ENABLE) { - // thumb - ss_saved_pc = target_thumb_ins(pc, *(unsigned short*)pc); - } else { - // ARM - unsigned long curins = *(unsigned long*)pc; - if (ins_will_execute(curins)) { - // Decode instruction to decide what the next PC will be - ss_saved_pc = (unsigned long) target_ins((unsigned long*)pc, - curins); - } else { - // The current instruction will not execute (the conditions - // don't hold) - ss_saved_pc = pc+4; - } - } - - // Set breakpoint according to type - if (IS_THUMB_ADDR(ss_saved_pc)) { - // Thumb instruction - unsigned long t_pc = UNMAKE_THUMB_ADDR(ss_saved_pc); - ss_saved_thumb_instr = *(unsigned short*)t_pc; - *(unsigned short*)t_pc = HAL_BREAKINST_THUMB; - } else { - // ARM instruction - ss_saved_instr = *(unsigned long*)ss_saved_pc; - *(unsigned long*)ss_saved_pc = HAL_BREAKINST_ARM; - } -} - - ****************************************************************************/ - #define __ASSEMBLY__ #include "debug_stub.h" #include "debug_internals.h" -- cgit v1.2.3