static int avr32_ap7k_poll(struct target *target) { uint32_t ds; int retval; struct avr32_ap7k_common *ap7k = target_to_ap7k(target); retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds); if (retval != ERROR_OK) return retval; /* check for processor halted */ if (ds & OCDREG_DS_DBA) { if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { target->state = TARGET_HALTED; retval = avr32_ap7k_debug_entry(target); if (retval != ERROR_OK) return retval; target_call_event_callbacks(target, TARGET_EVENT_HALTED); } else if (target->state == TARGET_DEBUG_RUNNING) { target->state = TARGET_HALTED; retval = avr32_ap7k_debug_entry(target); if (retval != ERROR_OK) return retval; target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); } } else target->state = TARGET_RUNNING; return ERROR_OK; }
static int avr32_ap7k_halt(struct target *target) { struct avr32_ap7k_common *ap7k = target_to_ap7k(target); LOG_DEBUG("target->state: %s", target_state_name(target)); if (target->state == TARGET_HALTED) { LOG_DEBUG("target was already halted"); return ERROR_OK; } if (target->state == TARGET_UNKNOWN) LOG_WARNING("target was in unknown state when halt was requested"); if (target->state == TARGET_RESET) { if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) { LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); return ERROR_TARGET_FAILURE; } else { target->debug_reason = DBG_REASON_DBGRQ; return ERROR_OK; } } avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBR); target->debug_reason = DBG_REASON_DBGRQ; return ERROR_OK; }
static struct reg_cache *avr32_build_reg_cache(struct target *target) { int num_regs = AVR32NUMCOREREGS; struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); struct reg_cache *cache = malloc(sizeof(struct reg_cache)); struct reg *reg_list = calloc(num_regs, sizeof(struct reg)); struct avr32_core_reg *arch_info = malloc(sizeof(struct avr32_core_reg) * num_regs); int i; /* Build the process context cache */ cache->name = "avr32 registers"; cache->next = NULL; cache->reg_list = reg_list; cache->num_regs = num_regs; (*cache_p) = cache; ap7k->core_cache = cache; for (i = 0; i < num_regs; i++) { arch_info[i] = avr32_core_reg_list_arch_info[i]; arch_info[i].target = target; arch_info[i].avr32_common = ap7k; reg_list[i].name = avr32_core_reg_list[i]; reg_list[i].size = 32; reg_list[i].value = calloc(1, 4); reg_list[i].dirty = 0; reg_list[i].valid = 0; reg_list[i].type = &avr32_reg_type; reg_list[i].arch_info = &arch_info[i]; } return cache; }
static int avr32_ap7k_examine(struct target *target) { uint32_t devid, ds; struct avr32_ap7k_common *ap7k = target_to_ap7k(target); if (!target_was_examined(target)) { target_set_examined(target); avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DID, &devid); LOG_INFO("device id: %08x", devid); avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC,OCDREG_DC_DBE); avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds); /* check for processor halted */ if (ds & OCDREG_DS_DBA) { LOG_INFO("target is halted"); target->state = TARGET_HALTED; } else target->state = TARGET_RUNNING; } return ERROR_OK; }
int avr32_ap7k_arch_state(struct target *target) { struct avr32_ap7k_common *ap7k = target_to_ap7k(target); LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "", debug_reason_name(target), ap7k->jtag.dpc); return ERROR_OK; }
static int avr32_ap7k_init_target(struct command_context *cmd_ctx, struct target *target) { struct avr32_ap7k_common *ap7k = target_to_ap7k(target); ap7k->jtag.tap = target->tap; avr32_build_reg_cache(target); return ERROR_OK; }
int avr32_ap7k_save_context(struct target *target) { int retval, i; struct avr32_ap7k_common *ap7k = target_to_ap7k(target); retval = avr32_jtag_read_regs(&ap7k->jtag, ap7k->core_regs); if (retval != ERROR_OK) return retval; for (i = 0; i < AVR32NUMCOREREGS; i++) { if (!ap7k->core_cache->reg_list[i].valid) avr32_read_core_reg(target, i); } return ERROR_OK; }
int avr32_ap7k_restore_context(struct target *target) { int i; /* get pointers to arch-specific information */ struct avr32_ap7k_common *ap7k = target_to_ap7k(target); for (i = 0; i < AVR32NUMCOREREGS; i++) { if (ap7k->core_cache->reg_list[i].dirty) avr32_write_core_reg(target, i); } /* write core regs */ avr32_jtag_write_regs(&ap7k->jtag, ap7k->core_regs); return ERROR_OK; }
static int avr32_read_core_reg(struct target *target, int num) { uint32_t reg_value; /* get pointers to arch-specific information */ struct avr32_ap7k_common *ap7k = target_to_ap7k(target); if ((num < 0) || (num >= AVR32NUMCOREREGS)) return ERROR_COMMAND_SYNTAX_ERROR; reg_value = ap7k->core_regs[num]; buf_set_u32(ap7k->core_cache->reg_list[num].value, 0, 32, reg_value); ap7k->core_cache->reg_list[num].valid = 1; ap7k->core_cache->reg_list[num].dirty = 0; return ERROR_OK; }
static int avr32_write_core_reg(struct target *target, int num) { uint32_t reg_value; /* get pointers to arch-specific information */ struct avr32_ap7k_common *ap7k = target_to_ap7k(target); if ((num < 0) || (num >= AVR32NUMCOREREGS)) return ERROR_COMMAND_SYNTAX_ERROR; reg_value = buf_get_u32(ap7k->core_cache->reg_list[num].value, 0, 32); ap7k->core_regs[num] = reg_value; LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value); ap7k->core_cache->reg_list[num].valid = 1; ap7k->core_cache->reg_list[num].dirty = 0; return ERROR_OK; }
static int avr32_ap7k_debug_entry(struct target *target) { uint32_t dpc, dinst; int retval; struct avr32_ap7k_common *ap7k = target_to_ap7k(target); retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DPC, &dpc); if (retval != ERROR_OK) return retval; retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DINST, &dinst); if (retval != ERROR_OK) return retval; ap7k->jtag.dpc = dpc; avr32_ap7k_save_context(target); return ERROR_OK; }
static int avr32_ap7k_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { struct avr32_ap7k_common *ap7k = target_to_ap7k(target); LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); if (target->state != TARGET_HALTED) { LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } /* sanitize arguments */ if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) return ERROR_COMMAND_SYNTAX_ERROR; if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) return ERROR_TARGET_UNALIGNED_ACCESS; switch (size) { case 4: return avr32_jtag_write_memory32(&ap7k->jtag, address, count, (uint32_t *)(void *)buffer); break; case 2: return avr32_jtag_write_memory16(&ap7k->jtag, address, count, (uint16_t *)(void *)buffer); break; case 1: return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer); break; default: break; } return ERROR_OK; }
static int avr32_ap7k_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution) { struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct breakpoint *breakpoint = NULL; uint32_t resume_pc; int retval; if (target->state != TARGET_HALTED) { LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } if (!debug_execution) { target_free_all_working_areas(target); /* avr32_ap7k_enable_breakpoints(target); avr32_ap7k_enable_watchpoints(target); */ } /* current = 1: continue on current pc, otherwise continue at <address> */ if (!current) { #if 0 if (retval != ERROR_OK) return retval; #endif } resume_pc = buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32); avr32_ap7k_restore_context(target); /* the front-end may request us not to handle breakpoints */ if (handle_breakpoints) { /* Single step past breakpoint at current address */ breakpoint = breakpoint_find(target, resume_pc); if (breakpoint) { LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address); #if 0 avr32_ap7k_unset_breakpoint(target, breakpoint); avr32_ap7k_single_step_core(target); avr32_ap7k_set_breakpoint(target, breakpoint); #endif } } #if 0 /* enable interrupts if we are running */ avr32_ap7k_enable_interrupts(target, !debug_execution); /* exit debug mode */ mips_ejtag_exit_debug(ejtag_info); #endif retval = avr32_ocd_clearbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBR); if (retval != ERROR_OK) return retval; retval = avr32_jtag_exec(&ap7k->jtag, RETD); if (retval != ERROR_OK) return retval; target->debug_reason = DBG_REASON_NOTHALTED; /* registers are now invalid */ register_cache_invalidate(ap7k->core_cache); if (!debug_execution) { target->state = TARGET_RUNNING; target_call_event_callbacks(target, TARGET_EVENT_RESUMED); LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc); } else { target->state = TARGET_DEBUG_RUNNING; target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc); } return ERROR_OK; }