⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 singlestep.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        handle_pc_load(inst.lsio.B_bit, operand);
    }
}


/*
 * Decode all load/store register offset instructions
 */
static void decode_lsro_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * Only support direct loads of the PC
     *
     * According to the ARM(R) manual, automatic updates of the PC
     * are UNPREDICTABLE (ie implementation defined).
     */
    if ((inst.lsro.Rd == REG_PC) && (inst.lsro.L_bit == LS_LOAD))
    {
        unsigned long operand = load_store_register_operand(regs,
                                                            inst.lsro.P_bit, 
                                                            inst.lsro.U_bit,
                                                            inst.lsro.Rn,
                                                            inst.lsro.Rm,
                                                            inst.lsro.shift,
                                                            inst.lsro.shift_immed);
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("Decoded an load/store w/ register offset instruction.\n");
        bsp_printf("inst.lsro.Rm          = 0x%x\n", inst.lsro.Rm);
        bsp_printf("inst.lsro.rsv2        = 0x%x\n", inst.lsro.rsv2);
        bsp_printf("inst.lsro.shift       = 0x%x\n", inst.lsro.shift);
        bsp_printf("inst.lsro.shift_immed = 0x%x\n", inst.lsro.shift_immed);
        bsp_printf("inst.lsro.Rd          = 0x%x\n", inst.lsro.Rd);
        bsp_printf("inst.lsro.Rn          = 0x%x\n", inst.lsro.Rn);
        bsp_printf("inst.lsro.L_bit       = 0x%x\n", inst.lsro.L_bit);
        bsp_printf("inst.lsro.W_bit       = 0x%x\n", inst.lsro.W_bit);
        bsp_printf("inst.lsro.B_bit       = 0x%x\n", inst.lsro.B_bit);
        bsp_printf("inst.lsro.U_bit       = 0x%x\n", inst.lsro.U_bit);
        bsp_printf("inst.lsro.P_bit       = 0x%x\n", inst.lsro.P_bit);
        bsp_printf("inst.lsro.rsv1        = 0x%x\n", inst.lsro.rsv1);
        bsp_printf("inst.lsro.cond        = 0x%x\n", inst.lsro.cond);
        bsp_printf("operand               = 0x%x\n", operand);
#endif /* DEBUG_SINGLESTEP_VERBOSE */

        handle_pc_load(inst.lsro.B_bit, operand);
    }
}


/*
 * Decode all load/store halfword/signed byte immediate offset instructions
 */
static void decode_lshwi_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * According to the ARM(R) Manual, if Rd is PC then
     * the result is unpredictable.  Don't do anything
     * here.  Just return.
     */
}


/*
 * Decode all load/store halfword/signed byte register offset instructions
 */
static void decode_lshwr_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * According to the ARM(R) Manual, if Rd is PC then
     * the result is unpredictable.  Don't do anything
     * here.  Just return.
     */
}


/*
 * Decode all swap/swap byte instructions
 */
static void decode_swap_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * According to the ARM(R) Manual, if Rd is PC then
     * the result is unpredictable.  Don't do anything
     * here.  Just return.
     */
}


/*
 * Decode all load/store multiple instructions
 */
static void decode_lsm_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * Only support direct load multiples where the PC is in the
     * register list.
     *
     * According to the ARM(R) manual, automatic updates of the PC
     * are UNPREDICTABLE (ie implementation defined).
     */
    if ((inst.lsm.L_bit == LS_LOAD) && (inst.lsm.Reg_List & (0x1 << REG_PC)))
    {
        unsigned char *regs_array = (unsigned char *)regs;
        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.lsm.Rn)];
        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
        unsigned long offset_to_pc = 0;
        int i;
        unsigned long **dest = 0;

#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("Decoded an load multiple instruction.\n");
        bsp_printf("inst.lsm.Reg_List   = 0x%x\n", inst.lsm.Reg_List);

        bsp_printf("inst.lsm.Rn         = 0x%x\n", inst.lsm.Rn);
        bsp_printf("inst.lsm.L_bit      = 0x%x\n", inst.lsm.L_bit);
        bsp_printf("inst.lsm.W_bit      = 0x%x\n", inst.lsm.W_bit);
        bsp_printf("inst.lsm.S_bit      = 0x%x\n", inst.lsm.S_bit);
        bsp_printf("inst.lsm.U_bit      = 0x%x\n", inst.lsm.U_bit);
        bsp_printf("inst.lsm.P_bit      = 0x%x\n", inst.lsm.P_bit);
        bsp_printf("inst.lsm.rsv1       = 0x%x\n", inst.lsm.rsv1);
        bsp_printf("inst.lsm.cond       = 0x%x\n", inst.lsm.cond);
