- .name = "arm11",
-
- ARM11_HANDLER(poll),
- ARM11_HANDLER(arch_state),
-
- ARM11_HANDLER(target_request_data),
-
- ARM11_HANDLER(halt),
- ARM11_HANDLER(resume),
- ARM11_HANDLER(step),
-
- ARM11_HANDLER(assert_reset),
- ARM11_HANDLER(deassert_reset),
- ARM11_HANDLER(soft_reset_halt),
-
- ARM11_HANDLER(get_gdb_reg_list),
-
- ARM11_HANDLER(read_memory),
- ARM11_HANDLER(write_memory),
-
- ARM11_HANDLER(bulk_write_memory),
-
- ARM11_HANDLER(checksum_memory),
-
- ARM11_HANDLER(add_breakpoint),
- ARM11_HANDLER(remove_breakpoint),
- ARM11_HANDLER(add_watchpoint),
- ARM11_HANDLER(remove_watchpoint),
-
- ARM11_HANDLER(run_algorithm),
-
- ARM11_HANDLER(register_commands),
- ARM11_HANDLER(target_command),
- ARM11_HANDLER(init_target),
- ARM11_HANDLER(quit),
+ .name = "arm11",
+
+ ARM11_HANDLER(poll),
+ ARM11_HANDLER(arch_state),
+
+ ARM11_HANDLER(target_request_data),
+
+ ARM11_HANDLER(halt),
+ ARM11_HANDLER(resume),
+ ARM11_HANDLER(step),
+
+ ARM11_HANDLER(assert_reset),
+ ARM11_HANDLER(deassert_reset),
+ ARM11_HANDLER(soft_reset_halt),
+
+ ARM11_HANDLER(get_gdb_reg_list),
+
+ ARM11_HANDLER(read_memory),
+ ARM11_HANDLER(write_memory),
+
+ ARM11_HANDLER(bulk_write_memory),
+
+ ARM11_HANDLER(checksum_memory),
+
+ ARM11_HANDLER(add_breakpoint),
+ ARM11_HANDLER(remove_breakpoint),
+ ARM11_HANDLER(add_watchpoint),
+ ARM11_HANDLER(remove_watchpoint),
+
+ ARM11_HANDLER(run_algorithm),
+
+ ARM11_HANDLER(register_commands),
+ ARM11_HANDLER(target_create),
+ ARM11_HANDLER(init_target),
+ ARM11_HANDLER(examine),
+ ARM11_HANDLER(quit),
- {"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},
- {"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},
- {"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},
- FNC_INFO_NOTIMPLEMENTED;
+ 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;
+ u32 context[16];
+ u32 cpsr;
+ int exit_breakpoint_size = 0;
+ int i;
+ int retval = ERROR_OK;
+ LOG_DEBUG("Running algorithm");
+
+ if (arm11_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
+ {
+ LOG_ERROR("current target isn't an ARMV4/5 target");
+ return ERROR_TARGET_INVALID;
+ }
+
+ if (target->state != TARGET_HALTED)
+ {
+ LOG_WARNING("target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ // FIXME
+// if (armv4_5_mode_to_number(arm11->core_mode)==-1)
+// return ERROR_FAIL;
+
+ // Save regs
+ for (i = 0; i < 16; i++)
+ {
+ context[i] = buf_get_u32((u8*)(&arm11->reg_values[i]),0,32);
+ LOG_DEBUG("Save %i: 0x%x",i,context[i]);
+ }
+
+ cpsr = buf_get_u32((u8*)(arm11->reg_values+ARM11_RC_CPSR),0,32);
+ LOG_DEBUG("Save CPSR: 0x%x", cpsr);
+
+ for (i = 0; i < num_mem_params; i++)
+ {
+ target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
+ }
+
+ // Set register parameters
+ for (i = 0; i < num_reg_params; i++)
+ {
+ reg_t *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0);
+ if (!reg)
+ {
+ LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
+ exit(-1);
+ }
+
+ if (reg->size != reg_params[i].size)
+ {
+ LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
+ exit(-1);
+ }
+ arm11_set_reg(reg,reg_params[i].value);
+// printf("%i: Set %s =%08x\n", i, reg_params[i].reg_name,val);
+ }
+
+ exit_breakpoint_size = 4;
+
+/* arm11->core_state = arm11_algorithm_info->core_state;
+ if (arm11->core_state == ARMV4_5_STATE_ARM)
+ exit_breakpoint_size = 4;
+ else if (arm11->core_state == ARMV4_5_STATE_THUMB)
+ exit_breakpoint_size = 2;
+ else
+ {
+ LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
+ exit(-1);
+ }
+*/
+ if (arm11_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
+ {
+ LOG_DEBUG("setting core_mode: 0x%2.2x", arm11_algorithm_info->core_mode);
+ buf_set_u32(arm11->reg_list[ARM11_RC_CPSR].value, 0, 5, arm11_algorithm_info->core_mode);
+ arm11->reg_list[ARM11_RC_CPSR].dirty = 1;
+ arm11->reg_list[ARM11_RC_CPSR].valid = 1;
+ }
+ if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
+ {
+ LOG_ERROR("can't add breakpoint to finish algorithm execution");
+ retval = ERROR_TARGET_FAILURE;
+ goto restore;
+ }
+
+ // no debug, otherwise breakpoint is not set
+ if((retval = target_resume(target, 0, entry_point, 1, 0)) != ERROR_OK)
+ {
+ return retval;
+ }
+
+ if((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
+ {
+ return retval;
+ }
+
+ if (target->state != TARGET_HALTED)
+ {
+ if ((retval=target_halt(target))!=ERROR_OK)
+ return retval;
+ if ((retval=target_wait_state(target, TARGET_HALTED, 500))!=ERROR_OK)
+ {
+ return retval;
+ }
+ retval = ERROR_TARGET_TIMEOUT;
+ goto del_breakpoint;
+ }
+
+ if (buf_get_u32(arm11->reg_list[15].value, 0, 32) != exit_point)
+ {
+ LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
+ buf_get_u32(arm11->reg_list[15].value, 0, 32));
+ retval = ERROR_TARGET_TIMEOUT;
+ goto del_breakpoint;
+ }
+
+ for (i = 0; i < num_mem_params; i++)
+ {
+ if (mem_params[i].direction != PARAM_OUT)
+ target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
+ }
+
+ for (i = 0; i < num_reg_params; i++)
+ {
+ if (reg_params[i].direction != PARAM_OUT)
+ {
+ reg_t *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0);
+ if (!reg)
+ {
+ LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
+ exit(-1);
+ }
+
+ if (reg->size != reg_params[i].size)
+ {
+ LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
+ exit(-1);
+ }
+
+ buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
+ }
+ }
+
+del_breakpoint:
+ breakpoint_remove(target, exit_point);
+
+restore:
+ // Restore context
+ for (i = 0; i < 16; i++)
+ {
+ LOG_DEBUG("restoring register %s with value 0x%8.8x",
+ arm11->reg_list[i].name, 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], (u8*)&cpsr);
+
+// arm11->core_state = core_state;
+// arm11->core_mode = core_mode;
+
+ return retval;