static int or1k_examine(struct target *target) { struct or1k_common *or1k = target_to_or1k(target); struct or1k_du *du_core = or1k_to_du(or1k); if (!target_was_examined(target)) { target_set_examined(target); int running; int retval = du_core->or1k_is_cpu_running(&or1k->jtag, &running); if (retval != ERROR_OK) { LOG_ERROR("Couldn't read the CPU state"); return retval; } else { if (running) target->state = TARGET_RUNNING; else { LOG_DEBUG("Target is halted"); /* This is the first time we examine the target, * it is stalled and we don't know why. Let's * assume this is because of a debug reason. */ if (target->state == TARGET_UNKNOWN) target->debug_reason = DBG_REASON_DBGRQ; target->state = TARGET_HALTED; } } } return ERROR_OK; }
int arc_ocd_examine(struct target *target) { uint32_t status; struct arc32_common *arc32 = target_to_arc32(target); LOG_DEBUG("-"); CHECK_RETVAL(arc_jtag_startup(&arc32->jtag_info)); if (!target_was_examined(target)) { CHECK_RETVAL(arc_jtag_status(&arc32->jtag_info, &status)); if (status & ARC_JTAG_STAT_RU) { target->state = TARGET_RUNNING; } else { /* It is first time we examine the target, it is halted * and we don't know why. Let's set debug reason, * otherwise OpenOCD will complain that reason is * unknown. */ if (target->state == TARGET_UNKNOWN) target->debug_reason = DBG_REASON_DBGRQ; target->state = TARGET_HALTED; } /* Read BCRs and configure optional registers. */ CHECK_RETVAL(arc32_configure(target)); target_set_examined(target); } return ERROR_OK; }
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; }
static int xtensa_examine(struct target *target) { int res = ERROR_OK; size_t i; if (!target_was_examined(target)) { target_set_examined(target); /* without IDCODE, there isn't actually a lot we can do here apart from try to poll and check that the TAP responds to it, ie has some known Xtensa registers. */ res = xtensa_poll(target); if(res != ERROR_OK) { LOG_ERROR("Failed to examine target."); return ERROR_FAIL; } if(target->state == TARGET_HALTED) { LOG_DEBUG("Resetting breakpoint/watchpoint state..."); xtensa_tap_queue_write_sr(target, XT_REG_IDX_IBREAKENABLE, 0); for(i = 0; i < XT_NUM_WATCHPOINTS; i++) { xtensa_tap_queue_write_sr(target, XT_REG_IDX_DBREAKA0+i*2, 0); xtensa_tap_queue_write_sr(target, XT_REG_IDX_DBREAKC0+i*2, 0); } res = jtag_execute_queue(); } else { LOG_WARNING("Warning: Target not halted, breakpoint/watchpoint state may be unpredictable."); } } return res; }
static int or1k_examine(struct target *target) { uint32_t cpu_cr; struct or1k_common *or1k = target_to_or1k(target); if (!target_was_examined(target)) { target_set_examined(target); /* Do nothing special yet - Julius */ /* 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 */ /* Possible specific to Mohor debug interface - others may * have to do something different here. */ or1k_jtag_read_cpu_cr(&or1k->jtag, &cpu_cr); if (cpu_cr & OR1K_MOHORDBGIF_CPU_CR_STALL) { LOG_DEBUG("target is halted"); target->state = TARGET_HALTED; } else target->state = TARGET_RUNNING; } return ERROR_OK; }
static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **rtos_reg_list, int *num_regs) { struct target_list *head; struct target *target; struct target *curr; struct reg **reg_list; int retval; if (rtos == NULL) return ERROR_FAIL; target = rtos->target; /* Find the thread with that thread_id */ if (target->smp) { curr = NULL; for (head = target->head; head != NULL; head = head->next) { curr = head->target; if (thread_id == threadid_from_target(curr)) break; } if (head == NULL) return ERROR_FAIL; } else { curr = target; if (thread_id != threadid_from_target(curr)) return ERROR_FAIL; } if (!target_was_examined(curr)) return ERROR_FAIL; retval = target_get_gdb_reg_list(curr, ®_list, num_regs, REG_CLASS_GENERAL); if (retval != ERROR_OK) return retval; *rtos_reg_list = calloc(*num_regs, sizeof(struct rtos_reg)); if (*rtos_reg_list == NULL) { free(reg_list); return ERROR_FAIL; } for (int i = 0; i < *num_regs; i++) { (*rtos_reg_list)[i].number = (*reg_list)[i].number; (*rtos_reg_list)[i].size = (*reg_list)[i].size; memcpy((*rtos_reg_list)[i].value, (*reg_list)[i].value, ((*reg_list)[i].size + 7) / 8); } free(reg_list); return ERROR_OK; }
/* talk to the target and set things up */ static int nds32_v3m_examine(struct target *target) { struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); struct nds32 *nds32 = &(nds32_v3m->nds32); struct aice_port_s *aice = target_to_aice(target); if (!target_was_examined(target)) { CHECK_RETVAL(nds32_edm_config(nds32)); if (nds32->reset_halt_as_examine) CHECK_RETVAL(nds32_reset_halt(nds32)); } uint32_t edm_cfg; aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); /* get the number of hardware breakpoints */ nds32_v3m->n_hbr = (edm_cfg & 0x7) + 1; nds32_v3m->used_n_wp = 0; /* get the number of hardware watchpoints */ /* If the WP field is hardwired to zero, it means this is a * simple breakpoint. Otherwise, if the WP field is writable * then it means this is a regular watchpoints. */ nds32_v3m->n_hwp = 0; for (int32_t i = 0 ; i < nds32_v3m->n_hbr ; i++) { /** check the hardware breakpoint is simple or not */ uint32_t tmp_value; aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + i, 0x1); aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &tmp_value); if (tmp_value) nds32_v3m->n_hwp++; } /* hardware breakpoint is inserted from high index to low index */ nds32_v3m->next_hbr_index = nds32_v3m->n_hbr - 1; /* hardware watchpoint is inserted from low index to high index */ nds32_v3m->next_hwp_index = 0; LOG_INFO("%s: total hardware breakpoint %d (simple breakpoint %d)", target_name(target), nds32_v3m->n_hbr, nds32_v3m->n_hbr - nds32_v3m->n_hwp); LOG_INFO("%s: total hardware watchpoint %d", target_name(target), nds32_v3m->n_hwp); nds32->target->state = TARGET_RUNNING; nds32->target->debug_reason = DBG_REASON_NOTHALTED; target_set_examined(target); return ERROR_OK; }
int arc_ocd_examine(struct target *target) { uint32_t status; struct arc32_common *arc32 = target_to_arc32(target); LOG_DEBUG("-"); CHECK_RETVAL(arc_jtag_startup(&arc32->jtag_info)); if (!target_was_examined(target)) { /* read ARC core info */ if (strncmp(target_name(target), ARCEM_STR, 6) == 0) { arc32->processor_type = ARCEM_NUM; LOG_USER("Processor type: %s", ARCEM_STR); } else if (strncmp(target_name(target), ARC600_STR, 6) == 0) { arc32->processor_type = ARC600_NUM; LOG_USER("Processor type: %s", ARC600_STR); } else if (strncmp(target_name(target), ARC700_STR, 6) == 0) { arc32->processor_type = ARC700_NUM; LOG_USER("Processor type: %s", ARC700_STR); } else { LOG_WARNING(" THIS IS A UNSUPPORTED TARGET: %s", target_name(target)); } CHECK_RETVAL(arc_jtag_status(&arc32->jtag_info, &status)); if (status & ARC_JTAG_STAT_RU) { target->state = TARGET_RUNNING; } else { /* It is first time we examine the target, it is halted * and we don't know why. Let's set debug reason, * otherwise OpenOCD will complain that reason is * unknown. */ if (target->state == TARGET_UNKNOWN) target->debug_reason = DBG_REASON_DBGRQ; target->state = TARGET_HALTED; } /* Read BCRs and configure optinal registers. */ CHECK_RETVAL(arc_regs_read_bcrs(target)); arc_regs_build_reg_list(target); CHECK_RETVAL(arc32_configure(target)); target_set_examined(target); } return ERROR_OK; }
int mips32_examine(struct target *target) { struct mips32_common *mips32 = target_to_mips32(target); if (!target_was_examined(target)) { target_set_examined(target); /* we will configure later */ mips32->bp_scanned = 0; mips32->num_inst_bpoints = 0; mips32->num_data_bpoints = 0; mips32->num_inst_bpoints_avail = 0; mips32->num_data_bpoints_avail = 0; } return ERROR_OK; }
static int arm11_assert_reset(struct target *target) { struct arm11_common *arm11 = target_to_arm11(target); if (!(target_was_examined(target))) { if (jtag_get_reset_config() & RESET_HAS_SRST) jtag_add_reset(0, 1); else { LOG_WARNING("Reset is not asserted because the target is not examined."); LOG_WARNING("Use a reset button or power cycle the target."); return ERROR_TARGET_NOT_EXAMINED; } } else { /* optionally catch reset vector */ if (target->reset_halt && !(arm11->vcr & 1)) CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1)); /* Issue some kind of warm reset. */ if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) target_handle_event(target, TARGET_EVENT_RESET_ASSERT); else if (jtag_get_reset_config() & RESET_HAS_SRST) { /* REVISIT handle "pulls" cases, if there's * hardware that needs them to work. */ jtag_add_reset(0, 1); } else { LOG_ERROR("%s: how to reset?", target_name(target)); return ERROR_FAIL; } } /* registers are now invalid */ register_cache_invalidate(arm11->arm.core_cache); target->state = TARGET_RESET; return ERROR_OK; }
/* talk to the target and set things up */ static int arm11_examine(struct target *target) { int retval; char *type; struct arm11_common *arm11 = target_to_arm11(target); uint32_t didr, device_id; uint8_t implementor; /* FIXME split into do-first-time and do-every-time logic ... */ /* check IDCODE */ arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT); struct scan_field idcode_field; arm11_setup_field(arm11, 32, NULL, &device_id, &idcode_field); arm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &idcode_field, TAP_DRPAUSE); /* check DIDR */ arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT); arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); struct scan_field chain0_fields[2]; arm11_setup_field(arm11, 32, NULL, &didr, chain0_fields + 0); arm11_setup_field(arm11, 8, NULL, &implementor, chain0_fields + 1); arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain0_fields), chain0_fields, TAP_IDLE); CHECK_RETVAL(jtag_execute_queue()); /* assume the manufacturer id is ok; check the part # */ switch ((device_id >> 12) & 0xFFFF) { case 0x7B36: type = "ARM1136"; break; case 0x7B37: type = "ARM11 MPCore"; break; case 0x7B56: type = "ARM1156"; break; case 0x7B76: arm11->arm.core_type = ARM_MODE_MON; /* NOTE: could default arm11->hardware_step to true */ type = "ARM1176"; break; default: LOG_ERROR("unexpected ARM11 ID code"); return ERROR_FAIL; } LOG_INFO("found %s", type); /* unlikely this could ever fail, but ... */ switch ((didr >> 16) & 0x0F) { case ARM11_DEBUG_V6: case ARM11_DEBUG_V61: /* supports security extensions */ break; default: LOG_ERROR("Only ARM v6 and v6.1 debug supported."); return ERROR_FAIL; } arm11->brp = ((didr >> 24) & 0x0F) + 1; /** \todo TODO: reserve one brp slot if we allow breakpoints during step */ arm11->free_brps = arm11->brp; LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32, device_id, implementor, didr); /* 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. */ retval = arm11_check_init(arm11); if (retval != ERROR_OK) return retval; /* Build register cache "late", after target_init(), since we * want to know if this core supports Secure Monitor mode. */ if (!target_was_examined(target)) CHECK_RETVAL(arm11_dpm_init(arm11, didr)); /* ETM on ARM11 still uses original scanchain 6 access mode */ if (arm11->arm.etm && !target_was_examined(target)) { *register_get_last_cache_p(&target->reg_cache) = etm_build_reg_cache(target, &arm11->jtag_info, arm11->arm.etm); CHECK_RETVAL(etm_setup(target)); } target_set_examined(target); return ERROR_OK; }
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { struct command_context *context; struct target *target; struct arm *arm; int retval; context = current_command_context(interp); assert(context != NULL); target = get_current_target(context); if (target == NULL) { LOG_ERROR("%s: no current target", __func__); return JIM_ERR; } if (!target_was_examined(target)) { LOG_ERROR("%s: not yet examined", target_name(target)); return JIM_ERR; } arm = target_to_arm(target); if (!is_arm(arm)) { LOG_ERROR("%s: not an ARM", target_name(target)); return JIM_ERR; } if ((argc < 6) || (argc > 7)) { /* FIXME use the command name to verify # params... */ LOG_ERROR("%s: wrong number of arguments", __func__); return JIM_ERR; } int cpnum; uint32_t op1; uint32_t op2; uint32_t CRn; uint32_t CRm; uint32_t value; long l; /* NOTE: parameter sequence matches ARM instruction set usage: * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX * The "rX" is necessarily omitted; it uses Tcl mechanisms. */ retval = Jim_GetLong(interp, argv[1], &l); if (retval != JIM_OK) return retval; if (l & ~0xf) { LOG_ERROR("%s: %s %d out of range", __func__, "coprocessor", (int) l); return JIM_ERR; } cpnum = l; retval = Jim_GetLong(interp, argv[2], &l); if (retval != JIM_OK) return retval; if (l & ~0x7) { LOG_ERROR("%s: %s %d out of range", __func__, "op1", (int) l); return JIM_ERR; } op1 = l; retval = Jim_GetLong(interp, argv[3], &l); if (retval != JIM_OK) return retval; if (l & ~0xf) { LOG_ERROR("%s: %s %d out of range", __func__, "CRn", (int) l); return JIM_ERR; } CRn = l; retval = Jim_GetLong(interp, argv[4], &l); if (retval != JIM_OK) return retval; if (l & ~0xf) { LOG_ERROR("%s: %s %d out of range", __func__, "CRm", (int) l); return JIM_ERR; } CRm = l; retval = Jim_GetLong(interp, argv[5], &l); if (retval != JIM_OK) return retval; if (l & ~0x7) { LOG_ERROR("%s: %s %d out of range", __func__, "op2", (int) l); return JIM_ERR; } op2 = l; value = 0; /* FIXME don't assume "mrc" vs "mcr" from the number of params; * that could easily be a typo! Check both... * * FIXME change the call syntax here ... simplest to just pass * the MRC() or MCR() instruction to be executed. That will also * let us support the "mrc2" and "mcr2" opcodes (toggling one bit) * if that's ever needed. */ if (argc == 7) { retval = Jim_GetLong(interp, argv[6], &l); if (retval != JIM_OK) return retval; value = l; /* NOTE: parameters reordered! */ /* ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2) */ retval = arm->mcr(target, cpnum, op1, op2, CRn, CRm, value); if (retval != ERROR_OK) return JIM_ERR; } else { /* NOTE: parameters reordered! */ /* ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2) */ retval = arm->mrc(target, cpnum, op1, op2, CRn, CRm, &value); if (retval != ERROR_OK) return JIM_ERR; Jim_SetResult(interp, Jim_NewIntObj(interp, value)); } return JIM_OK; }
static int hwthread_update_threads(struct rtos *rtos) { int threads_found = 0; int thread_list_size = 0; struct target_list *head; struct target *target; int64_t current_thread = 0; enum target_debug_reason current_reason = DBG_REASON_UNDEFINED; if (rtos == NULL) return -1; target = rtos->target; /* wipe out previous thread details if any */ rtos_free_threadlist(rtos); /* determine the number of "threads" */ if (target->smp) { for (head = target->head; head != NULL; head = head->next) { struct target *curr = head->target; if (!target_was_examined(curr)) continue; ++thread_list_size; } } else thread_list_size = 1; /* create space for new thread details */ rtos->thread_details = malloc(sizeof(struct thread_detail) * thread_list_size); if (target->smp) { /* loop over all threads */ for (head = target->head; head != NULL; head = head->next) { struct target *curr = head->target; if (!target_was_examined(curr)) continue; threadid_t tid = threadid_from_target(curr); hwthread_fill_thread(rtos, curr, threads_found); /* find an interesting thread to set as current */ switch (current_reason) { case DBG_REASON_UNDEFINED: current_reason = curr->debug_reason; current_thread = tid; break; case DBG_REASON_SINGLESTEP: /* single-step can only be overridden by itself */ if (curr->debug_reason == DBG_REASON_SINGLESTEP) { if (tid == rtos->current_threadid) current_thread = tid; } break; case DBG_REASON_BREAKPOINT: /* single-step overrides breakpoint */ if (curr->debug_reason == DBG_REASON_SINGLESTEP) { current_reason = curr->debug_reason; current_thread = tid; } else /* multiple breakpoints, prefer gdbs' threadid */ if (curr->debug_reason == DBG_REASON_BREAKPOINT) { if (tid == rtos->current_threadid) current_thread = tid; } break; case DBG_REASON_WATCHPOINT: /* breakpoint and single-step override watchpoint */ if (curr->debug_reason == DBG_REASON_SINGLESTEP || curr->debug_reason == DBG_REASON_BREAKPOINT) { current_reason = curr->debug_reason; current_thread = tid; } break; case DBG_REASON_DBGRQ: /* all other reasons override debug-request */ if (curr->debug_reason == DBG_REASON_SINGLESTEP || curr->debug_reason == DBG_REASON_WATCHPOINT || curr->debug_reason == DBG_REASON_BREAKPOINT) { current_reason = curr->debug_reason; current_thread = tid; } else if (curr->debug_reason == DBG_REASON_DBGRQ) { if (tid == rtos->current_threadid) current_thread = tid; } break; default: break; } threads_found++; } } else { hwthread_fill_thread(rtos, target, threads_found); current_thread = threadid_from_target(target); threads_found++; } rtos->thread_count = threads_found; /* we found an interesting thread, set it as current */ if (current_thread != 0) rtos->current_thread = current_thread; else if (rtos->current_threadid != 0) rtos->current_thread = rtos->current_threadid; else rtos->current_thread = threadid_from_target(target); LOG_DEBUG("%s current_thread=%i", __func__, (int)rtos->current_thread); return 0; }