#endif /* DEBUG_SINGLESTEP_VERBOSE */

        if (inst.lsm.U_bit == 0)
        {
            /*
             * We are using a ascending stack.
             * That means the PC is actually the register
             * nearest to Rn currently.
             */
            if (inst.lsm.P_bit == 1)
                /*
                 * Using a pre-decrement.
                 */
                offset_to_pc = -bsp_regsize(REG_PC);
            else
                offset_to_pc = 0;
        } else {
            /*
             * We are using an descending stack.
             * That means the PC is actually the register
             * farthest from Rn currently.
             *
             * Find the number of registers stored before the PC
             */
            for (i = 0; i < REG_PC; i++)
            {
                if ((inst.lsm.Reg_List & (0x1 << i)) != 0)
                {
                    /*
                     * Bit #i is set.  Increment our count.
                     */
                    offset_to_pc += bsp_regsize(i);
                }
            }

            /*
             * Adjust the offset if we do a decrement/increment __BEFORE__
             * the write.
             */
            if (inst.lsm.P_bit == 1)
                offset_to_pc += bsp_regsize(REG_PC);
        }

        /*
         * Now let's calculate the real address of the stored PC
         * making sure to mask out the two LO bits.
         */
        dest = (unsigned long **)((Rn_val + offset_to_pc) & ~0x3);

#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("Rn_val = 0x%08lx\n", Rn_val);
        bsp_printf("offset_to_pc = 0x%08lx\n", offset_to_pc);
        bsp_printf("dest = 0x%08lx\n", dest);
        bsp_printf("*dest = 0x%08lx\n", *dest);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        
        insert_ss_break(*dest);
    }
}


/*
 * Decode all coprocessor data processing instructions
 */
static void decode_cpdp_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * Can't possibly predict what this instruction will do.
     * Don't do anything here.  Just return.
     */
}


/*
 * Decode all coprocessor register transfer instructions
 */
static void decode_cprt_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * Can't possibly predict what this instruction will do.
     * Don't do anything here.  Just return.
     */
}


/*
 * Decode all coprocessor load/store instructions
 */
static void decode_cpls_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * Can't possibly predict what this instruction will do.
     * Don't do anything here.  Just return.
     */
}


/*
 * Decode all branch/branch w/ link instructions
 */
static void decode_bbl_inst(ex_regs_t *regs, union arm_insn inst)
{
    unsigned long disp = inst.bbl.offset;

    /*
     * Sign extend the 24 bit value
     */
    if (disp & 0x00800000)
        disp |= 0xff000000;
    
    /*
     * Convert to long words
     */
    disp <<= 2;

    /*
     * Note: when the processor actually executes this instruction, the pc
     *       will point to the address of the current instruction + 8 because
     *       of the fetch/decode/execute cycle
     */
    disp += 8;
    
    insert_ss_break((unsigned long *)(regs->_pc + disp));
}


/*
 * Decode all swi instructions
 */
static void decode_swi_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * Can't possibly predict where we should set the breakpoint for this.
     * Don't do anything here.  Just return.
     */
}


/*
 * Decode all undefined instructions
 */
static void decode_undef_inst(ex_regs_t *regs, union arm_insn inst)
{
    /*
     * Can't possibly predict what this instruction will do.
     * Don't do anything here.  Just return.
     */
}


/*
 * Set breakpoint instructions for single stepping.
 */
