static int swd_init(struct command_context *ctx) { struct target *target = get_current_target(ctx); struct arm *arm = target_to_arm(target); struct adiv5_dap *dap = arm->dap; uint32_t idcode; int status; /* FIXME validate transport config ... is the * configured DAP present (check IDCODE)? * Is *only* one DAP configured? * * MUST READ IDCODE */ /* Note, debugport_init() does setup too */ uint8_t ack; status = swd_queue_idcode_read(dap, &ack, &idcode); if (status == ERROR_OK) LOG_INFO("SWD IDCODE %#8.8x", idcode); return status; }
/*! Find the target in first word of psz_args or use $@ (the current stack) if none. We also allow $@ or @ explicitly as a target name to mean the current target on the stack. NULL is returned if a lookup of the target name was not found. ppsz_target is to the name looked up. */ file_t * get_target(char **ppsz_args, /*out*/ const char **ppsz_target) { if (!*ppsz_args || !**ppsz_args) { file_t *p_target = (file_t *) get_current_target(); /* Use current target */ if (p_target && p_target->name) { *ppsz_args = (char *) p_target->name; } else { printf(_("Default target not found here. You must supply one\n")); return NULL; } } *ppsz_target = get_word(ppsz_args); /* As a special case, we'll allow $@ or @ for the current target. */ if ( 0 == strcmp("$@", *ppsz_target) || 0 == strcmp("@", *ppsz_target) ) { if (p_stack && p_stack->p_target && p_stack->p_target->name) *ppsz_target = p_stack->p_target->name; else { printf(_("No current target found for $@ - supply a target name.\n")); return NULL; } } { file_t *p_target = lookup_file (*ppsz_target); if (!p_target) printf(_("Target \"%s\" doesn't appear to be a target name.\n"), *ppsz_target); return p_target; } }
static int swd_select(struct command_context *ctx) { struct target *target = get_current_target(ctx); int retval; retval = register_commands(ctx, NULL, swd_handlers); if (retval != ERROR_OK) return retval; /* be sure driver is in SWD mode; start * with hardware default TRN (1), it can be changed later */ if (!swd || !swd->read_reg || !swd->write_reg || !swd->init) { LOG_DEBUG("no SWD driver?"); return ERROR_FAIL; } retval = swd->init(1); if (retval != ERROR_OK) { LOG_DEBUG("can't init SWD driver"); return retval; } /* force DAP into SWD mode (not JTAG) */ retval = dap_to_swd(target); return retval; }
int handle_trace_history_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { target_t *target = get_current_target(cmd_ctx); trace_t *trace = target->trace_info; if (argc > 0) { trace->trace_history_pos = 0; trace->trace_history_overflowed = 0; if (!strcmp(args[0], "clear")) { /* clearing is implicit, we've just reset position anyway */ return ERROR_OK; } if (trace->trace_history) free(trace->trace_history); trace->trace_history_size = strtoul(args[0], NULL, 0); trace->trace_history = malloc(sizeof(u32) * trace->trace_history_size); command_print(cmd_ctx, "new trace history size: %i", trace->trace_history_size); } else { int i; int first = 0; int last = trace->trace_history_pos; if ( !trace->trace_history_size ) { command_print(cmd_ctx, "trace history buffer is not allocated"); return ERROR_OK; } if (trace->trace_history_overflowed) { first = trace->trace_history_pos; last = trace->trace_history_pos - 1; } for (i = first; (i % trace->trace_history_size) != last; i++) { if (trace->trace_history[i % trace->trace_history_size] < trace->num_trace_points) { u32 address; address = trace->trace_points[trace->trace_history[i % trace->trace_history_size]].address; command_print(cmd_ctx, "trace point %i: 0x%8.8x", trace->trace_history[i % trace->trace_history_size], address); } else { command_print(cmd_ctx, "trace point %i: -not defined-", trace->trace_history[i % trace->trace_history_size]); } } } return ERROR_OK; }
/* write a byte array from the pc to the netx */ int fn_write_image(void *pvHandle, unsigned long ulNetxAddress, const char *pcData, unsigned long ulSize, lua_State *L, int iLuaCallbackTag, void *pvCallbackUserData) { command_context_t *cmd_ctx; target_t *target; int iResult; /* cast the handle to the command context */ cmd_ctx = (command_context_t*)pvHandle; /* get the target from the command context */ target = get_current_target(cmd_ctx); /* write the data to the netX */ iResult = target_write_buffer(target, ulNetxAddress, ulSize, (u8*)pcData); if( iResult==ERROR_OK ) { iResult = 0; } else { iResult = 1; } wxMilliSleep(1); return iResult; }
/* write a long (32bit) from the pc to the netx */ int fn_write_data32(void *pvHandle, unsigned long ulNetxAddress, unsigned long ulData) { command_context_t *cmd_ctx; target_t *target; int iResult; /* cast the handle to the command context */ cmd_ctx = (command_context_t*)pvHandle; /* get the target from the command context */ target = get_current_target(cmd_ctx); /* read the data from the netX */ iResult = target_write_u32(target, ulNetxAddress, ulData); if( iResult==ERROR_OK ) { iResult = 0; } else { iResult = 1; } wxMilliSleep(1); return iResult; }
static int cmsis_dap_init(struct command_context *ctx) { struct target *target = get_current_target(ctx); struct arm *arm = target_to_arm(target); struct adiv5_dap *dap = arm->dap; uint32_t idcode; int status; LOG_DEBUG("CMSIS-ADI: cmsis_dap_init"); /* Force the DAP's ops vector for CMSIS-DAP mode. * messy - is there a better way? */ arm->dap->ops = &cmsis_dap_ops; /* FIXME validate transport config ... is the * configured DAP present (check IDCODE)? * Is *only* one DAP configured? * * MUST READ IDCODE */ /* Note, debugport_init() does setup too */ #if 0 const struct swd_driver *swd = jtag_interface->swd; if (!swd || !swd->read_reg || !swd->write_reg || !swd->init) { LOG_ERROR("no SWD driver?"); return ERROR_FAIL; } int retval = swd->init(1); if (retval != ERROR_OK) { LOG_ERROR("unable to init CMSIS-DAP driver"); return retval; } #endif uint8_t ack; status = cmsis_dap_queue_idcode_read(dap, &ack, &idcode); if (status == ERROR_OK) LOG_INFO("IDCODE 0x%08" PRIx32, idcode); /* force clear all sticky faults */ cmsis_dap_queue_ap_abort(dap, &ack); /* this is a workaround to get polling working */ jtag_add_reset(0, 0); return status; }
/*! Return the current target from the stack or NULL if none set. */ const floc_t * get_current_floc(void) { file_t *p_target = (file_t *) get_current_target(); floc_t *p_floc; p_floc = &p_target->floc; if (p_floc->filenm && p_floc->lineno != 0) return p_floc; else return NULL; }
static int stlink_transport_init(struct command_context *cmd_ctx) { LOG_DEBUG("stlink_transport_init"); struct target *t = get_current_target(cmd_ctx); if (!t) { LOG_ERROR("stlink_transport_init: no current target"); return ERROR_FAIL; } stlink_interface_open(); return stlink_interface_init_target(t); }
int handle_trace_point_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { target_t *target = get_current_target(cmd_ctx); trace_t *trace = target->trace_info; if (argc == 0) { int i; for (i = 0; i < trace->num_trace_points; i++) { command_print(cmd_ctx, "trace point 0x%8.8x (%"PRIi64" times hit)", trace->trace_points[i].address, trace->trace_points[i].hit_counter); } return ERROR_OK; } if (!strcmp(args[0], "clear")) { if (trace->trace_points) { free(trace->trace_points); trace->trace_points = NULL; } trace->num_trace_points = 0; trace->trace_points_size = 0; return ERROR_OK; } /* resize array if necessary */ if (!trace->trace_points || (trace->trace_points_size == trace->num_trace_points)) { trace->trace_points = realloc(trace->trace_points, sizeof(trace_point_t) * (trace->trace_points_size + 32)); trace->trace_points_size += 32; } trace->trace_points[trace->num_trace_points].address = strtoul(args[0], NULL, 0); trace->trace_points[trace->num_trace_points].hit_counter = 0; trace->num_trace_points++; 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; }
int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { target_t *target = get_current_target(cmd_ctx); armv4_5_common_t *armv4_5; arm7_9_common_t *arm7_9; arm9tdmi_common_t *arm9tdmi; reg_t *vector_catch; u32 vector_catch_value; int i, j; if (arm9tdmi_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi) != ERROR_OK) { command_print(cmd_ctx, "current target isn't an ARM9TDMI based target"); return ERROR_OK; } vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]; /* read the vector catch register if necessary */ if (!vector_catch->valid) embeddedice_read_reg(vector_catch); /* get the current setting */ vector_catch_value = buf_get_u32(vector_catch->value, 0, 32); if (argc > 0) { vector_catch_value = 0x0; if (strcmp(args[0], "all") == 0) { vector_catch_value = 0xdf; } else if (strcmp(args[0], "none") == 0) { /* do nothing */ } else { for (i = 0; i < argc; i++) { /* go through list of vectors */ for(j = 0; arm9tdmi_vectors[j].name; j++) { if (strcmp(args[i], arm9tdmi_vectors[j].name) == 0) { vector_catch_value |= arm9tdmi_vectors[j].value; break; } } /* complain if vector wasn't found */ if (!arm9tdmi_vectors[j].name) { command_print(cmd_ctx, "vector '%s' not found, leaving current setting unchanged", args[i]); /* reread current setting */ vector_catch_value = buf_get_u32(vector_catch->value, 0, 32); break; } } } /* store new settings */ buf_set_u32(vector_catch->value, 0, 32, vector_catch_value); embeddedice_store_reg(vector_catch); } /* output current settings (skip RESERVED vector) */ for (i = 0; i < 8; i++) { if (i != 5) { command_print(cmd_ctx, "%s: %s", arm9tdmi_vectors[i].name, (vector_catch_value & (1 << i)) ? "catch" : "don't catch"); } } return ERROR_OK; }
/* call routine */ int fn_call(void *pvHandle, unsigned long ulNetxAddress, unsigned long ulParameterR0, lua_State *L, int iLuaCallbackTag, void *pvCallbackUserData) { command_context_t *cmd_ctx; int iOocdResult; int iResult; wxString strCmd; target_t *target; bool fIsRunning; enum target_state state; /* cast the handle to the command context */ cmd_ctx = (command_context_t*)pvHandle; // expect failure iResult = 1; // set R0 parameter strCmd.Printf(wxT("reg r0 0x%08X"), ulParameterR0); iOocdResult = command_run_line(cmd_ctx, strCmd.ToAscii()); if( iOocdResult!=ERROR_OK ) { wxLogError(wxT("config failed!")); } else { // resume <ulNetxAddress> strCmd.Printf(wxT("resume 0x%08X"), ulNetxAddress); iOocdResult = command_run_line(cmd_ctx, strCmd.ToAscii()); if( iOocdResult!=ERROR_OK ) { wxLogError(wxT("config failed!")); } else { // grab messages here // TODO: redirect outputhandler, then grab messages, restore default output handler on halt // wait for halt target = get_current_target(cmd_ctx); do { wxMilliSleep(100); target->type->poll(target); state = target->state; if( state==TARGET_HALTED ) { wxLogMessage(wxT("call finished!")); iResult = 0; } else { // execute callback fIsRunning = callback(L, iLuaCallbackTag, 0, pvCallbackUserData); if( fIsRunning!=true ) { // operation was canceled, halt the target wxLogMessage(wxT("Call canceled, stopping target...")); target = get_current_target(cmd_ctx); iOocdResult = target->type->halt(target); if( iOocdResult!=ERROR_OK && iOocdResult!=ERROR_TARGET_ALREADY_HALTED ) { wxLogError(wxT("Failed to halt target!")); } break; } else { target_call_timer_callbacks(); } } } while( state!=TARGET_HALTED ); // usb cmd delay wxMilliSleep(1); } } return iResult; }
static int romloader_openocd_connect(command_context_t **pptCmdCtx) { int iResult; command_context_t *cmd_ctx; target_t *target; wxString strCmd; wxString strMsg; size_t sizCfgCnt; size_t sizCfgMax; int iInitCnt; cmd_ctx = command_init(); /* register subsystem commands */ log_register_commands(cmd_ctx); jtag_register_commands(cmd_ctx); interpreter_register_commands(cmd_ctx); xsvf_register_commands(cmd_ctx); target_register_commands(cmd_ctx); /* init the log functions */ iResult = log_init(cmd_ctx); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to init log level: %d"), iResult); wxLogError(strMsg); } else { command_set_output_handler(cmd_ctx, romloader_openocd_default_output_handler, NULL); log_set_output_handler(romloader_openocd_log_printf, romloader_openocd_short_log_printf); cmd_ctx->mode = COMMAND_CONFIG; // set config sizCfgCnt = 0; sizCfgMax = astrInitCfg.GetCount(); while( sizCfgCnt<sizCfgMax ) { strCmd = astrInitCfg.Item(sizCfgCnt); wxLogMessage(wxT("command: ") + strCmd); iResult = command_run_line(cmd_ctx, strCmd.ToAscii()); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to set config: %d"), iResult); wxLogError(strMsg); strMsg = wxT("error line was: '") + strCmd + wxT("'"); wxLogError(strMsg); break; } ++sizCfgCnt; } if( iResult==ERROR_OK ) { cmd_ctx->mode = COMMAND_EXEC; iResult = jtag_init(cmd_ctx); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to init jtag: %d"), iResult); wxLogError(strMsg); } else { iResult = target_init(cmd_ctx); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to init jtag: %d"), iResult); wxLogError(strMsg); } else { wxMilliSleep(500); /* wait for target reset */ iInitCnt = 10; do { target_call_timer_callbacks(); wxMilliSleep(100); } while( --iInitCnt>0 ); target = get_current_target(cmd_ctx); if( target->state!=TARGET_HALTED ) { wxLogError(wxT("failed to halt the target")); iResult = ERROR_TARGET_NOT_HALTED; } else { // set config sizCfgCnt = 0; sizCfgMax = astrRunCfg.GetCount(); while( sizCfgCnt<sizCfgMax ) { strCmd = astrRunCfg.Item(sizCfgCnt); wxLogMessage(wxT("command: ") + strCmd); iResult = command_run_line(cmd_ctx, strCmd.ToAscii()); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to run command: %d"), iResult); wxLogError(strMsg); strMsg = wxT("error line was: '") + strCmd + wxT("'"); wxLogError(strMsg); break; } ++sizCfgCnt; } if( iResult!=ERROR_OK ) { wxLogError(wxT("config failed!")); } } } } } } if( iResult!=ERROR_OK ) { // close connection romloader_openocd_close_instance(cmd_ctx); *pptCmdCtx = NULL; } else { // connection open, ok! *pptCmdCtx = cmd_ctx; } return iResult; }