diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/target/arm11.c | 1613 | ||||
-rw-r--r-- | src/target/arm11.h | 166 | ||||
-rw-r--r-- | src/target/mips32_dmaacc.c | 881 | ||||
-rw-r--r-- | src/target/mips32_dmaacc.h | 106 | ||||
-rw-r--r-- | src/target/mips_m4k.c | 1 |
5 files changed, 1357 insertions, 1410 deletions
diff --git a/src/target/arm11.c b/src/target/arm11.c index f2adce85..f93e716a 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -36,68 +36,65 @@ #define _DEBUG_INSTRUCTION_EXECUTION_ #endif - #if 0 -#define FNC_INFO LOG_DEBUG("-") +#define FNC_INFO LOG_DEBUG("-") #else #define FNC_INFO #endif #if 1 -#define FNC_INFO_NOTIMPLEMENTED do { LOG_DEBUG("NOT IMPLEMENTED"); /*exit(-1);*/ } while (0) +#define FNC_INFO_NOTIMPLEMENTED do { LOG_DEBUG("NOT IMPLEMENTED"); /*exit(-1);*/ } while (0) #else #define FNC_INFO_NOTIMPLEMENTED #endif static void arm11_on_enter_debug_state(arm11_common_t * arm11); - bool arm11_config_memwrite_burst = true; bool arm11_config_memwrite_error_fatal = true; u32 arm11_vcr = 0; - #define ARM11_HANDLER(x) \ - .x = arm11_##x + .x = arm11_##x target_type_t arm11_target = { - .name = "arm11", + .name = "arm11", - ARM11_HANDLER(poll), - ARM11_HANDLER(arch_state), + ARM11_HANDLER(poll), + ARM11_HANDLER(arch_state), - ARM11_HANDLER(target_request_data), + ARM11_HANDLER(target_request_data), - ARM11_HANDLER(halt), - ARM11_HANDLER(resume), - ARM11_HANDLER(step), + ARM11_HANDLER(halt), + ARM11_HANDLER(resume), + ARM11_HANDLER(step), - ARM11_HANDLER(assert_reset), - ARM11_HANDLER(deassert_reset), - ARM11_HANDLER(soft_reset_halt), + ARM11_HANDLER(assert_reset), + ARM11_HANDLER(deassert_reset), + ARM11_HANDLER(soft_reset_halt), - ARM11_HANDLER(get_gdb_reg_list), + ARM11_HANDLER(get_gdb_reg_list), - ARM11_HANDLER(read_memory), - ARM11_HANDLER(write_memory), + ARM11_HANDLER(read_memory), + ARM11_HANDLER(write_memory), - ARM11_HANDLER(bulk_write_memory), + ARM11_HANDLER(bulk_write_memory), - ARM11_HANDLER(checksum_memory), + ARM11_HANDLER(checksum_memory), - ARM11_HANDLER(add_breakpoint), - ARM11_HANDLER(remove_breakpoint), - ARM11_HANDLER(add_watchpoint), - ARM11_HANDLER(remove_watchpoint), + ARM11_HANDLER(add_breakpoint), + ARM11_HANDLER(remove_breakpoint), + ARM11_HANDLER(add_watchpoint), + ARM11_HANDLER(remove_watchpoint), - ARM11_HANDLER(run_algorithm), + ARM11_HANDLER(run_algorithm), - ARM11_HANDLER(register_commands), - ARM11_HANDLER(target_create), - ARM11_HANDLER(init_target), - ARM11_HANDLER(examine), - ARM11_HANDLER(quit), + ARM11_HANDLER(register_commands), + ARM11_HANDLER(target_create), + ARM11_HANDLER(init_target), + ARM11_HANDLER(examine), + ARM11_HANDLER(quit), }; int arm11_regs_arch_type = -1; @@ -105,188 +102,188 @@ int arm11_regs_arch_type = -1; enum arm11_regtype { - ARM11_REGISTER_CORE, - ARM11_REGISTER_CPSR, - - ARM11_REGISTER_FX, - ARM11_REGISTER_FPS, - - ARM11_REGISTER_FIQ, - ARM11_REGISTER_SVC, - ARM11_REGISTER_ABT, - ARM11_REGISTER_IRQ, - ARM11_REGISTER_UND, - ARM11_REGISTER_MON, - - ARM11_REGISTER_SPSR_FIQ, - ARM11_REGISTER_SPSR_SVC, - ARM11_REGISTER_SPSR_ABT, - ARM11_REGISTER_SPSR_IRQ, - ARM11_REGISTER_SPSR_UND, - ARM11_REGISTER_SPSR_MON, - - /* debug regs */ - ARM11_REGISTER_DSCR, - ARM11_REGISTER_WDTR, - ARM11_REGISTER_RDTR, + ARM11_REGISTER_CORE, + ARM11_REGISTER_CPSR, + + ARM11_REGISTER_FX, + ARM11_REGISTER_FPS, + + ARM11_REGISTER_FIQ, + ARM11_REGISTER_SVC, + ARM11_REGISTER_ABT, + ARM11_REGISTER_IRQ, + ARM11_REGISTER_UND, + ARM11_REGISTER_MON, + + ARM11_REGISTER_SPSR_FIQ, + ARM11_REGISTER_SPSR_SVC, + ARM11_REGISTER_SPSR_ABT, + ARM11_REGISTER_SPSR_IRQ, + ARM11_REGISTER_SPSR_UND, + ARM11_REGISTER_SPSR_MON, + + /* debug regs */ + ARM11_REGISTER_DSCR, + ARM11_REGISTER_WDTR, + ARM11_REGISTER_RDTR, }; typedef struct arm11_reg_defs_s { - char * name; - u32 num; - int gdb_num; - enum arm11_regtype type; + char * name; + u32 num; + int gdb_num; + enum arm11_regtype type; } arm11_reg_defs_t; /* update arm11_regcache_ids when changing this */ static const arm11_reg_defs_t arm11_reg_defs[] = { - {"r0", 0, 0, ARM11_REGISTER_CORE}, - {"r1", 1, 1, ARM11_REGISTER_CORE}, - {"r2", 2, 2, ARM11_REGISTER_CORE}, - {"r3", 3, 3, ARM11_REGISTER_CORE}, - {"r4", 4, 4, ARM11_REGISTER_CORE}, - {"r5", 5, 5, ARM11_REGISTER_CORE}, - {"r6", 6, 6, ARM11_REGISTER_CORE}, - {"r7", 7, 7, ARM11_REGISTER_CORE}, - {"r8", 8, 8, ARM11_REGISTER_CORE}, - {"r9", 9, 9, ARM11_REGISTER_CORE}, - {"r10", 10, 10, ARM11_REGISTER_CORE}, - {"r11", 11, 11, ARM11_REGISTER_CORE}, - {"r12", 12, 12, ARM11_REGISTER_CORE}, - {"sp", 13, 13, ARM11_REGISTER_CORE}, - {"lr", 14, 14, ARM11_REGISTER_CORE}, - {"pc", 15, 15, ARM11_REGISTER_CORE}, + {"r0", 0, 0, ARM11_REGISTER_CORE}, + {"r1", 1, 1, ARM11_REGISTER_CORE}, + {"r2", 2, 2, ARM11_REGISTER_CORE}, + {"r3", 3, 3, ARM11_REGISTER_CORE}, + {"r4", 4, 4, ARM11_REGISTER_CORE}, + {"r5", 5, 5, ARM11_REGISTER_CORE}, + {"r6", 6, 6, ARM11_REGISTER_CORE}, + {"r7", 7, 7, ARM11_REGISTER_CORE}, + {"r8", 8, 8, ARM11_REGISTER_CORE}, + {"r9", 9, 9, ARM11_REGISTER_CORE}, + {"r10", 10, 10, ARM11_REGISTER_CORE}, + {"r11", 11, 11, ARM11_REGISTER_CORE}, + {"r12", 12, 12, ARM11_REGISTER_CORE}, + {"sp", 13, 13, ARM11_REGISTER_CORE}, + {"lr", 14, 14, ARM11_REGISTER_CORE}, + {"pc", 15, 15, ARM11_REGISTER_CORE}, #if ARM11_REGCACHE_FREGS - {"f0", 0, 16, ARM11_REGISTER_FX}, - {"f1", 1, 17, ARM11_REGISTER_FX}, - {"f2", 2, 18, ARM11_REGISTER_FX}, - {"f3", 3, 19, ARM11_REGISTER_FX}, - {"f4", 4, 20, ARM11_REGISTER_FX}, - {"f5", 5, 21, ARM11_REGISTER_FX}, - {"f6", 6, 22, ARM11_REGISTER_FX}, - {"f7", 7, 23, ARM11_REGISTER_FX}, - {"fps", 0, 24, ARM11_REGISTER_FPS}, + {"f0", 0, 16, ARM11_REGISTER_FX}, + {"f1", 1, 17, ARM11_REGISTER_FX}, + {"f2", 2, 18, ARM11_REGISTER_FX}, + {"f3", 3, 19, ARM11_REGISTER_FX}, + {"f4", 4, 20, ARM11_REGISTER_FX}, + {"f5", 5, 21, ARM11_REGISTER_FX}, + {"f6", 6, 22, ARM11_REGISTER_FX}, + {"f7", 7, 23, ARM11_REGISTER_FX}, + {"fps", 0, 24, ARM11_REGISTER_FPS}, #endif - {"cpsr", 0, 25, ARM11_REGISTER_CPSR}, + {"cpsr", 0, 25, ARM11_REGISTER_CPSR}, #if ARM11_REGCACHE_MODEREGS - {"r8_fiq", 8, -1, ARM11_REGISTER_FIQ}, - {"r9_fiq", 9, -1, ARM11_REGISTER_FIQ}, - {"r10_fiq", 10, -1, ARM11_REGISTER_FIQ}, - {"r11_fiq", 11, -1, ARM11_REGISTER_FIQ}, - {"r12_fiq", 12, -1, ARM11_REGISTER_FIQ}, - {"r13_fiq", 13, -1, ARM11_REGISTER_FIQ}, - {"r14_fiq", 14, -1, ARM11_REGISTER_FIQ}, - {"spsr_fiq", 0, -1, ARM11_REGISTER_SPSR_FIQ}, - - {"r13_svc", 13, -1, ARM11_REGISTER_SVC}, - {"r14_svc", 14, -1, ARM11_REGISTER_SVC}, - {"spsr_svc", 0, -1, ARM11_REGISTER_SPSR_SVC}, - - {"r13_abt", 13, -1, ARM11_REGISTER_ABT}, - {"r14_abt", 14, -1, ARM11_REGISTER_ABT}, - {"spsr_abt", 0, -1, ARM11_REGISTER_SPSR_ABT}, - - {"r13_irq", 13, -1, ARM11_REGISTER_IRQ}, - {"r14_irq", 14, -1, ARM11_REGISTER_IRQ}, - {"spsr_irq", 0, -1, ARM11_REGISTER_SPSR_IRQ}, - - {"r13_und", 13, -1, ARM11_REGISTER_UND}, - {"r14_und", 14, -1, ARM11_REGISTER_UND}, - {"spsr_und", 0, -1, ARM11_REGISTER_SPSR_UND}, - - /* ARM1176 only */ - {"r13_mon", 13, -1, ARM11_REGISTER_MON}, - {"r14_mon", 14, -1, ARM11_REGISTER_MON}, - {"spsr_mon", 0, -1, ARM11_REGISTER_SPSR_MON}, + {"r8_fiq", 8, -1, ARM11_REGISTER_FIQ}, + {"r9_fiq", 9, -1, ARM11_REGISTER_FIQ}, + {"r10_fiq", 10, -1, ARM11_REGISTER_FIQ}, + {"r11_fiq", 11, -1, ARM11_REGISTER_FIQ}, + {"r12_fiq", 12, -1, ARM11_REGISTER_FIQ}, + {"r13_fiq", 13, -1, ARM11_REGISTER_FIQ}, + {"r14_fiq", 14, -1, ARM11_REGISTER_FIQ}, + {"spsr_fiq", 0, -1, ARM11_REGISTER_SPSR_FIQ}, + + {"r13_svc", 13, -1, ARM11_REGISTER_SVC}, + {"r14_svc", 14, -1, ARM11_REGISTER_SVC}, + {"spsr_svc", 0, -1, ARM11_REGISTER_SPSR_SVC}, + + {"r13_abt", 13, -1, ARM11_REGISTER_ABT}, + {"r14_abt", 14, -1, ARM11_REGISTER_ABT}, + {"spsr_abt", 0, -1, ARM11_REGISTER_SPSR_ABT}, + + {"r13_irq", 13, -1, ARM11_REGISTER_IRQ}, + {"r14_irq", 14, -1, ARM11_REGISTER_IRQ}, + {"spsr_irq", 0, -1, ARM11_REGISTER_SPSR_IRQ}, + + {"r13_und", 13, -1, ARM11_REGISTER_UND}, + {"r14_und", 14, -1, ARM11_REGISTER_UND}, + {"spsr_und", 0, -1, ARM11_REGISTER_SPSR_UND}, + + /* ARM1176 only */ + {"r13_mon", 13, -1, ARM11_REGISTER_MON}, + {"r14_mon", 14, -1, ARM11_REGISTER_MON}, + {"spsr_mon", 0, -1, ARM11_REGISTER_SPSR_MON}, #endif - /* Debug Registers */ - {"dscr", 0, -1, ARM11_REGISTER_DSCR}, - {"wdtr", 0, -1, ARM11_REGISTER_WDTR}, - {"rdtr", 0, -1, ARM11_REGISTER_RDTR}, + /* Debug Registers */ + {"dscr", 0, -1, ARM11_REGISTER_DSCR}, + {"wdtr", 0, -1, ARM11_REGISTER_WDTR}, + {"rdtr", 0, -1, ARM11_REGISTER_RDTR}, }; enum arm11_regcache_ids { - ARM11_RC_R0, - ARM11_RC_RX = ARM11_RC_R0, - - ARM11_RC_R1, - ARM11_RC_R2, - ARM11_RC_R3, - ARM11_RC_R4, - ARM11_RC_R5, - ARM11_RC_R6, - ARM11_RC_R7, - ARM11_RC_R8, - ARM11_RC_R9, - ARM11_RC_R10, - ARM11_RC_R11, - ARM11_RC_R12, - ARM11_RC_R13, - ARM11_RC_SP = ARM11_RC_R13, - ARM11_RC_R14, - ARM11_RC_LR = ARM11_RC_R14, - ARM11_RC_R15, - ARM11_RC_PC = ARM11_RC_R15, + ARM11_RC_R0, + ARM11_RC_RX = ARM11_RC_R0, + + ARM11_RC_R1, + ARM11_RC_R2, + ARM11_RC_R3, + ARM11_RC_R4, + ARM11_RC_R5, + ARM11_RC_R6, + ARM11_RC_R7, + ARM11_RC_R8, + ARM11_RC_R9, + ARM11_RC_R10, + ARM11_RC_R11, + ARM11_RC_R12, + ARM11_RC_R13, + ARM11_RC_SP = ARM11_RC_R13, + ARM11_RC_R14, + ARM11_RC_LR = ARM11_RC_R14, + ARM11_RC_R15, + ARM11_RC_PC = ARM11_RC_R15, #if ARM11_REGCACHE_FREGS - ARM11_RC_F0, - ARM11_RC_FX = ARM11_RC_F0, - ARM11_RC_F1, - ARM11_RC_F2, - ARM11_RC_F3, - ARM11_RC_F4, - ARM11_RC_F5, - ARM11_RC_F6, - ARM11_RC_F7, - ARM11_RC_FPS, + ARM11_RC_F0, + ARM11_RC_FX = ARM11_RC_F0, + ARM11_RC_F1, + ARM11_RC_F2, + ARM11_RC_F3, + ARM11_RC_F4, + ARM11_RC_F5, + ARM11_RC_F6, + ARM11_RC_F7, + ARM11_RC_FPS, #endif - ARM11_RC_CPSR, + ARM11_RC_CPSR, #if ARM11_REGCACHE_MODEREGS - ARM11_RC_R8_FIQ, - ARM11_RC_R9_FIQ, - ARM11_RC_R10_FIQ, - ARM11_RC_R11_FIQ, - ARM11_RC_R12_FIQ, - ARM11_RC_R13_FIQ, - ARM11_RC_R14_FIQ, - ARM11_RC_SPSR_FIQ, - - ARM11_RC_R13_SVC, - ARM11_RC_R14_SVC, - ARM11_RC_SPSR_SVC, - - ARM11_RC_R13_ABT, - ARM11_RC_R14_ABT, - ARM11_RC_SPSR_ABT, - - ARM11_RC_R13_IRQ, - ARM11_RC_R14_IRQ, - ARM11_RC_SPSR_IRQ, - - ARM11_RC_R13_UND, - ARM11_RC_R14_UND, - ARM11_RC_SPSR_UND, - - ARM11_RC_R13_MON, - ARM11_RC_R14_MON, - ARM11_RC_SPSR_MON, + ARM11_RC_R8_FIQ, + ARM11_RC_R9_FIQ, + ARM11_RC_R10_FIQ, + ARM11_RC_R11_FIQ, + ARM11_RC_R12_FIQ, + ARM11_RC_R13_FIQ, + ARM11_RC_R14_FIQ, + ARM11_RC_SPSR_FIQ, + + ARM11_RC_R13_SVC, + ARM11_RC_R14_SVC, + ARM11_RC_SPSR_SVC, + + ARM11_RC_R13_ABT, + ARM11_RC_R14_ABT, + ARM11_RC_SPSR_ABT, + + ARM11_RC_R13_IRQ, + ARM11_RC_R14_IRQ, + ARM11_RC_SPSR_IRQ, + + ARM11_RC_R13_UND, + ARM11_RC_R14_UND, + ARM11_RC_SPSR_UND, + + ARM11_RC_R13_MON, + ARM11_RC_R14_MON, + ARM11_RC_SPSR_MON, #endif - ARM11_RC_DSCR, - ARM11_RC_WDTR, - ARM11_RC_RDTR, + ARM11_RC_DSCR, + ARM11_RC_WDTR, + ARM11_RC_RDTR, - ARM11_RC_MAX, + ARM11_RC_MAX, }; #define ARM11_GDB_REGISTER_COUNT 26 @@ -295,14 +292,14 @@ u8 arm11_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; reg_t arm11_gdb_dummy_fp_reg = { - "GDB dummy floating-point register", arm11_gdb_dummy_fp_value, 0, 1, 96, NULL, 0, NULL, 0 + "GDB dummy floating-point register", arm11_gdb_dummy_fp_value, 0, 1, 96, NULL, 0, NULL, 0 }; u8 arm11_gdb_dummy_fps_value[] = {0, 0, 0, 0}; reg_t arm11_gdb_dummy_fps_reg = { - "GDB dummy floating-point status register", arm11_gdb_dummy_fps_value, 0, 1, 32, NULL, 0, NULL, 0 + "GDB dummy floating-point status register", arm11_gdb_dummy_fps_value, 0, 1, 32, NULL, 0, NULL, 0 }; @@ -311,23 +308,23 @@ reg_t arm11_gdb_dummy_fps_reg = * * \param arm11 Target state variable. * \param dscr If the current DSCR content is - * available a pointer to a word holding the - * DSCR can be passed. Otherwise use NULL. + * available a pointer to a word holding the + * DSCR can be passed. Otherwise use NULL. */ void arm11_check_init(arm11_common_t * arm11, u32 * dscr) { - FNC_INFO; + FNC_INFO; - u32 dscr_local_tmp_copy; + u32 dscr_local_tmp_copy; - if (!dscr) - { + if (!dscr) + { dscr = &dscr_local_tmp_copy; *dscr = arm11_read_DSCR(arm11); - } + } - if (!(*dscr & ARM11_DSCR_MODE_SELECT)) - { + if (!(*dscr & ARM11_DSCR_MODE_SELECT)) + { LOG_DEBUG("Bringing target into debug mode"); *dscr |= ARM11_DSCR_MODE_SELECT; /* Halt debug-mode */ @@ -339,27 +336,27 @@ void arm11_check_init(arm11_common_t * arm11, u32 * dscr) if (*dscr & ARM11_DSCR_CORE_HALTED) { - /** \todo TODO: this needs further scrutiny because - * arm11_on_enter_debug_state() never gets properly called - */ + /** \todo TODO: this needs further scrutiny because + * arm11_on_enter_debug_state() never gets properly called + */ - arm11->target->state = TARGET_HALTED; - arm11->target->debug_reason = arm11_get_DSCR_debug_reason(*dscr); + arm11->target->state = TARGET_HALTED; + arm11->target->debug_reason = arm11_get_DSCR_debug_reason(*dscr); } else { - arm11->target->state = TARGET_RUNNING; - arm11->target->debug_reason = DBG_REASON_NOTHALTED; + arm11->target->state = TARGET_RUNNING; + arm11->target->debug_reason = DBG_REASON_NOTHALTED; } arm11_sc7_clear_vbw(arm11); - } + } } #define R(x) \ - (arm11->reg_values[ARM11_RC_##x]) + (arm11->reg_values[ARM11_RC_##x]) /** Save processor state. * @@ -369,23 +366,23 @@ void arm11_check_init(arm11_common_t * arm11, u32 * dscr) */ static void arm11_on_enter_debug_state(arm11_common_t * arm11) { - FNC_INFO; + FNC_INFO; - {size_t i; - for(i = 0; i < asizeof(arm11->reg_values); i++) - { + {size_t i; + for(i = 0; i < asizeof(arm11->reg_values); i++) + { arm11->reg_list[i].valid = 1; arm11->reg_list[i].dirty = 0; - }} + }} - /* Save DSCR */ + /* Save DSCR */ - R(DSCR) = arm11_read_DSCR(arm11); + R(DSCR) = arm11_read_DSCR(arm11); - /* Save wDTR */ + /* Save wDTR */ - if (R(DSCR) & ARM11_DSCR_WDTR_FULL) - { + if (R(DSCR) & ARM11_DSCR_WDTR_FULL) + { arm11_add_debug_SCAN_N(arm11, 0x05, -1); arm11_add_IR(arm11, ARM11_INTEST, -1); @@ -397,37 +394,37 @@ static void arm11_on_enter_debug_state(arm11_common_t * arm11) arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_PD); - } - else - { + } + else + { arm11->reg_list[ARM11_RC_WDTR].valid = 0; - } + } - /* DSCR: set ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE */ - /* ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode", but not to issue ITRs - ARM1136 seems to require this to issue ITR's as well */ + /* DSCR: set ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE */ + /* ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode", but not to issue ITRs + ARM1136 seems to require this to issue ITR's as well */ - u32 new_dscr = R(DSCR) | ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE; + u32 new_dscr = R(DSCR) | ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE; - /* this executes JTAG queue: */ + /* this executes JTAG queue: */ - arm11_write_DSCR(arm11, new_dscr); + arm11_write_DSCR(arm11, new_dscr); - /* From the spec: + /* From the spec: Before executing any instruction in debug state you have to drain the write buffer. - This ensures that no imprecise Data Aborts can return at a later point:*/ + This ensures that no imprecise Data Aborts can return at a later point:*/ - /** \todo TODO: Test drain write buffer. */ + /** \todo TODO: Test drain write buffer. */ #if 0 - while (1) - { + while (1) + { /* MRC p14,0,R0,c5,c10,0 */ // arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000); - /* mcr 15, 0, r0, cr7, cr10, {4} */ + /* mcr 15, 0, r0, cr7, cr10, {4} */ arm11_run_instr_no_data1(arm11, 0xee070f9a); u32 dscr = arm11_read_DSCR(arm11); @@ -436,74 +433,71 @@ static void arm11_on_enter_debug_state(arm11_common_t * arm11) if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT) { - arm11_run_instr_no_data1(arm11, 0xe320f000); + arm11_run_instr_no_data1(arm11, 0xe320f000); - dscr = arm11_read_DSCR(arm11); + dscr = arm11_read_DSCR(arm11); - LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr); + LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr); - break; + break; + } } - } #endif + arm11_run_instr_data_prepare(arm11); - arm11_run_instr_data_prepare(arm11); - - /* save r0 - r14 */ + /* save r0 - r14 */ + /** \todo TODO: handle other mode registers */ - /** \todo TODO: handle other mode registers */ - - {size_t i; - for (i = 0; i < 15; i++) - { + {size_t i; + for (i = 0; i < 15; i++) + { /* MCR p14,0,R?,c0,c5,0 */ arm11_run_instr_data_from_core(arm11, 0xEE000E15 | (i << 12), &R(RX + i), 1); - }} - + }} - /* save rDTR */ + /* save rDTR */ - /* check rDTRfull in DSCR */ + /* check rDTRfull in DSCR */ - if (R(DSCR) & ARM11_DSCR_RDTR_FULL) - { + if (R(DSCR) & ARM11_DSCR_RDTR_FULL) + { /* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */ arm11_run_instr_data_from_core_via_r0(arm11, 0xEE100E15, &R(RDTR)); - } - else - { + } + else + { arm11->reg_list[ARM11_RC_RDTR].valid = 0; - } + } - /* save CPSR */ + /* save CPSR */ - /* MRS r0,CPSR (move CPSR -> r0 (-> wDTR -> local var)) */ - arm11_run_instr_data_from_core_via_r0(arm11, 0xE10F0000, &R(CPSR)); + /* MRS r0,CPSR (move CPSR -> r0 (-> wDTR -> local var)) */ + arm11_run_instr_data_from_core_via_r0(arm11, 0xE10F0000, &R(CPSR)); - /* save PC */ + /* save PC */ - /* MOV R0,PC (move PC -> r0 (-> wDTR -> local var)) */ - arm11_run_instr_data_from_core_via_r0(arm11, 0xE1A0000F, &R(PC)); + /* MOV R0,PC (move PC -> r0 (-> wDTR -> local var)) */ + arm11_run_instr_data_from_core_via_r0(arm11, 0xE1A0000F, &R(PC)); - /* adjust PC depending on ARM state */ + /* adjust PC depending on ARM state */ - if (R(CPSR) & ARM11_CPSR_J) /* Java state */ - { + if (R(CPSR) & ARM11_CPSR_J) /* Java state */ + { arm11->reg_values[ARM11_RC_PC] -= 0; - } - else if (R(CPSR) & ARM11_CPSR_T) /* Thumb state */ - { + } + else if (R(CPSR) & ARM11_CPSR_T) /* Thumb state */ + { arm11->reg_values[ARM11_RC_PC] -= 4; - } - else /* ARM state */ - { + } + else /* ARM state */ + { arm11->reg_values[ARM11_RC_PC] -= 8; - } + } - if (arm11->simulate_reset_on_next_halt) - { + if (arm11->simulate_reset_on_next_halt) + { arm11->simulate_reset_on_next_halt = false; LOG_DEBUG("Reset c1 Control Register"); @@ -513,39 +507,38 @@ static void arm11_on_enter_debug_state(arm11_common_t * arm11) /* MCR p15,0,R0,c1,c0,0 */ arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0); - } + } - arm11_run_instr_data_finish(arm11); + arm11_run_instr_data_finish(arm11); - arm11_dump_reg_changes(arm11); + arm11_dump_reg_changes(arm11); } void arm11_dump_reg_changes(arm11_common_t * arm11) { - {size_t i; - for(i = 0; i < ARM11_REGCACHE_COUNT; i++) - { + {size_t i; + for(i = 0; i < ARM11_REGCACHE_COUNT; i++) + { if (!arm11->reg_list[i].valid) { - if (arm11->reg_history[i].valid) - LOG_INFO("%8s INVALID (%08x)", arm11_reg_defs[i].name, arm11->reg_history[i].value); + if (arm11->reg_history[i].valid) + LOG_INFO("%8s INVALID (%08x)", arm11_reg_defs[i].name, arm11->reg_history[i].value); } else { - if (arm11->reg_history[i].valid) - { + if (arm11->reg_history[i].valid) + { if (arm11->reg_history[i].value != arm11->reg_values[i]) - LOG_INFO("%8s %08x (%08x)", arm11_reg_defs[i].name, arm11->reg_values[i], arm11->reg_history[i].value); - } - else - { + LOG_INFO("%8s %08x (%08x)", arm11_reg_defs[i].name, arm11->reg_values[i], arm11->reg_history[i].value); + } + else + { LOG_INFO("%8s %08x (INVALID)", arm11_reg_defs[i].name, arm11->reg_values[i]); - } + } } - }} + }} } - /** Restore processor state * * This is called in preparation for the RESTART function. @@ -553,271 +546,262 @@ void arm11_dump_reg_changes(arm11_common_t * arm11) */ void arm11_leave_debug_state(arm11_common_t * arm11) { - FNC_INFO; + FNC_INFO; - arm11_run_instr_data_prepare(arm11); + arm11_run_instr_data_prepare(arm11); - /** \todo TODO: handle other mode registers */ + /** \todo TODO: handle other mode registers */ - /* restore R1 - R14 */ - {size_t i; - for (i = 1; i < 15; i++) - { + /* restore R1 - R14 */ + {size_t i; + for (i = 1; i < 15; i++) + { if (!arm11->reg_list[ARM11_RC_RX + i].dirty) - continue; + continue; /* MRC p14,0,r?,c0,c5,0 */ arm11_run_instr_data_to_core1(arm11, 0xee100e15 | (i << 12), R(RX + i)); // LOG_DEBUG("RESTORE R" ZU " %08x", i, R(RX + i)); - }} - - arm11_run_instr_data_finish(arm11); + }} + arm11_run_instr_data_finish(arm11); - /* spec says clear wDTR and rDTR; we assume they are clear as - otherwise our programming would be sloppy */ + /* spec says clear wDTR and rDTR; we assume they are clear as + otherwise our programming would be sloppy */ - { + { u32 DSCR = arm11_read_DSCR(arm11); if (DSCR & (ARM11_DSCR_RDTR_FULL | ARM11_DSCR_WDTR_FULL)) { - LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08x)", DSCR); + LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08x)", DSCR); + } } - } - arm11_run_instr_data_prepare(arm11); + arm11_run_instr_data_prepare(arm11); - /* restore original wDTR */ + /* restore original wDTR */ - if ((R(DSCR) & ARM11_DSCR_WDTR_FULL) || arm11->reg_list[ARM11_RC_WDTR].dirty) - { + if ((R(DSCR) & ARM11_DSCR_WDTR_FULL) || arm11->reg_list[ARM11_RC_WDTR].dirty) + { /* MCR p14,0,R0,c0,c5,0 */ arm11_run_instr_data_to_core_via_r0(arm11, 0xee000e15, R(WDTR)); - } - - /* restore CPSR */ - - /* MSR CPSR,R0*/ - arm11_run_instr_data_to_core_via_r0(arm11, 0xe129f000, R(CPSR)); - - - /* restore PC */ + } - /* MOV PC,R0 */ - arm11_run_instr_data_to_core_via_r0(arm11, 0xe1a0f000, R(PC)); + /* restore CPSR */ + /* MSR CPSR,R0*/ + arm11_run_instr_data_to_core_via_r0(arm11, 0xe129f000, R(CPSR)); - /* restore R0 */ + /* restore PC */ - /* MRC p14,0,r0,c0,c5,0 */ - arm11_run_instr_data_to_core1(arm11, 0xee100e15, R(R0)); + /* MOV PC,R0 */ + arm11_run_instr_data_to_core_via_r0(arm11, 0xe1a0f000, R(PC)); - arm11_run_instr_data_finish(arm11); + /* restore R0 */ + /* MRC p14,0,r0,c0,c5,0 */ + arm11_run_instr_data_to_core1(arm11, 0xee100e15, R(R0)); - /* restore DSCR */ + arm11_run_instr_data_finish(arm11); - arm11_write_DSCR(arm11, R(DSCR)); + /* restore DSCR */ + arm11_write_DSCR(arm11, R(DSCR)); - /* restore rDTR */ + /* restore rDTR */ - if (R(DSCR) & ARM11_DSCR_RDTR_FULL || arm11->reg_list[ARM11_RC_RDTR].dirty) - { + if (R(DSCR) & ARM11_DSCR_RDTR_FULL || arm11->reg_list[ARM11_RC_RDTR].dirty) + { arm11_add_debug_SCAN_N(arm11, 0x05, -1); arm11_add_IR(arm11, ARM11_EXTEST, -1); scan_field_t chain5_fields[3]; - u8 Ready = 0; /* ignored */ - u8 Valid = 0; /* ignored */ + u8 Ready = 0; /* ignored */ + u8 Valid = 0; /* ignored */ arm11_setup_field(arm11, 32, &R(RDTR), NULL, chain5_fields + 0); arm11_setup_field(arm11, 1, &Ready, NULL, chain5_fields + 1); arm11_setup_field(arm11, 1, &Valid, NULL, chain5_fields + 2); arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_PD); - } + } - arm11_record_register_history(arm11); + arm11_record_register_history(arm11); } void arm11_record_register_history(arm11_common_t * arm11) { - {size_t i; - for(i = 0; i < ARM11_REGCACHE_COUNT; i++) - { + {size_t i; + for(i = 0; i < ARM11_REGCACHE_COUNT; i++) + { arm11->reg_history[i].value = arm11->reg_values[i]; arm11->reg_history[i].valid = arm11->reg_list[i].valid; arm11->reg_list[i].valid = 0; arm11->reg_list[i].dirty = 0; - }} + }} } /* poll current target status */ int arm11_poll(struct target_s *target) { - FNC_INFO; + FNC_INFO; - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - if (arm11->trst_active) + if (arm11->trst_active) return ERROR_OK; - u32 dscr = arm11_read_DSCR(arm11); + u32 dscr = arm11_read_DSCR(arm11); - LOG_DEBUG("DSCR %08x", dscr); + LOG_DEBUG("DSCR %08x", dscr); - arm11_check_init(arm11, &dscr); + arm11_check_init(arm11, &dscr); - if (dscr & ARM11_DSCR_CORE_HALTED) - { + if (dscr & ARM11_DSCR_CORE_HALTED) + { if (target->state != TARGET_HALTED) { - enum target_state old_state = target->state; + enum target_state old_state = target->state; - LOG_DEBUG("enter TARGET_HALTED"); - target->state = TARGET_HALTED; - target->debug_reason = arm11_get_DSCR_debug_reason(dscr); - arm11_on_enter_debug_state(arm11); + LOG_DEBUG("enter TARGET_HALTED"); + target->state = TARGET_HALTED; + target->debug_reason = arm11_get_DSCR_debug_reason(dscr); + arm11_on_enter_debug_state(arm11); - target_call_event_callbacks(target, + target_call_event_callbacks(target, old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED); } - } - else - { + } + else + { if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) { - LOG_DEBUG("enter TARGET_RUNNING"); - target->state = TARGET_RUNNING; - target->debug_reason = DBG_REASON_NOTHALTED; + LOG_DEBUG("enter TARGET_RUNNING"); + target->state = TARGET_RUNNING; + target->debug_reason = DBG_REASON_NOTHALTED; + } } - } - return ERROR_OK; + return ERROR_OK; } /* architecture specific status reply */ int arm11_arch_state(struct target_s *target) { - FNC_INFO_NOTIMPLEMENTED; + FNC_INFO_NOTIMPLEMENTED; - return ERROR_OK; + return ERROR_OK; } - /* target request support */ int arm11_target_request_data(struct target_s *target, u32 size, u8 *buffer) { - FNC_INFO_NOTIMPLEMENTED; + FNC_INFO_NOTIMPLEMENTED; - return ERROR_OK; + return ERROR_OK; } - - /* target execution control */ int arm11_halt(struct target_s *target) { - FNC_INFO; + FNC_INFO; - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - LOG_DEBUG("target->state: %s", - Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); + LOG_DEBUG("target->state: %s", + Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); - if (target->state == TARGET_UNKNOWN) - { + if (target->state == TARGET_UNKNOWN) + { arm11->simulate_reset_on_next_halt = true; - } + } - if (target->state == TARGET_HALTED) - { + if (target->state == TARGET_HALTED) + { LOG_DEBUG("target was already halted"); return ERROR_OK; - } + } - if (arm11->trst_active) - { + if (arm11->trst_active) + { arm11->halt_requested = true; return ERROR_OK; - } + } - arm11_add_IR(arm11, ARM11_HALT, TAP_RTI); + arm11_add_IR(arm11, ARM11_HALT, TAP_RTI); - jtag_execute_queue(); + jtag_execute_queue(); - u32 dscr; + u32 dscr; - while (1) - { + while (1) + { dscr = arm11_read_DSCR(arm11); if (dscr & ARM11_DSCR_CORE_HALTED) - break; - } + break; + } - arm11_on_enter_debug_state(arm11); + arm11_on_enter_debug_state(arm11); - enum target_state old_state = target->state; + enum target_state old_state = target->state; - target->state = TARGET_HALTED; - target->debug_reason = arm11_get_DSCR_debug_reason(dscr); + target->state = TARGET_HALTED; + target->debug_reason = arm11_get_DSCR_debug_reason(dscr); - target_call_event_callbacks(target, + target_call_event_callbacks(target, old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED); - return ERROR_OK; + return ERROR_OK; } - int arm11_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution) { - FNC_INFO; + FNC_INFO; -// LOG_DEBUG("current %d address %08x handle_breakpoints %d debug_execution %d", +// LOG_DEBUG("current %d address %08x handle_breakpoints %d debug_execution %d", // current, address, handle_breakpoints, debug_execution); - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - LOG_DEBUG("target->state: %s", - Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); + LOG_DEBUG("target->state: %s", + Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); - if (target->state != TARGET_HALTED) + if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - if (!current) + if (!current) R(PC) = address; - LOG_INFO("RESUME PC %08x%s", R(PC), !current ? "!" : ""); + LOG_INFO("RESUME PC %08x%s", R(PC), !current ? "!" : ""); - /* clear breakpoints/watchpoints and VCR*/ - arm11_sc7_clear_vbw(arm11); + /* clear breakpoints/watchpoints and VCR*/ + arm11_sc7_clear_vbw(arm11); - /* Set up breakpoints */ - if (!debug_execution) - { + /* Set up breakpoints */ + if (!debug_execution) + { /* check if one matches PC and step over it if necessary */ breakpoint_t * bp; for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->address == R(PC)) - { + if (bp->address == R(PC)) + { LOG_DEBUG("must step over %08x", bp->address); arm11_step(target, 1, 0, 0); break; - } + } } /* set all breakpoints */ @@ -826,108 +810,107 @@ int arm11_resume(struct target_s *target, int current, u32 address, int handle_b for (bp = target->breakpoints; bp; bp = bp->next) { - arm11_sc7_action_t brp[2]; + arm11_sc7_action_t brp[2]; - brp[0].write = 1; - brp[0].address = ARM11_SC7_BVR0 + brp_num; - brp[0].value = bp->address; - brp[1].write = 1; - brp[1].address = ARM11_SC7_BCR0 + brp_num; - brp[1].value = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21); + brp[0].write = 1; + brp[0].address = ARM11_SC7_BVR0 + brp_num; + brp[0].value = bp->address; + brp[1].write = 1; + brp[1].address = ARM11_SC7_BCR0 + brp_num; + brp[1].value = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21); - arm11_sc7_run(arm11, brp, asizeof(brp)); + arm11_sc7_run(arm11, brp, asizeof(brp)); - LOG_DEBUG("Add BP " ZU " at %08x", brp_num, bp->address); + LOG_DEBUG("Add BP " ZU " at %08x", brp_num, bp->address); - brp_num++; + brp_num++; } arm11_sc7_set_vcr(arm11, arm11_vcr); - } - + } - arm11_leave_debug_state(arm11); + arm11_leave_debug_state(arm11); - arm11_add_IR(arm11, ARM11_RESTART, TAP_RTI); + arm11_add_IR(arm11, ARM11_RESTART, TAP_RTI); - jtag_execute_queue(); + jtag_execute_queue(); - while (1) - { + while (1) + { u32 dscr = arm11_read_DSCR(arm11); LOG_DEBUG("DSCR %08x", dscr); if (dscr & ARM11_DSCR_CORE_RESTARTED) - break; - } + break; + } - if (!debug_execution) - { + if (!debug_execution) + { target->state = TARGET_RUNNING; target->debug_reason = DBG_REASON_NOTHALTED; target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - } - else - { + } + else + { target->state = TARGET_DEBUG_RUNNING; target->debug_reason = DBG_REASON_NOTHALTED; target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - } + } - return ERROR_OK; + return ERROR_OK; } int arm11_step(struct target_s *target, int current, u32 address, int handle_breakpoints) { - FNC_INFO; + FNC_INFO; - LOG_DEBUG("target->state: %s", - Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); + LOG_DEBUG("target->state: %s", + Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) + { LOG_WARNING("target was not halted"); return ERROR_TARGET_NOT_HALTED; - } + } - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - if (!current) + if (!current) R(PC) = address; - LOG_INFO("STEP PC %08x%s", R(PC), !current ? "!" : ""); + LOG_INFO("STEP PC %08x%s", R(PC), !current ? "!" : ""); - /** \todo TODO: Thumb not supported here */ + /** \todo TODO: Thumb not supported here */ - u32 next_instruction; + u32 next_instruction; - arm11_read_memory_word(arm11, R(PC), &next_instruction); + arm11_read_memory_word(arm11, R(PC), &next_instruction); - /* skip over BKPT */ - if ((next_instruction & 0xFFF00070) == 0xe1200070) - { + /* skip over BKPT */ + if ((next_instruction & 0xFFF00070) == 0xe1200070) + { R(PC) += 4; arm11->reg_list[ARM11_RC_PC].valid = 1; arm11->reg_list[ARM11_RC_PC].dirty = 0; LOG_INFO("Skipping BKPT"); - } - /* skip over Wait for interrupt / Standby */ - /* mcr 15, 0, r?, cr7, cr0, {4} */ - else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90) - { + } + /* skip over Wait for interrupt / Standby */ + /* mcr 15, 0, r?, cr7, cr0, {4} */ + else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90) + { R(PC) += 4; arm11->reg_list[ARM11_RC_PC].valid = 1; arm11->reg_list[ARM11_RC_PC].dirty = 0; LOG_INFO("Skipping WFI"); - } - /* ignore B to self */ - else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe) - { + } + /* ignore B to self */ + else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe) + { LOG_INFO("Not stepping jump to self"); - } - else - { + } + else + { /** \todo TODO: check if break-/watchpoints make any sense at all in combination * with this. */ @@ -962,11 +945,11 @@ int arm11_step(struct target_s *target, int current, u32 address, int handle_bre while (1) { - u32 dscr = arm11_read_DSCR(arm11); + u32 dscr = arm11_read_DSCR(arm11); - LOG_DEBUG("DSCR %08x", dscr); + LOG_DEBUG("DSCR %08x", dscr); - if ((dscr & (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) == + if ((dscr & (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) == (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) break; } @@ -976,154 +959,149 @@ int arm11_step(struct target_s *target, int current, u32 address, int handle_bre /* save state */ arm11_on_enter_debug_state(arm11); - } + } -// target->state = TARGET_HALTED; - target->debug_reason = DBG_REASON_SINGLESTEP; +// target->state = TARGET_HALTED; + target->debug_reason = DBG_REASON_SINGLESTEP; - target_call_event_callbacks(target, TARGET_EVENT_HALTED); + target_call_event_callbacks(target, TARGET_EVENT_HALTED); - return ERROR_OK; + return ERROR_OK; } - /* target reset control */ int arm11_assert_reset(struct target_s *target) { - FNC_INFO; + FNC_INFO; #if 0 - /* assert reset lines */ - /* resets only the DBGTAP, not the ARM */ + /* assert reset lines */ + /* resets only the DBGTAP, not the ARM */ - jtag_add_reset(1, 0); - jtag_add_sleep(5000); + jtag_add_reset(1, 0); + jtag_add_sleep(5000); - arm11_common_t * arm11 = target->arch_info; - arm11->trst_active = true; + arm11_common_t * arm11 = target->arch_info; + arm11->trst_active = true; #endif - if (target->reset_halt) - { - int retval; + if (target->reset_halt) + { + int retval; if ((retval = target_halt(target))!=ERROR_OK) return retval; - } + } - return ERROR_OK; + return ERROR_OK; } int arm11_deassert_reset(struct target_s *target) { - FNC_INFO; + FNC_INFO; #if 0 - LOG_DEBUG("target->state: %s", - Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); + LOG_DEBUG("target->state: %s", + Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); - /* deassert reset lines */ - jtag_add_reset(0, 0); + /* deassert reset lines */ + jtag_add_reset(0, 0); - arm11_common_t * arm11 = target->arch_info; - arm11->trst_active = false; + arm11_common_t * arm11 = target->arch_info; + arm11->trst_active = false; - if (arm11->halt_requested) + if (arm11->halt_requested) return arm11_halt(target); #endif - return ERROR_OK; + return ERROR_OK; } int arm11_soft_reset_halt(struct target_s *target) { - FNC_INFO_NOTIMPLEMENTED; + FNC_INFO_NOTIMPLEMENTED; - return ERROR_OK; + return ERROR_OK; } - - /* target register access for gdb */ int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size) { - FNC_INFO; + FNC_INFO; - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - *reg_list_size = ARM11_GDB_REGISTER_COUNT; - *reg_list = malloc(sizeof(reg_t*) * ARM11_GDB_REGISTER_COUNT); + *reg_list_size = ARM11_GDB_REGISTER_COUNT; + *reg_list = malloc(sizeof(reg_t*) * ARM11_GDB_REGISTER_COUNT); - {size_t i; - for (i = 16; i < 24; i++) - { + {size_t i; + for (i = 16; i < 24; i++) + { (*reg_list)[i] = &arm11_gdb_dummy_fp_reg; - }} - - (*reg_list)[24] = &arm11_gdb_dummy_fps_reg; + }} + (*reg_list)[24] = &arm11_gdb_dummy_fps_reg; - {size_t i; - for (i = 0; i < ARM11_REGCACHE_COUNT; i++) - { + {size_t i; + for (i = 0; i < ARM11_REGCACHE_COUNT; i++) + { if (arm11_reg_defs[i].gdb_num == -1) - continue; + continue; (*reg_list)[arm11_reg_defs[i].gdb_num] = arm11->reg_list + i; - }} + }} - return ERROR_OK; + return ERROR_OK; } - /* target memory access * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit) * count: number of items of <size> */ int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer) { - /** \todo TODO: check if buffer cast to u32* and u16* might cause alignment problems */ + /** \todo TODO: check if buffer cast to u32* and u16* might cause alignment problems */ - FNC_INFO; + FNC_INFO; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) + { LOG_WARNING("target was not halted"); return ERROR_TARGET_NOT_HALTED; - } + } - LOG_DEBUG("ADDR %08x SIZE %08x COUNT %08x", address, size, count); + LOG_DEBUG("ADDR %08x SIZE %08x COUNT %08x", address, size, count); - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - arm11_run_instr_data_prepare(arm11); + arm11_run_instr_data_prepare(arm11); - /* MRC p14,0,r0,c0,c5,0 */ - arm11_run_instr_data_to_core1(arm11, 0xee100e15, address); + /* MRC p14,0,r0,c0,c5,0 */ + arm11_run_instr_data_to_core1(arm11, 0xee100e15, address); - switch (size) - { - case 1: + switch (size) + { + case 1: /** \todo TODO: check if dirty is the right choice to force a rewrite on arm11_resume() */ arm11->reg_list[ARM11_RC_R1].dirty = 1; {size_t i; for (i = 0; i < count; i++) { - /* ldrb r1, [r0], #1 */ - arm11_run_instr_no_data1(arm11, 0xe4d01001); + /* ldrb r1, [r0], #1 */ + arm11_run_instr_no_data1(arm11, 0xe4d01001); - u32 res; - /* MCR p14,0,R1,c0,c5,0 */ - arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1); + u32 res; + /* MCR p14,0,R1,c0,c5,0 */ + arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1); - *buffer++ = res; + *buffer++ = res; }} break; - case 2: - { + case 2: + { arm11->reg_list[ARM11_RC_R1].dirty = 1; u16 * buf16 = (u16*)buffer; @@ -1131,72 +1109,72 @@ int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count, {size_t i; for (i = 0; i < count; i++) { - /* ldrh r1, [r0], #2 */ - arm11_run_instr_no_data1(arm11, 0xe0d010b2); + /* ldrh r1, [r0], #2 */ + arm11_run_instr_no_data1(arm11, 0xe0d010b2); - u32 res; + u32 res; - /* MCR p14,0,R1,c0,c5,0 */ - arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1); + /* MCR p14,0,R1,c0,c5,0 */ + arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1); - *buf16++ = res; + *buf16++ = res; }} break; - } + } - case 4: + case 4: /* LDC p14,c5,[R0],#4 */ arm11_run_instr_data_from_core(arm11, 0xecb05e01, (u32 *)buffer, count); break; - } + } - arm11_run_instr_data_finish(arm11); + arm11_run_instr_data_finish(arm11); - return ERROR_OK; + return ERROR_OK; } int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer) { - FNC_INFO; + FNC_INFO; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) + { LOG_WARNING("target was not halted"); return ERROR_TARGET_NOT_HALTED; - } + } - LOG_DEBUG("ADDR %08x SIZE %08x COUNT %08x", address, size, count); + LOG_DEBUG("ADDR %08x SIZE %08x COUNT %08x", address, size, count); - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - arm11_run_instr_data_prepare(arm11); + arm11_run_instr_data_prepare(arm11); - /* MRC p14,0,r0,c0,c5,0 */ - arm11_run_instr_data_to_core1(arm11, 0xee100e15, address); + /* MRC p14,0,r0,c0,c5,0 */ + arm11_run_instr_data_to_core1(arm11, 0xee100e15, address); - switch (size) - { - case 1: - { + switch (size) + { + case 1: + { arm11->reg_list[ARM11_RC_R1].dirty = 1; {size_t i; for (i = 0; i < count; i++) { - /* MRC p14,0,r1,c0,c5,0 */ - arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++); + /* MRC p14,0,r1,c0,c5,0 */ + arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++); - /* strb r1, [r0], #1 */ - arm11_run_instr_no_data1(arm11, 0xe4c01001); + /* strb r1, [r0], #1 */ + arm11_run_instr_no_data1(arm11, 0xe4c01001); }} break; - } + } - case 2: - { + case 2: + { arm11->reg_list[ARM11_RC_R1].dirty = 1; u16 * buf16 = (u16*)buffer; @@ -1204,36 +1182,36 @@ int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count {size_t i; for (i = 0; i < count; i++) { - /* MRC p14,0,r1,c0,c5,0 */ - arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buf16++); + /* MRC p14,0,r1,c0,c5,0 */ + arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buf16++); - /* strh r1, [r0], #2 */ - arm11_run_instr_no_data1(arm11, 0xe0c010b2); + /* strh r1, [r0], #2 */ + arm11_run_instr_no_data1(arm11, 0xe0c010b2); }} break; - } + } - case 4: + case 4: /** \todo TODO: check if buffer cast to u32* might cause alignment problems */ if (!arm11_config_memwrite_burst) { - /* STC p14,c5,[R0],#4 */ - arm11_run_instr_data_to_core(arm11, 0xeca05e01, (u32 *)buffer, count); + /* STC p14,c5,[R0],#4 */ + arm11_run_instr_data_to_core(arm11, 0xeca05e01, (u32 *)buffer, count); } else { - /* STC p14,c5,[R0],#4 */ - arm11_run_instr_data_to_core_noack(arm11, 0xeca05e01, (u32 *)buffer, count); + /* STC p14,c5,[R0],#4 */ + arm11_run_instr_data_to_core_noack(arm11, 0xeca05e01, (u32 *)buffer, count); } break; - } + } #if 1 - /* r0 verification */ - { + /* r0 verification */ + { u32 r0; /* MCR p14,0,R0,c0,c5,0 */ @@ -1241,107 +1219,101 @@ int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count if (address + size * count != r0) { - LOG_ERROR("Data transfer failed. (%d)", (r0 - address) - size * count); + LOG_ERROR("Data transfer failed. (%d)", (r0 - address) - size * count); - if (arm11_config_memwrite_burst) + if (arm11_config_memwrite_burst) LOG_ERROR("use 'arm11 memwrite burst disable' to disable fast burst mode"); - if (arm11_config_memwrite_error_fatal) - return ERROR_FAIL; + if (arm11_config_memwrite_error_fatal) + return ERROR_FAIL; + } } - } #endif + arm11_run_instr_data_finish(arm11); - arm11_run_instr_data_finish(arm11); - - - - - return ERROR_OK; + return ERROR_OK; } /* write target memory in multiples of 4 byte, optimized for writing large quantities of data */ int arm11_bulk_write_memory(struct target_s *target, u32 address, u32 count, u8 *buffer) { - FNC_INFO; + FNC_INFO; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) + { LOG_WARNING("target was not halted"); return ERROR_TARGET_NOT_HALTED; - } + } - return arm11_write_memory(target, address, 4, count, buffer); + return arm11_write_memory(target, address, 4, count, buffer); } - int arm11_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum) { - FNC_INFO_NOTIMPLEMENTED; + FNC_INFO_NOTIMPLEMENTED; - return ERROR_OK; + return ERROR_OK; } - /* target break-/watchpoint control * rw: 0 = write, 1 = read, 2 = access */ int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint) { - FNC_INFO; + FNC_INFO; - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; #if 0 - if (breakpoint->type == BKPT_SOFT) - { + if (breakpoint->type == BKPT_SOFT) + { LOG_INFO("sw breakpoint requested, but software breakpoints not enabled"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + } #endif - if (!arm11->free_brps) - { + if (!arm11->free_brps) + { LOG_INFO("no breakpoint unit available for hardware breakpoint"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + } - if (breakpoint->length != 4) - { + if (breakpoint->length != 4) + { LOG_INFO("only breakpoints of four bytes length supported"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + } - arm11->free_brps--; + arm11->free_brps--; - return ERROR_OK; + return ERROR_OK; } int arm11_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint) { - FNC_INFO; + FNC_INFO; - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - arm11->free_brps++; + arm11->free_brps++; - return ERROR_OK; + return ERROR_OK; } int arm11_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint) { - FNC_INFO_NOTIMPLEMENTED; + FNC_INFO_NOTIMPLEMENTED; - return ERROR_OK; + return ERROR_OK; } int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint) { - FNC_INFO_NOTIMPLEMENTED; + FNC_INFO_NOTIMPLEMENTED; - return ERROR_OK; + return ERROR_OK; } // HACKHACKHACK - FIXME mode/state @@ -1350,7 +1322,7 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info) { - arm11_common_t *arm11 = target->arch_info; + arm11_common_t *arm11 = target->arch_info; armv4_5_algorithm_t *arm11_algorithm_info = arch_info; // enum armv4_5_state core_state = arm11->core_state; // enum armv4_5_mode core_mode = arm11->core_mode; @@ -1359,7 +1331,7 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t int exit_breakpoint_size = 0; int i; int retval = ERROR_OK; - LOG_DEBUG("Running algorithm"); + LOG_DEBUG("Running algorithm"); if (arm11_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC) { @@ -1385,7 +1357,7 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t } cpsr = buf_get_u32((u8*)(arm11->reg_values+ARM11_RC_CPSR),0,32); - LOG_DEBUG("Save CPSR: 0x%x",i,cpsr); + LOG_DEBUG("Save CPSR: 0x%x", cpsr); for (i = 0; i < num_mem_params; i++) { @@ -1396,7 +1368,6 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t for (i = 0; i < num_reg_params; i++) { reg_t *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0); - u32 val; if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); @@ -1416,7 +1387,7 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t /* arm11->core_state = arm11_algorithm_info->core_state; if (arm11->core_state == ARMV4_5_STATE_ARM) - exit_breakpoint_size = 4; + exit_breakpoint_size = 4; else if (arm11->core_state == ARMV4_5_STATE_THUMB) exit_breakpoint_size = 2; else @@ -1499,10 +1470,10 @@ restore: { LOG_DEBUG("restoring register %s with value 0x%8.8x", arm11->reg_list[i].name, context[i]); - arm11_set_reg(&arm11->reg_list[i], &context[i]); + arm11_set_reg(&arm11->reg_list[i], (u8*)&context[i]); } LOG_DEBUG("restoring CPSR with value 0x%8.8x", cpsr); - arm11_set_reg(&arm11->reg_list[ARM11_RC_CPSR], &cpsr); + arm11_set_reg(&arm11->reg_list[ARM11_RC_CPSR], (u8*)&cpsr); // arm11->core_state = core_state; // arm11->core_mode = core_mode; @@ -1512,29 +1483,29 @@ restore: int arm11_target_create(struct target_s *target, Jim_Interp *interp) { - FNC_INFO; + FNC_INFO; - NEW(arm11_common_t, arm11, 1); + NEW(arm11_common_t, arm11, 1); - arm11->target = target; + arm11->target = target; - /* prepare JTAG information for the new target */ - arm11->jtag_info.chain_pos = target->chain_position; - arm11->jtag_info.scann_size = 5; + /* prepare JTAG information for the new target */ + arm11->jtag_info.chain_pos = target->chain_position; + arm11->jtag_info.scann_size = 5; - arm_jtag_setup_connection(&arm11->jtag_info); + arm_jtag_setup_connection(&arm11->jtag_info); - jtag_device_t *device = jtag_get_device(target->chain_position); + jtag_device_t *device = jtag_get_device(target->chain_position); - if (device->ir_length != 5) - { + if (device->ir_length != 5) + { LOG_ERROR("'target arm11' expects 'jtag_device 5 0x01 0x1F 0x1E'"); return ERROR_COMMAND_SYNTAX_ERROR; - } + } - target->arch_info = arm11; + target->arch_info = arm11; - return ERROR_OK; + return ERROR_OK; } int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target) @@ -1546,175 +1517,173 @@ int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target /* talk to the target and set things up */ int arm11_examine(struct target_s *target) { - FNC_INFO; - int retval; + FNC_INFO; + int retval; - arm11_common_t * arm11 = target->arch_info; + arm11_common_t * arm11 = target->arch_info; - /* check IDCODE */ + /* check IDCODE */ - arm11_add_IR(arm11, ARM11_IDCODE, -1); + arm11_add_IR(arm11, ARM11_IDCODE, -1); - scan_field_t idcode_field; + scan_field_t idcode_field; - arm11_setup_field(arm11, 32, NULL, &arm11->device_id, &idcode_field); + arm11_setup_field(arm11, 32, NULL, &arm11->device_id, &idcode_field); - arm11_add_dr_scan_vc(1, &idcode_field, TAP_PD); + arm11_add_dr_scan_vc(1, &idcode_field, TAP_PD); - /* check DIDR */ + /* check DIDR */ - arm11_add_debug_SCAN_N(arm11, 0x00, -1); + arm11_add_debug_SCAN_N(arm11, 0x00, -1); - arm11_add_IR(arm11, ARM11_INTEST, -1); + arm11_add_IR(arm11, ARM11_INTEST, -1); - scan_field_t chain0_fields[2]; + scan_field_t chain0_fields[2]; - arm11_setup_field(arm11, 32, NULL, &arm11->didr, chain0_fields + 0); - arm11_setup_field(arm11, 8, NULL, &arm11->implementor, chain0_fields + 1); + arm11_setup_field(arm11, 32, NULL, &arm11->didr, chain0_fields + 0); + arm11_setup_field(arm11, 8, NULL, &arm11->implementor, chain0_fields + 1); - arm11_add_dr_scan_vc(asizeof(chain0_fields), chain0_fields, TAP_RTI); + arm11_add_dr_scan_vc(asizeof(chain0_fields), chain0_fields, TAP_RTI); - if ((retval=jtag_execute_queue())!=ERROR_OK) - return retval; + if ((retval=jtag_execute_queue())!=ERROR_OK) + return retval; - switch (arm11->device_id & 0x0FFFF000) - { - case 0x07B36000: LOG_INFO("found ARM1136"); break; - case 0x07B56000: LOG_INFO("found ARM1156"); break; - case 0x07B76000: LOG_INFO("found ARM1176"); break; - default: - { + switch (arm11->device_id & 0x0FFFF000) + { + case 0x07B36000: LOG_INFO("found ARM1136"); break; + case 0x07B56000: LOG_INFO("found ARM1156"); break; + case 0x07B76000: LOG_INFO("found ARM1176"); break; + default: + { LOG_ERROR("'target arm11' expects IDCODE 0x*7B*7****"); return ERROR_FAIL; - } - } + } + } - arm11->debug_version = (arm11->didr >> 16) & 0x0F; + arm11->debug_version = (arm11->didr >> 16) & 0x0F; - if (arm11->debug_version != ARM11_DEBUG_V6 && + if (arm11->debug_version != ARM11_DEBUG_V6 && arm11->debug_version != ARM11_DEBUG_V61) - { + { LOG_ERROR("Only ARMv6 v6 and v6.1 architectures supported."); return ERROR_FAIL; - } + } - arm11->brp = ((arm11->didr >> 24) & 0x0F) + 1; - arm11->wrp = ((arm11->didr >> 28) & 0x0F) + 1; + arm11->brp = ((arm11->didr >> 24) & 0x0F) + 1; + arm11->wrp = ((arm11->didr >> 28) & 0x0F) + 1; - /** \todo TODO: reserve one brp slot if we allow breakpoints during step */ - arm11->free_brps = arm11->brp; - arm11->free_wrps = arm11->wrp; + /** \todo TODO: reserve one brp slot if we allow breakpoints during step */ + arm11->free_brps = arm11->brp; + arm11->free_wrps = arm11->wrp; - LOG_DEBUG("IDCODE %08x IMPLEMENTOR %02x DIDR %08x", + LOG_DEBUG("IDCODE %08x IMPLEMENTOR %02x DIDR %08x", arm11->device_id, arm11->implementor, arm11->didr); - arm11_build_reg_cache(target); - + arm11_build_reg_cache(target); - /* as a side-effect this reads DSCR and thus - * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag - * as suggested by the spec. - */ + /* as a side-effect this reads DSCR and thus + * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag + * as suggested by the spec. + */ - arm11_check_init(arm11, NULL); + arm11_check_init(arm11, NULL); - target->type->examined = 1; + target->type->examined = 1; - return ERROR_OK; + return ERROR_OK; } int arm11_quit(void) { - FNC_INFO_NOTIMPLEMENTED; + FNC_INFO_NOTIMPLEMENTED; - return ERROR_OK; + return ERROR_OK; } /** Load a register that is marked !valid in the register cache */ int arm11_get_reg(reg_t *reg) { - FNC_INFO; + FNC_INFO; - target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target; + target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) + { LOG_WARNING("target was not halted"); return ERROR_TARGET_NOT_HALTED; - } + } - /** \todo TODO: Check this. We assume that all registers are fetched at debug entry. */ + /** \todo TODO: Check this. We assume that all registers are fetched at debug entry. */ #if 0 - arm11_common_t *arm11 = target->arch_info; - const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index; + arm11_common_t *arm11 = target->arch_info; + const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index; #endif - return ERROR_OK; + return ERROR_OK; } /** Change a value in the register cache */ int arm11_set_reg(reg_t *reg, u8 *buf) { - FNC_INFO; + FNC_INFO; - target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target; - arm11_common_t *arm11 = target->arch_info; -// const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index; + target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target; + arm11_common_t *arm11 = target->arch_info; +// const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index; - arm11->reg_values[((arm11_reg_state_t *)reg->arch_info)->def_index] = buf_get_u32(buf, 0, 32); - reg->valid = 1; - reg->dirty = 1; + arm11->reg_values[((arm11_reg_state_t *)reg->arch_info)->def_index] = buf_get_u32(buf, 0, 32); + reg->valid = 1; + reg->dirty = 1; - return ERROR_OK; + return ERROR_OK; } - void arm11_build_reg_cache(target_t *target) { - arm11_common_t *arm11 = target->arch_info; + arm11_common_t *arm11 = target->arch_info; + + NEW(reg_cache_t, cache, 1); + NEW(reg_t, reg_list, ARM11_REGCACHE_COUNT); + NEW(arm11_reg_state_t, arm11_reg_states, ARM11_REGCACHE_COUNT); - NEW(reg_cache_t, cache, 1); - NEW(reg_t, reg_list, ARM11_REGCACHE_COUNT); - NEW(arm11_reg_state_t, arm11_reg_states, ARM11_REGCACHE_COUNT); + if (arm11_regs_arch_type == -1) + arm11_regs_arch_type = register_reg_arch_type(arm11_get_reg, arm11_set_reg); - if (arm11_regs_arch_type == -1) - arm11_regs_arch_type = register_reg_arch_type(arm11_get_reg, arm11_set_reg); - register_init_dummy(&arm11_gdb_dummy_fp_reg); register_init_dummy(&arm11_gdb_dummy_fps_reg); - arm11->reg_list = reg_list; + arm11->reg_list = reg_list; - /* Build the process context cache */ - cache->name = "arm11 registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = ARM11_REGCACHE_COUNT; + /* Build the process context cache */ + cache->name = "arm11 registers"; + cache->next = NULL; + cache->reg_list = reg_list; + cache->num_regs = ARM11_REGCACHE_COUNT; - reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache); - (*cache_p) = cache; + reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache); + (*cache_p) = cache; - arm11->core_cache = cache; -// armv7m->process_context = cache; + arm11->core_cache = cache; +// armv7m->process_context = cache; - size_t i; + size_t i; - /* Not very elegant assertion */ - if (ARM11_REGCACHE_COUNT != asizeof(arm11->reg_values) || + /* Not very elegant assertion */ + if (ARM11_REGCACHE_COUNT != asizeof(arm11->reg_values) || ARM11_REGCACHE_COUNT != asizeof(arm11_reg_defs) || ARM11_REGCACHE_COUNT != ARM11_RC_MAX) - { + { LOG_ERROR("BUG: arm11->reg_values inconsistent (%d " ZU " " ZU " %d)", ARM11_REGCACHE_COUNT, asizeof(arm11->reg_values), asizeof(arm11_reg_defs), ARM11_RC_MAX); exit(-1); - } + } - for (i = 0; i < ARM11_REGCACHE_COUNT; i++) - { + for (i = 0; i < ARM11_REGCACHE_COUNT; i++) + { reg_t * r = reg_list + i; const arm11_reg_defs_t * rd = arm11_reg_defs + i; arm11_reg_state_t * rs = arm11_reg_states + i; @@ -1731,224 +1700,216 @@ void arm11_build_reg_cache(target_t *target) rs->def_index = i; rs->target = target; - } + } } - - int arm11_handle_bool(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, bool * var, char * name) { - if (argc == 0) - { + if (argc == 0) + { LOG_INFO("%s is %s.", name, *var ? "enabled" : "disabled"); return ERROR_OK; - } + } - if (argc != 1) + if (argc != 1) return ERROR_COMMAND_SYNTAX_ERROR; - switch (args[0][0]) - { - case '0': /* 0 */ - case 'f': /* false */ - case 'F': - case 'd': /* disable */ - case 'D': + switch (args[0][0]) + { + case '0': /* 0 */ + case 'f': /* false */ + case 'F': + case 'd': /* disable */ + case 'D': *var = false; break; - case '1': /* 1 */ - case 't': /* true */ - case 'T': - case 'e': /* enable */ - case 'E': + case '1': /* 1 */ + case 't': /* true */ + case 'T': + case 'e': /* enable */ + case 'E': *var = true; break; - } + } - LOG_INFO("%s %s.", *var ? "Enabled" : "Disabled", name); + LOG_INFO("%s %s.", *var ? "Enabled" : "Disabled", name); - return ERROR_OK; + return ERROR_OK; } - -#define BOOL_WRAPPER(name, print_name) \ +#define BOOL_WRAPPER(name, print_name) \ int arm11_handle_bool_##name(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) \ { \ - return arm11_handle_bool(cmd_ctx, cmd, args, argc, &arm11_config_##name, print_name); \ + return arm11_handle_bool(cmd_ctx, cmd, args, argc, &arm11_config_##name, print_name); \ } #define RC_TOP(name, descr, more) \ { \ - command_t * new_cmd = register_command(cmd_ctx, top_cmd, name, NULL, COMMAND_ANY, descr); \ - command_t * top_cmd = new_cmd; \ - more \ + command_t * new_cmd = register_command(cmd_ctx, top_cmd, name, NULL, COMMAND_ANY, descr); \ + command_t * top_cmd = new_cmd; \ + more \ } -#define RC_FINAL(name, descr, handler) \ - register_command(cmd_ctx, top_cmd, name, handler, COMMAND_ANY, descr); +#define RC_FINAL(name, descr, handler) \ + register_command(cmd_ctx, top_cmd, name, handler, COMMAND_ANY, descr); #define RC_FINAL_BOOL(name, descr, var) \ - register_command(cmd_ctx, top_cmd, name, arm11_handle_bool_##var, COMMAND_ANY, descr); - + register_command(cmd_ctx, top_cmd, name, arm11_handle_bool_##var, COMMAND_ANY, descr); BOOL_WRAPPER(memwrite_burst, "memory write burst mode") BOOL_WRAPPER(memwrite_error_fatal, "fatal error mode for memory writes") - int arm11_handle_vcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - if (argc == 1) - { + if (argc == 1) + { arm11_vcr = strtoul(args[0], NULL, 0); - } - else if (argc != 0) - { + } + else if (argc != 0) + { return ERROR_COMMAND_SYNTAX_ERROR; - } + } - LOG_INFO("VCR 0x%08X", arm11_vcr); - return ERROR_OK; + LOG_INFO("VCR 0x%08X", arm11_vcr); + return ERROR_OK; } const u32 arm11_coproc_instruction_limits[] = { - 15, /* coprocessor */ - 7, /* opcode 1 */ - 15, /* CRn */ - 15, /* CRm */ - 7, /* opcode 2 */ - 0xFFFFFFFF, /* value */ + 15, /* coprocessor */ + 7, /* opcode 1 */ + 15, /* CRn */ + 15, /* CRm */ + 7, /* opcode 2 */ + 0xFFFFFFFF, /* value */ }; const char arm11_mrc_syntax[] = "Syntax: mrc <jtag_target> <coprocessor> <opcode 1> <CRn> <CRm> <opcode 2>. All parameters are numbers only."; const char arm11_mcr_syntax[] = "Syntax: mcr <jtag_target> <coprocessor> <opcode 1> <CRn> <CRm> <opcode 2> <32bit value to write>. All parameters are numbers only."; - arm11_common_t * arm11_find_target(const char * arg) { - size_t jtag_target = strtoul(arg, NULL, 0); + size_t jtag_target = strtoul(arg, NULL, 0); - {target_t * t; - for (t = all_targets; t; t = t->next) - { - if (strcmp(t->type->name,"arm11")) - continue; + {target_t * t; + for (t = all_targets; t; t = t->next) + { + if (strcmp(t->type->name,"arm11")) + continue; arm11_common_t * arm11 = t->arch_info; if (arm11->jtag_info.chain_pos != jtag_target) - continue; + continue; return arm11; - }} + }} - return 0; + return 0; } int arm11_handle_mrc_mcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, bool read) { - if (argc != (read ? 6 : 7)) - { + if (argc != (read ? 6 : 7)) + { LOG_ERROR("Invalid number of arguments. %s", read ? arm11_mrc_syntax : arm11_mcr_syntax); return -1; - } + } - arm11_common_t * arm11 = arm11_find_target(args[0]); + arm11_common_t * arm11 = arm11_find_target(args[0]); - if (!arm11) - { + if (!arm11) + { LOG_ERROR("Parameter 1 is not a the JTAG chain position of an ARM11 device. %s", read ? arm11_mrc_syntax : arm11_mcr_syntax); return -1; - } + } - if (arm11->target->state != TARGET_HALTED) - { + if (arm11->target->state != TARGET_HALTED) + { LOG_WARNING("target was not halted"); return ERROR_TARGET_NOT_HALTED; - } - + } - u32 values[6]; + u32 values[6]; - {size_t i; - for (i = 0; i < (read ? 5 : 6); i++) - { + {size_t i; + for (i = 0; i < (read ? 5 : 6); i++) + { values[i] = strtoul(args[i + 1], NULL, 0); if (values[i] > arm11_coproc_instruction_limits[i]) { - LOG_ERROR("Parameter %ld out of bounds (%d max). %s", - (long)(i + 2), arm11_coproc_instruction_limits[i], + LOG_ERROR("Parameter %ld out of bounds (%d max). %s", + (long)(i + 2), arm11_coproc_instruction_limits[i], read ? arm11_mrc_syntax : arm11_mcr_syntax); - return -1; + return -1; } - }} + }} - u32 instr = 0xEE000010 | + u32 instr = 0xEE000010 | (values[0] << 8) | (values[1] << 21) | (values[2] << 16) | (values[3] << 0) | (values[4] << 5); - if (read) + if (read) instr |= 0x00100000; + arm11_run_instr_data_prepare(arm11); - arm11_run_instr_data_prepare(arm11); - - if (read) - { + if (read) + { u32 result; arm11_run_instr_data_from_core_via_r0(arm11, instr, &result); LOG_INFO("MRC p%d, %d, R0, c%d, c%d, %d = 0x%08x (%d)", - values[0], values[1], values[2], values[3], values[4], result, result); - } - else - { + values[0], values[1], values[2], values[3], values[4], result, result); + } + else + { arm11_run_instr_data_to_core_via_r0(arm11, instr, values[5]); LOG_INFO("MRC p%d, %d, R0 (#0x%08x), c%d, c%d, %d", - values[0], values[1], - values[5], - values[2], values[3], values[4]); - } + values[0], values[1], + values[5], + values[2], values[3], values[4]); + } - arm11_run_instr_data_finish(arm11); + arm11_run_instr_data_finish(arm11); - return ERROR_OK; + return ERROR_OK; } int arm11_handle_mrc(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, true); + return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, true); } int arm11_handle_mcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, false); + return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, false); } int arm11_register_commands(struct command_context_s *cmd_ctx) { - FNC_INFO; + FNC_INFO; - command_t * top_cmd = NULL; + command_t * top_cmd = NULL; - RC_TOP( "arm11", "arm11 specific commands", + RC_TOP( "arm11", "arm11 specific commands", RC_TOP( "memwrite", "Control memory write transfer mode", - RC_FINAL_BOOL( "burst", "Enable/Disable non-standard but fast burst mode (default: enabled)", + RC_FINAL_BOOL( "burst", "Enable/Disable non-standard but fast burst mode (default: enabled)", memwrite_burst) - RC_FINAL_BOOL( "error_fatal", + RC_FINAL_BOOL( "error_fatal", "Terminate program if transfer error was found (default: enabled)", memwrite_error_fatal) ) @@ -1961,7 +1922,7 @@ int arm11_register_commands(struct command_context_s *cmd_ctx) RC_FINAL( "mcr", "Write Coprocessor register", arm11_handle_mcr) - ) + ) - return ERROR_OK; + return ERROR_OK; } diff --git a/src/target/arm11.h b/src/target/arm11.h index d7200a40..e685f0e0 100644 --- a/src/target/arm11.h +++ b/src/target/arm11.h @@ -28,12 +28,10 @@ #include "arm_jtag.h" #include <stdbool.h> - #define asizeof(x) (sizeof(x) / sizeof((x)[0])) #define NEW(type, variable, items) \ - type * variable = calloc(1, sizeof(type) * items) - + type * variable = calloc(1, sizeof(type) * items) /* For MinGW use 'I' prefix to print size_t (instead of 'z') */ @@ -43,7 +41,6 @@ #define ZU "%Iu" #endif - #define ARM11_REGCACHE_MODEREGS 0 #define ARM11_REGCACHE_FREGS 0 @@ -51,63 +48,60 @@ 23 * ARM11_REGCACHE_MODEREGS + \ 9 * ARM11_REGCACHE_FREGS) - typedef struct arm11_register_history_s { - u32 value; - u8 valid; + u32 value; + u8 valid; }arm11_register_history_t; enum arm11_debug_version { - ARM11_DEBUG_V6 = 0x01, - ARM11_DEBUG_V61 = 0x02, - ARM11_DEBUG_V7 = 0x03, - ARM11_DEBUG_V7_CP14 = 0x04, + ARM11_DEBUG_V6 = 0x01, + ARM11_DEBUG_V61 = 0x02, + ARM11_DEBUG_V7 = 0x03, + ARM11_DEBUG_V7_CP14 = 0x04, }; typedef struct arm11_common_s { - target_t * target; - - arm_jtag_t jtag_info; + target_t * target; - /** \name Processor type detection */ - /*@{*/ + arm_jtag_t jtag_info; - u32 device_id; /**< IDCODE readout */ - u32 didr; /**< DIDR readout (debug capabilities) */ - u8 implementor; /**< DIDR Implementor readout */ + /** \name Processor type detection */ + /*@{*/ - size_t brp; /**< Number of Breakpoint Register Pairs from DIDR */ - size_t wrp; /**< Number of Watchpoint Register Pairs from DIDR */ + u32 device_id; /**< IDCODE readout */ + u32 didr; /**< DIDR readout (debug capabilities) */ + u8 implementor; /**< DIDR Implementor readout */ - enum arm11_debug_version - debug_version; /**< ARM debug architecture from DIDR */ - /*@}*/ + size_t brp; /**< Number of Breakpoint Register Pairs from DIDR */ + size_t wrp; /**< Number of Watchpoint Register Pairs from DIDR */ + + enum arm11_debug_version + debug_version; /**< ARM debug architecture from DIDR */ + /*@}*/ + u32 last_dscr; /**< Last retrieved DSCR value; + * Can be used to detect changes */ - u32 last_dscr; /**< Last retrieved DSCR value; - * Can be used to detect changes */ + bool trst_active; + bool halt_requested; + bool simulate_reset_on_next_halt; - bool trst_active; - bool halt_requested; - bool simulate_reset_on_next_halt; + /** \name Shadow registers to save processor state */ + /*@{*/ - /** \name Shadow registers to save processor state */ - /*@{*/ + reg_t * reg_list; /**< target register list */ + u32 reg_values[ARM11_REGCACHE_COUNT]; /**< data for registers */ - reg_t * reg_list; /**< target register list */ - u32 reg_values[ARM11_REGCACHE_COUNT]; /**< data for registers */ + /*@}*/ - /*@}*/ - - arm11_register_history_t + arm11_register_history_t reg_history[ARM11_REGCACHE_COUNT]; /**< register state before last resume */ - - size_t free_brps; /**< keep track of breakpoints allocated by arm11_add_breakpoint() */ - size_t free_wrps; /**< keep track of breakpoints allocated by arm11_add_watchpoint() */ + size_t free_brps; /**< keep track of breakpoints allocated by arm11_add_breakpoint() */ + size_t free_wrps; /**< keep track of breakpoints allocated by arm11_add_watchpoint() */ // GA reg_cache_t *core_cache; @@ -121,65 +115,60 @@ typedef struct arm11_common_s */ enum arm11_instructions { - ARM11_EXTEST = 0x00, - ARM11_SCAN_N = 0x02, - ARM11_RESTART = 0x04, - ARM11_HALT = 0x08, - ARM11_INTEST = 0x0C, - ARM11_ITRSEL = 0x1D, - ARM11_IDCODE = 0x1E, - ARM11_BYPASS = 0x1F, + ARM11_EXTEST = 0x00, + ARM11_SCAN_N = 0x02, + ARM11_RESTART = 0x04, + ARM11_HALT = 0x08, + ARM11_INTEST = 0x0C, + ARM11_ITRSEL = 0x1D, + ARM11_IDCODE = 0x1E, + ARM11_BYPASS = 0x1F, }; enum arm11_dscr { - ARM11_DSCR_CORE_HALTED = 1 << 0, - ARM11_DSCR_CORE_RESTARTED = 1 << 1, - - ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2, - ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 2, - ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT = 0x01 << 2, - ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 2, - ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION = 0x03 << 2, - ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2, - ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2, - - ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6, - ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7, - ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13, - ARM11_DSCR_MODE_SELECT = 1 << 14, - ARM11_DSCR_WDTR_FULL = 1 << 29, - ARM11_DSCR_RDTR_FULL = 1 << 30, + ARM11_DSCR_CORE_HALTED = 1 << 0, + ARM11_DSCR_CORE_RESTARTED = 1 << 1, + + ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2, + ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 2, + ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT = 0x01 << 2, + ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 2, + ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION = 0x03 << 2, + ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2, + ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2, + + ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6, + ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7, + ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13, + ARM11_DSCR_MODE_SELECT = 1 << 14, + ARM11_DSCR_WDTR_FULL = 1 << 29, + ARM11_DSCR_RDTR_FULL = 1 << 30, }; enum arm11_cpsr { - ARM11_CPSR_T = 1 << 5, - ARM11_CPSR_J = 1 << 24, + ARM11_CPSR_T = 1 << 5, + ARM11_CPSR_J = 1 << 24, }; enum arm11_sc7 { - ARM11_SC7_NULL = 0, - ARM11_SC7_VCR = 7, - ARM11_SC7_PC = 8, - ARM11_SC7_BVR0 = 64, - ARM11_SC7_BCR0 = 80, - ARM11_SC7_WVR0 = 96, - ARM11_SC7_WCR0 = 112, + ARM11_SC7_NULL = 0, + ARM11_SC7_VCR = 7, + ARM11_SC7_PC = 8, + ARM11_SC7_BVR0 = 64, + ARM11_SC7_BCR0 = 80, + ARM11_SC7_WVR0 = 96, + ARM11_SC7_WCR0 = 112, }; - - typedef struct arm11_reg_state_s { - u32 def_index; - target_t * target; + u32 def_index; + target_t * target; } arm11_reg_state_t; - - - /* poll current target status */ int arm11_poll(struct target_s *target); /* architecture specific status reply */ @@ -230,14 +219,14 @@ int arm11_target_create(struct target_s *target, Jim_Interp *interp); int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target); int arm11_quit(void); - /* helpers */ void arm11_build_reg_cache(target_t *target); +int arm11_set_reg(reg_t *reg, u8 *buf); +int arm11_get_reg(reg_t *reg); void arm11_record_register_history(arm11_common_t * arm11); void arm11_dump_reg_changes(arm11_common_t * arm11); - /* internals */ void arm11_setup_field (arm11_common_t * arm11, int num_bits, void * in_data, void * out_data, scan_field_t * field); @@ -263,18 +252,17 @@ void arm11_run_instr_data_to_core_via_r0 (arm11_common_t * arm11, u32 opcode, u3 int arm11_add_dr_scan_vc(int num_fields, scan_field_t *fields, enum tap_state state); int arm11_add_ir_scan_vc(int num_fields, scan_field_t *fields, enum tap_state state); - /** Used to make a list of read/write commands for scan chain 7 * * Use with arm11_sc7_run() */ typedef struct arm11_sc7_action_s { - bool write; /**< Access mode: true for write, false for read. */ - u8 address; /**< Register address mode. Use enum #arm11_sc7 */ - u32 value; /**< If write then set this to value to be written. - In read mode this receives the read value when the - function returns. */ + bool write; /**< Access mode: true for write, false for read. */ + u8 address; /**< Register address mode. Use enum #arm11_sc7 */ + u32 value; /**< If write then set this to value to be written. + In read mode this receives the read value when the + function returns. */ } arm11_sc7_action_t; void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count); @@ -285,6 +273,4 @@ void arm11_sc7_set_vcr(arm11_common_t * arm11, u32 value); void arm11_read_memory_word(arm11_common_t * arm11, u32 address, u32 * result); - - #endif /* ARM11_H */ diff --git a/src/target/mips32_dmaacc.c b/src/target/mips32_dmaacc.c index 96426c0a..7ca6c29a 100644 --- a/src/target/mips32_dmaacc.c +++ b/src/target/mips32_dmaacc.c @@ -1,441 +1,440 @@ -/***************************************************************************
- * Copyright (C) 2008 by John McCarthy *
- * jgmcc@magma.ca *
- * *
- * Copyright (C) 2008 by Spencer Oliver *
- * spen@spen-soft.co.uk *
- * *
- * Copyright (C) 2008 by David T.L. Wong *
- * *
- * This program 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 of the License, or *
- * (at your option) any later version. *
- * *
- * This program 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 this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include "log.h"
-#include "mips32.h"
-#include "mips32_dmaacc.h"
-
-/*
- * The following logic shamelessly cloned from HairyDairyMaid's wrt54g_debrick
- * to support the Broadcom BCM5352 SoC in the Linksys WRT54GL wireless router
- * (and any others that support EJTAG DMA transfers).
- * Note: This only supports memory read/write. Since the BCM5352 doesn't
- * appear to support PRACC accesses, all debug functions except halt
- * do not work. Still, this does allow erasing/writing flash as well as
- * displaying/modifying memory and memory mapped registers.
- */
-
-static int ejtag_dma_read(mips_ejtag_t *ejtag_info, u32 addr, u32 *data)
-{
- u32 v;
- u32 ctrl_reg;
- int retries = RETRY_ATTEMPTS;
-
-begin_ejtag_dma_read:
-
- // Setup Address
- v = addr;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Initiate DMA Read & set DSTRT
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
-
- // Wait for DSTRT to Clear
- do {
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- } while(ctrl_reg & EJTAG_CTRL_DSTRT);
-
- // Read Data
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
- mips_ejtag_drscan_32(ejtag_info, data);
-
- // Clear DMA & Check DERR
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- if (ctrl_reg & EJTAG_CTRL_DERR)
- {
- if (retries--) {
- printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
- goto begin_ejtag_dma_read;
- } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- return ERROR_OK;
-}
-
-static int ejtag_dma_read_h(mips_ejtag_t *ejtag_info, u32 addr, u16 *data)
-{
- u32 v;
- u32 ctrl_reg;
- int retries = RETRY_ATTEMPTS;
-
-begin_ejtag_dma_read_h:
-
- // Setup Address
- v = addr;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Initiate DMA Read & set DSTRT
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
-
- // Wait for DSTRT to Clear
- do {
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- } while(ctrl_reg & EJTAG_CTRL_DSTRT);
-
- // Read Data
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Clear DMA & Check DERR
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- if (ctrl_reg & EJTAG_CTRL_DERR)
- {
- if (retries--) {
- printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
- goto begin_ejtag_dma_read_h;
- } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- // Handle the bigendian/littleendian
- if ( addr & 0x2 ) *data = (v>>16)&0xffff ;
- else *data = (v&0x0000ffff) ;
-
- return ERROR_OK;
-}
-
-static int ejtag_dma_read_b(mips_ejtag_t *ejtag_info, u32 addr, u8 *data)
-{
- u32 v;
- u32 ctrl_reg;
- int retries = RETRY_ATTEMPTS;
-
-begin_ejtag_dma_read_b:
-
- // Setup Address
- v = addr;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Initiate DMA Read & set DSTRT
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
-
- // Wait for DSTRT to Clear
- do {
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- } while(ctrl_reg & EJTAG_CTRL_DSTRT);
-
- // Read Data
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Clear DMA & Check DERR
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- if (ctrl_reg & EJTAG_CTRL_DERR)
- {
- if (retries--) {
- printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr);
- goto begin_ejtag_dma_read_b;
- } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- // Handle the bigendian/littleendian
- switch(addr & 0x3) {
- case 0: *data = v & 0xff; break;
- case 1: *data = (v>>8) & 0xff; break;
- case 2: *data = (v>>16) & 0xff; break;
- case 3: *data = (v>>24) & 0xff; break;
- }
-
- return ERROR_OK;
-}
-
-static int ejtag_dma_write(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
-{
- u32 v;
- u32 ctrl_reg;
- int retries = RETRY_ATTEMPTS;
-
-begin_ejtag_dma_write:
-
- // Setup Address
- v = addr;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Setup Data
- v = data;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Initiate DMA Write & set DSTRT
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
-
- // Wait for DSTRT to Clear
- do {
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- } while(ctrl_reg & EJTAG_CTRL_DSTRT);
-
- // Clear DMA & Check DERR
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- if (ctrl_reg & EJTAG_CTRL_DERR)
- {
- if (retries--) {
- printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
- goto begin_ejtag_dma_write;
- } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- return ERROR_OK;
-}
-
-static int ejtag_dma_write_h(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
-{
- u32 v;
- u32 ctrl_reg;
- int retries = RETRY_ATTEMPTS;
-
-
- // Handle the bigendian/littleendian
- data &= 0xffff;
- data |= data<<16;
-
-begin_ejtag_dma_write_h:
-
- // Setup Address
- v = addr;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Setup Data
- v = data;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Initiate DMA Write & set DSTRT
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
-
- // Wait for DSTRT to Clear
- do {
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- } while(ctrl_reg & EJTAG_CTRL_DSTRT);
-
- // Clear DMA & Check DERR
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- if (ctrl_reg & EJTAG_CTRL_DERR)
- {
- if (retries--) {
- printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
- goto begin_ejtag_dma_write_h;
- } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- return ERROR_OK;
-}
-
-static int ejtag_dma_write_b(mips_ejtag_t *ejtag_info, u32 addr, u32 data)
-{
- u32 v;
- u32 ctrl_reg;
- int retries = RETRY_ATTEMPTS;
-
-
- // Handle the bigendian/littleendian
- data &= 0xff;
- data |= data<<8;
- data |= data<<16;
-
-begin_ejtag_dma_write_b:
-
- // Setup Address
- v = addr;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Setup Data
- v = data;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
- mips_ejtag_drscan_32(ejtag_info, &v);
-
- // Initiate DMA Write & set DSTRT
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
-
- // Wait for DSTRT to Clear
- do {
- ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- } while(ctrl_reg & EJTAG_CTRL_DSTRT);
-
- // Clear DMA & Check DERR
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
- ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC;
- mips_ejtag_drscan_32(ejtag_info, &ctrl_reg);
- if (ctrl_reg & EJTAG_CTRL_DERR)
- {
- if (retries--) {
- printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr);
- goto begin_ejtag_dma_write_b;
- } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- return ERROR_OK;
-}
-
-
-int mips32_dmaacc_read_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
-{
- switch (size)
- {
- case 1:
- return mips32_dmaacc_read_mem8(ejtag_info, addr, count, (u8*)buf);
- case 2:
- return mips32_dmaacc_read_mem16(ejtag_info, addr, count, (u16*)buf);
- case 4:
- return mips32_dmaacc_read_mem32(ejtag_info, addr, count, (u32*)buf);
- }
-
- return ERROR_OK;
-}
-
-int mips32_dmaacc_read_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
-{
- int i;
- int retval;
-
- for(i=0; i<count; i++) {
- if((retval=ejtag_dma_read(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
- return retval;
- }
-
- return ERROR_OK;
-}
-
-int mips32_dmaacc_read_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
-{
- int i;
- int retval;
-
- for(i=0; i<count; i++) {
- if((retval=ejtag_dma_read_h(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
- return retval;
- }
-
- return ERROR_OK;
-}
-
-int mips32_dmaacc_read_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
-{
- int i;
- int retval;
-
- for(i=0; i<count; i++) {
- if((retval=ejtag_dma_read_b(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK)
- return retval;
- }
-
- return ERROR_OK;
-}
-
-int mips32_dmaacc_write_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf)
-{
- switch (size)
- {
- case 1:
- return mips32_dmaacc_write_mem8(ejtag_info, addr, count, (u8*)buf);
- case 2:
- return mips32_dmaacc_write_mem16(ejtag_info, addr, count,(u16*)buf);
- case 4:
- return mips32_dmaacc_write_mem32(ejtag_info, addr, count, (u32*)buf);
- }
-
- return ERROR_OK;
-}
-
-int mips32_dmaacc_write_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf)
-{
- int i;
- int retval;
-
- for(i=0; i<count; i++) {
- if((retval=ejtag_dma_write(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
- return retval;
- }
-
- return ERROR_OK;
-}
-
-int mips32_dmaacc_write_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf)
-{
- int i;
- int retval;
-
- for(i=0; i<count; i++) {
- if((retval=ejtag_dma_write_h(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
- return retval;
- }
-
- return ERROR_OK;
-}
-
-int mips32_dmaacc_write_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf)
-{
- int i;
- int retval;
-
- for(i=0; i<count; i++) {
- if((retval=ejtag_dma_write_b(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK)
- return retval;
- }
-
- return ERROR_OK;
-}
+/*************************************************************************** + * Copyright (C) 2008 by John McCarthy * + * jgmcc@magma.ca * + * * + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * Copyright (C) 2008 by David T.L. Wong * + * * + * This program 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 of the License, or * + * (at your option) any later version. * + * * + * This program 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 this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> +#include "log.h" +#include "mips32.h" +#include "mips32_dmaacc.h" + +/* + * The following logic shamelessly cloned from HairyDairyMaid's wrt54g_debrick + * to support the Broadcom BCM5352 SoC in the Linksys WRT54GL wireless router + * (and any others that support EJTAG DMA transfers). + * Note: This only supports memory read/write. Since the BCM5352 doesn't + * appear to support PRACC accesses, all debug functions except halt + * do not work. Still, this does allow erasing/writing flash as well as + * displaying/modifying memory and memory mapped registers. + */ + +static int ejtag_dma_read(mips_ejtag_t *ejtag_info, u32 addr, u32 *data) +{ + u32 v; + u32 ctrl_reg; + int retries = RETRY_ATTEMPTS; + +begin_ejtag_dma_read: + + // Setup Address + v = addr; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Initiate DMA Read & set DSTRT + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + + // Wait for DSTRT to Clear + do { + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + } while(ctrl_reg & EJTAG_CTRL_DSTRT); + + // Read Data + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL); + mips_ejtag_drscan_32(ejtag_info, data); + + // Clear DMA & Check DERR + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + if (ctrl_reg & EJTAG_CTRL_DERR) + { + if (retries--) { + printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr); + goto begin_ejtag_dma_read; + } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +static int ejtag_dma_read_h(mips_ejtag_t *ejtag_info, u32 addr, u16 *data) +{ + u32 v; + u32 ctrl_reg; + int retries = RETRY_ATTEMPTS; + +begin_ejtag_dma_read_h: + + // Setup Address + v = addr; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Initiate DMA Read & set DSTRT + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + + // Wait for DSTRT to Clear + do { + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + } while(ctrl_reg & EJTAG_CTRL_DSTRT); + + // Read Data + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Clear DMA & Check DERR + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + if (ctrl_reg & EJTAG_CTRL_DERR) + { + if (retries--) { + printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr); + goto begin_ejtag_dma_read_h; + } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr); + return ERROR_JTAG_DEVICE_ERROR; + } + + // Handle the bigendian/littleendian + if ( addr & 0x2 ) *data = (v>>16)&0xffff ; + else *data = (v&0x0000ffff) ; + + return ERROR_OK; +} + +static int ejtag_dma_read_b(mips_ejtag_t *ejtag_info, u32 addr, u8 *data) +{ + u32 v; + u32 ctrl_reg; + int retries = RETRY_ATTEMPTS; + +begin_ejtag_dma_read_b: + + // Setup Address + v = addr; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Initiate DMA Read & set DSTRT + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + + // Wait for DSTRT to Clear + do { + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + } while(ctrl_reg & EJTAG_CTRL_DSTRT); + + // Read Data + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Clear DMA & Check DERR + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + if (ctrl_reg & EJTAG_CTRL_DERR) + { + if (retries--) { + printf("DMA Read Addr = %08x Data = ERROR ON READ (retrying)\n", addr); + goto begin_ejtag_dma_read_b; + } else printf("DMA Read Addr = %08x Data = ERROR ON READ\n", addr); + return ERROR_JTAG_DEVICE_ERROR; + } + + // Handle the bigendian/littleendian + switch(addr & 0x3) { + case 0: *data = v & 0xff; break; + case 1: *data = (v>>8) & 0xff; break; + case 2: *data = (v>>16) & 0xff; break; + case 3: *data = (v>>24) & 0xff; break; + } + + return ERROR_OK; +} + +static int ejtag_dma_write(mips_ejtag_t *ejtag_info, u32 addr, u32 data) +{ + u32 v; + u32 ctrl_reg; + int retries = RETRY_ATTEMPTS; + +begin_ejtag_dma_write: + + // Setup Address + v = addr; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Setup Data + v = data; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Initiate DMA Write & set DSTRT + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + + // Wait for DSTRT to Clear + do { + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + } while(ctrl_reg & EJTAG_CTRL_DSTRT); + + // Clear DMA & Check DERR + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + if (ctrl_reg & EJTAG_CTRL_DERR) + { + if (retries--) { + printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr); + goto begin_ejtag_dma_write; + } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +static int ejtag_dma_write_h(mips_ejtag_t *ejtag_info, u32 addr, u32 data) +{ + u32 v; + u32 ctrl_reg; + int retries = RETRY_ATTEMPTS; + + + // Handle the bigendian/littleendian + data &= 0xffff; + data |= data<<16; + +begin_ejtag_dma_write_h: + + // Setup Address + v = addr; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Setup Data + v = data; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Initiate DMA Write & set DSTRT + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + + // Wait for DSTRT to Clear + do { + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + } while(ctrl_reg & EJTAG_CTRL_DSTRT); + + // Clear DMA & Check DERR + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + if (ctrl_reg & EJTAG_CTRL_DERR) + { + if (retries--) { + printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr); + goto begin_ejtag_dma_write_h; + } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +static int ejtag_dma_write_b(mips_ejtag_t *ejtag_info, u32 addr, u32 data) +{ + u32 v; + u32 ctrl_reg; + int retries = RETRY_ATTEMPTS; + + + // Handle the bigendian/littleendian + data &= 0xff; + data |= data<<8; + data |= data<<16; + +begin_ejtag_dma_write_b: + + // Setup Address + v = addr; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Setup Data + v = data; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL); + mips_ejtag_drscan_32(ejtag_info, &v); + + // Initiate DMA Write & set DSTRT + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + + // Wait for DSTRT to Clear + do { + ctrl_reg = EJTAG_CTRL_DMAACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + } while(ctrl_reg & EJTAG_CTRL_DSTRT); + + // Clear DMA & Check DERR + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); + ctrl_reg = EJTAG_CTRL_PROBEN | EJTAG_CTRL_PRACC; + mips_ejtag_drscan_32(ejtag_info, &ctrl_reg); + if (ctrl_reg & EJTAG_CTRL_DERR) + { + if (retries--) { + printf("DMA Write Addr = %08x Data = ERROR ON WRITE (retrying)\n", addr); + goto begin_ejtag_dma_write_b; + } else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +int mips32_dmaacc_read_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf) +{ + switch (size) + { + case 1: + return mips32_dmaacc_read_mem8(ejtag_info, addr, count, (u8*)buf); + case 2: + return mips32_dmaacc_read_mem16(ejtag_info, addr, count, (u16*)buf); + case 4: + return mips32_dmaacc_read_mem32(ejtag_info, addr, count, (u32*)buf); + } + + return ERROR_OK; +} + +int mips32_dmaacc_read_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf) +{ + int i; + int retval; + + for(i=0; i<count; i++) { + if((retval=ejtag_dma_read(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +int mips32_dmaacc_read_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf) +{ + int i; + int retval; + + for(i=0; i<count; i++) { + if((retval=ejtag_dma_read_h(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +int mips32_dmaacc_read_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf) +{ + int i; + int retval; + + for(i=0; i<count; i++) { + if((retval=ejtag_dma_read_b(ejtag_info, addr+i*sizeof(*buf), &buf[i])) != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +int mips32_dmaacc_write_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf) +{ + switch (size) + { + case 1: + return mips32_dmaacc_write_mem8(ejtag_info, addr, count, (u8*)buf); + case 2: + return mips32_dmaacc_write_mem16(ejtag_info, addr, count,(u16*)buf); + case 4: + return mips32_dmaacc_write_mem32(ejtag_info, addr, count, (u32*)buf); + } + + return ERROR_OK; +} + +int mips32_dmaacc_write_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf) +{ + int i; + int retval; + + for(i=0; i<count; i++) { + if((retval=ejtag_dma_write(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +int mips32_dmaacc_write_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf) +{ + int i; + int retval; + + for(i=0; i<count; i++) { + if((retval=ejtag_dma_write_h(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +int mips32_dmaacc_write_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf) +{ + int i; + int retval; + + for(i=0; i<count; i++) { + if((retval=ejtag_dma_write_b(ejtag_info, addr+i*sizeof(*buf), buf[i])) != ERROR_OK) + return retval; + } + + return ERROR_OK; +} diff --git a/src/target/mips32_dmaacc.h b/src/target/mips32_dmaacc.h index b6d544c5..2383ee9f 100644 --- a/src/target/mips32_dmaacc.h +++ b/src/target/mips32_dmaacc.h @@ -1,53 +1,53 @@ -/***************************************************************************
- * Copyright (C) 2008 by John McCarthy *
- * jgmcc@magma.ca *
- * *
- * Copyright (C) 2008 by Spencer Oliver *
- * spen@spen-soft.co.uk *
- * *
- * Copyright (C) 2008 by David T.L. Wong *
- * *
- * This program 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 of the License, or *
- * (at your option) any later version. *
- * *
- * This program 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 this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-#ifndef MIPS32_DMAACC_H
-#define MIPS32_DMAACC_H
-
-#include "mips_ejtag.h"
-
-#define EJTAG_CTRL_DMA_BYTE 0x00000000
-#define EJTAG_CTRL_DMA_HALFWORD 0x00000080
-#define EJTAG_CTRL_DMA_WORD 0x00000100
-#define EJTAG_CTRL_DMA_TRIPLEBYTE 0x00000180
-
-#define RETRY_ATTEMPTS 4
-
-extern int mips32_dmaacc_read_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf);
-extern int mips32_dmaacc_write_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf);
-
-extern int mips32_dmaacc_read_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf);
-extern int mips32_dmaacc_read_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf);
-extern int mips32_dmaacc_read_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf);
-
-extern int mips32_dmaacc_write_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf);
-extern int mips32_dmaacc_write_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf);
-extern int mips32_dmaacc_write_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf);
-
-#if 0
-extern int mips32_dmaacc_read_regs(mips_ejtag_t *ejtag_info, u32 *regs);
-extern int mips32_dmaacc_write_regs(mips_ejtag_t *ejtag_info, u32 *regs);
-#endif
-
-#endif
+/*************************************************************************** + * Copyright (C) 2008 by John McCarthy * + * jgmcc@magma.ca * + * * + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * Copyright (C) 2008 by David T.L. Wong * + * * + * This program 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 of the License, or * + * (at your option) any later version. * + * * + * This program 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 this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MIPS32_DMAACC_H +#define MIPS32_DMAACC_H + +#include "mips_ejtag.h" + +#define EJTAG_CTRL_DMA_BYTE 0x00000000 +#define EJTAG_CTRL_DMA_HALFWORD 0x00000080 +#define EJTAG_CTRL_DMA_WORD 0x00000100 +#define EJTAG_CTRL_DMA_TRIPLEBYTE 0x00000180 + +#define RETRY_ATTEMPTS 4 + +extern int mips32_dmaacc_read_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf); +extern int mips32_dmaacc_write_mem(mips_ejtag_t *ejtag_info, u32 addr, int size, int count, void *buf); + +extern int mips32_dmaacc_read_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf); +extern int mips32_dmaacc_read_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf); +extern int mips32_dmaacc_read_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf); + +extern int mips32_dmaacc_write_mem8(mips_ejtag_t *ejtag_info, u32 addr, int count, u8 *buf); +extern int mips32_dmaacc_write_mem16(mips_ejtag_t *ejtag_info, u32 addr, int count, u16 *buf); +extern int mips32_dmaacc_write_mem32(mips_ejtag_t *ejtag_info, u32 addr, int count, u32 *buf); + +#if 0 +extern int mips32_dmaacc_read_regs(mips_ejtag_t *ejtag_info, u32 *regs); +extern int mips32_dmaacc_write_regs(mips_ejtag_t *ejtag_info, u32 *regs); +#endif + +#endif diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 03995b5e..3508ebd1 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -25,6 +25,7 @@ #include "mips32.h" #include "mips_m4k.h" +#include "mips32_dmaacc.h" #include "jtag.h" #include "log.h" |