void
bsp_singlestep_setup(void *registers)
{
    ex_regs_t *regs = (ex_regs_t *)registers;
    union arm_insn inst;

    if (bsp_memory_read((void*)(regs->_pc), 0, ARM_INST_SIZE * 8, 1, &(inst.word)) == 0)
    {
        /*
         * Unable to read the instruction at the current address.
         * Let's not do anything with this.  We can't set breakpoints
         * so let's get out now.
         */
        return;
    }

    /*
     * Handle the simple case -- linear code
     */
    insert_ss_break((unsigned long *)(regs->_pc + ARM_INST_SIZE));

    /*
     * Now, we need to decode the instructions and figure out what
     * they would do.
     */
    if ((inst.mrs.rsv1 == MRS_RSV1_VALUE) &&
        (inst.mrs.rsv2 == MRS_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("MRS type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_mrs_inst(regs, inst);
    } else if ((inst.misr.rsv1 == MISR_RSV1_VALUE) &&
               (inst.misr.rsv2 == MISR_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("MISR type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_misr_inst(regs, inst);
    } else if ((inst.mrsr.rsv1 == MRSR_RSV1_VALUE) &&
               (inst.mrsr.rsv2 == MRSR_RSV2_VALUE) &&
               (inst.mrsr.rsv3 == MRSR_RSV3_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("MRSR type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_mrsr_inst(regs, inst);
    } else if (inst.dpi.rsv1 == DPI_RSV1_VALUE) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("DPI type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_dpi_inst(regs, inst);
    } else if ((inst.bx.rsv1 == BX_RSV1_VALUE) &&
               (inst.bx.rsv2 == BX_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("BX type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_bx_inst(regs, inst);
    } else if ((inst.dpis.rsv1 == DPIS_RSV1_VALUE) &&
               (inst.dpis.rsv2 == DPIS_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("DPIS type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_dpis_inst(regs, inst);
    } else if ((inst.dprs.rsv1 == DPRS_RSV1_VALUE) &&
               (inst.dprs.rsv2 == DPRS_RSV2_VALUE) &&
               (inst.dprs.rsv3 == DPRS_RSV3_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("DPRS type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_dprs_inst(regs, inst);
    } else if ((inst.m.rsv1 == M_RSV1_VALUE) &&
               (inst.m.rsv2 == M_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("M type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_m_inst(regs, inst);
    } else if ((inst.ml.rsv1 == ML_RSV1_VALUE) &&
               (inst.ml.rsv2 == ML_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("ML type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_ml_inst(regs, inst);
    } else if (inst.lsio.rsv1 == LSIO_RSV1_VALUE) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("LSIO type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_lsio_inst(regs, inst);
    } else if ((inst.lsro.rsv1 == LSRO_RSV1_VALUE) &&
               (inst.lsro.rsv2 == LSRO_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("LSRO type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_lsro_inst(regs, inst);
    } else if ((inst.lshwi.rsv1 == LSHWI_RSV1_VALUE) &&
               (inst.lshwi.rsv2 == LSHWI_RSV2_VALUE) &&
               (inst.lshwi.rsv3 == LSHWI_RSV3_VALUE) &&
               (inst.lshwi.rsv4 == LSHWI_RSV4_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("LSHWI type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_lshwi_inst(regs, inst);
    } else if ((inst.lshwr.rsv1 == LSHWR_RSV1_VALUE) &&
               (inst.lshwr.rsv2 == LSHWR_RSV2_VALUE) &&
               (inst.lshwr.rsv3 == LSHWR_RSV3_VALUE) &&
               (inst.lshwr.rsv4 == LSHWR_RSV4_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("LSHWR type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_lshwr_inst(regs, inst);
    } else if ((inst.swap.rsv1 == SWAP_RSV1_VALUE) &&
               (inst.swap.rsv2 == SWAP_RSV2_VALUE) &&
               (inst.swap.rsv3 == SWAP_RSV3_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("SWAP type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_swap_inst(regs, inst);
    } else if (inst.lsm.rsv1 == LSM_RSV1_VALUE) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("LSM type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_lsm_inst(regs, inst);
    } else if ((inst.cpdp.rsv1 == CPDP_RSV1_VALUE) &&
               (inst.cpdp.rsv2 == CPDP_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("CPDP type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_cpdp_inst(regs, inst);
    } else if ((inst.cprt.rsv1 == CPRT_RSV1_VALUE) &&
               (inst.cprt.rsv2 == CPRT_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("CPRT type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_cprt_inst(regs, inst);
    } else if (inst.cpls.rsv1 == CPLS_RSV1_VALUE) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("CPLS type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_cpls_inst(regs, inst);
    } else if (inst.bbl.rsv1 == BBL_RSV1_VALUE) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("BBL type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_bbl_inst(regs, inst);
    } else if (inst.swi.rsv1 == SWI_RSV1_VALUE) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("SWI type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_swi_inst(regs, inst);
    } else if ((inst.undef.rsv1 == UNDEF_RSV1_VALUE) &&
               (inst.undef.rsv2 == UNDEF_RSV2_VALUE)) {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("UNDEF type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
        decode_undef_inst(regs, inst);
    } else {
#if DEBUG_SINGLESTEP_VERBOSE
        bsp_printf("Unknown instruction type: 0x%08lx\n", inst.word);
#endif /* DEBUG_SINGLESTEP_VERBOSE */
    }
}

void
bsp_skip_instruction(void *registers)
{
    ex_regs_t *regs = (ex_regs_t *)registers;
    regs->_pc += ARM_INST_SIZE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -