X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=b5c473b21e0495ea713d2f5b05269374d5da57dc;hp=ced09e900966f36d2042868cdafcc47fd4e30b00;hb=6a0af06bd9f66780d2c3e9f69c40f2b89ad90605;hpb=a8234af06c16500426a421910886d26a46e6fa53 diff --git a/src/target/target.c b/src/target/target.c index ced09e9009..b5c473b21e 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -69,6 +69,7 @@ static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, cha static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv); static int jim_target(Jim_Interp *interp, int argc, Jim_Obj *const *argv); @@ -378,24 +379,57 @@ target_t* get_current_target(command_context_t *cmd_ctx) int target_poll(struct target_s *target) { + int retval; + /* We can't poll until after examine */ if (!target_was_examined(target)) { /* Fail silently lest we pollute the log */ return ERROR_FAIL; } - return target->type->poll(target); + + retval = target->type->poll(target); + if (retval != ERROR_OK) + return retval; + + if (target->halt_issued) + { + if (target->state == TARGET_HALTED) + { + target->halt_issued = false; + } else + { + long long t = timeval_ms() - target->halt_issued_time; + if (t>1000) + { + target->halt_issued = false; + LOG_INFO("Halt timed out, wake up GDB."); + target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); + } + } + } + + return ERROR_OK; } int target_halt(struct target_s *target) { + int retval; /* We can't poll until after examine */ if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; } - return target->type->halt(target); + + retval = target->type->halt(target); + if (retval != ERROR_OK) + return retval; + + target->halt_issued = true; + target->halt_issued_time = timeval_ms(); + + return ERROR_OK; } int target_resume(struct target_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution) @@ -462,7 +496,13 @@ static int default_virt2phys(struct target_s *target, uint32_t virtual, uint32_t static int default_mmu(struct target_s *target, int *enabled) { - *enabled = 0; + LOG_ERROR("Not implemented."); + return ERROR_FAIL; +} + +static int default_has_mmu(struct target_s *target, bool *has_mmu) +{ + *has_mmu = true; return ERROR_OK; } @@ -568,11 +608,24 @@ int target_read_memory(struct target_s *target, return target->type->read_memory(target, address, size, count, buffer); } +int target_read_phys_memory(struct target_s *target, + uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) +{ + return target->type->read_phys_memory(target, address, size, count, buffer); +} + int target_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { return target->type->write_memory(target, address, size, count, buffer); } + +int target_write_phys_memory(struct target_s *target, + uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) +{ + return target->type->write_phys_memory(target, address, size, count, buffer); +} + int target_bulk_write_memory(struct target_s *target, uint32_t address, uint32_t count, uint8_t *buffer) { @@ -641,6 +694,114 @@ void target_reset_examined(struct target_s *target) } + +static int default_mrc(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value) +{ + LOG_ERROR("Not implemented"); + return ERROR_FAIL; +} + +static int default_mcr(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value) +{ + LOG_ERROR("Not implemented"); + return ERROR_FAIL; +} + +static int arm_cp_check(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm) +{ + /* basic check */ + if (!target_was_examined(target)) + { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + + if ((cpnum <0) || (cpnum > 15)) + { + LOG_ERROR("Illegal co-processor %d", cpnum); + return ERROR_FAIL; + } + + if (op1 > 7) + { + LOG_ERROR("Illegal op1"); + return ERROR_FAIL; + } + + if (op2 > 7) + { + LOG_ERROR("Illegal op2"); + return ERROR_FAIL; + } + + if (CRn > 15) + { + LOG_ERROR("Illegal CRn"); + return ERROR_FAIL; + } + + if (CRm > 15) + { + LOG_ERROR("Illegal CRm"); + return ERROR_FAIL; + } + + return ERROR_OK; +} + +int target_mrc(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value) +{ + int retval; + + retval = arm_cp_check(target, cpnum, op1, op2, CRn, CRm); + if (retval != ERROR_OK) + return retval; + + return target->type->mrc(target, cpnum, op1, op2, CRn, CRm, value); +} + +int target_mcr(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value) +{ + int retval; + + retval = arm_cp_check(target, cpnum, op1, op2, CRn, CRm); + if (retval != ERROR_OK) + return retval; + + return target->type->mcr(target, cpnum, op1, op2, CRn, CRm, value); +} + +static int default_read_phys_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) +{ + int retval; + bool mmu; + retval = target->type->has_mmu(target, &mmu); + if (retval != ERROR_OK) + return retval; + if (mmu) + { + LOG_ERROR("Not implemented"); + return ERROR_FAIL; + } + return target_read_memory(target, address, size, count, buffer); +} + +static int default_write_phys_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) +{ + int retval; + bool mmu; + retval = target->type->has_mmu(target, &mmu); + if (retval != ERROR_OK) + return retval; + if (mmu) + { + LOG_ERROR("Not implemented"); + return ERROR_FAIL; + } + return target_write_memory(target, address, size, count, buffer); +} + + int target_init(struct command_context_s *cmd_ctx) { target_t *target = all_targets; @@ -665,7 +826,39 @@ int target_init(struct command_context_s *cmd_ctx) { target->type->virt2phys = default_virt2phys; } - target->type->virt2phys = default_virt2phys; + + if (target->type->read_phys_memory == NULL) + { + target->type->read_phys_memory = default_read_phys_memory; + } + + if (target->type->write_phys_memory == NULL) + { + target->type->write_phys_memory = default_write_phys_memory; + } + + if (target->type->mcr == NULL) + { + target->type->mcr = default_mcr; + } else + { + /* FIX! multiple targets will generally register global commands + * multiple times. Only register this one if *one* of the + * targets need the command. Hmm... make it a command on the + * Jim Tcl target object? + */ + register_jim(cmd_ctx, "mcr", jim_mcrmrc, "write coprocessor "); + } + + if (target->type->mrc == NULL) + { + target->type->mrc = default_mrc; + } else + { + register_jim(cmd_ctx, "mrc", jim_mcrmrc, "read coprocessor "); + } + + /* a non-invasive way(in terms of patches) to add some code that * runs before the type->write/read_memory implementation */ @@ -682,6 +875,10 @@ int target_init(struct command_context_s *cmd_ctx) { target->type->mmu = default_mmu; } + if (target->type->has_mmu == NULL) + { + target->type->has_mmu = default_has_mmu; + } target = target->next; } @@ -923,13 +1120,29 @@ int target_alloc_working_area(struct target_s *target, uint32_t size, working_ar { return retval; } + if (enabled) { - target->working_area = target->working_area_virt; - } - else + if (target->working_area_phys_spec) + { + LOG_DEBUG("MMU disabled, using physical address for working memory 0x%08x", (unsigned)target->working_area_phys); + target->working_area = target->working_area_phys; + } else + { + LOG_ERROR("No working memory available. Specify -work-area-phys to target."); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + } else { - target->working_area = target->working_area_phys; + if (target->working_area_virt_spec) + { + LOG_DEBUG("MMU enabled, using virtual address for working memory 0x%08x", (unsigned)target->working_area_virt); + target->working_area = target->working_area_virt; + } else + { + LOG_ERROR("No working memory available. Specify -work-area-virt to target."); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } } } @@ -958,8 +1171,6 @@ int target_alloc_working_area(struct target_s *target, uint32_t size, working_ar uint32_t first_free = target->working_area; uint32_t free_size = target->working_area_size; - LOG_DEBUG("allocating new working area"); - c = target->working_areas; while (c) { @@ -976,6 +1187,8 @@ int target_alloc_working_area(struct target_s *target, uint32_t size, working_ar return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } + LOG_DEBUG("allocated new working area at address 0x%08x", (unsigned)first_free); + new_wa = malloc(sizeof(working_area_t)); new_wa->next = NULL; new_wa->size = size; @@ -1499,13 +1712,13 @@ int target_register_user_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run | halt | init] - default is run"); register_command(cmd_ctx, NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset"); - register_command(cmd_ctx, NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words [count]"); - register_command(cmd_ctx, NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words [count]"); - register_command(cmd_ctx, NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes [count]"); + register_command(cmd_ctx, NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words [phys] [count]"); + register_command(cmd_ctx, NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words [phys] [count]"); + register_command(cmd_ctx, NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes [phys] [count]"); - register_command(cmd_ctx, NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word [count]"); - register_command(cmd_ctx, NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word [count]"); - register_command(cmd_ctx, NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte [count]"); + register_command(cmd_ctx, NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word [phys] [count]"); + register_command(cmd_ctx, NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word [phys] [count]"); + register_command(cmd_ctx, NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte [phys] [count]"); register_command(cmd_ctx, NULL, "bp", handle_bp_command, COMMAND_EXEC, @@ -1767,6 +1980,8 @@ static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char { int i; + command_print(cmd_ctx, "===== %s", cache->name); + for (i = 0, reg = cache->reg_list; i < cache->num_regs; i++, reg++, count++) @@ -1799,9 +2014,7 @@ static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char if ((args[0][0] >= '0') && (args[0][0] <= '9')) { unsigned num; - int retval = parse_uint(args[0], &num); - if (ERROR_OK != retval) - return ERROR_COMMAND_SYNTAX_ERROR; + COMMAND_PARSE_NUMBER(uint, args[0], num); reg_cache_t *cache = target->reg_cache; count = 0; @@ -2055,9 +2268,7 @@ static int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, c uint32_t addr = 0; if (argc == 1) { - int retval = parse_u32(args[0], &addr); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[0], addr); current = 0; } @@ -2078,9 +2289,7 @@ static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, cha int current_pc = 1; if (argc == 1) { - int retval = parse_u32(args[0], &addr); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[0], addr); current_pc = 0; } @@ -2151,24 +2360,34 @@ static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char default: return ERROR_COMMAND_SYNTAX_ERROR; } + bool physical=strcmp(args[0], "phys")==0; + int (*fn)(struct target_s *target, + uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); + if (physical) + { + argc--; + args++; + fn=target_read_phys_memory; + } else + { + fn=target_read_memory; + } + if ((argc < 1) || (argc > 2)) + { + return ERROR_COMMAND_SYNTAX_ERROR; + } + uint32_t address; - int retval = parse_u32(args[0], &address); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[0], address); unsigned count = 1; if (argc == 2) - { - retval = parse_uint(args[1], &count); - if (ERROR_OK != retval) - return retval; - } + COMMAND_PARSE_NUMBER(uint, args[1], count); uint8_t *buffer = calloc(count, size); target_t *target = get_current_target(cmd_ctx); - retval = target_read_memory(target, - address, size, count, buffer); + int retval = fn(target, address, size, count, buffer); if (ERROR_OK == retval) handle_md_output(cmd_ctx, target, address, size, count, buffer); @@ -2179,26 +2398,34 @@ static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - if ((argc < 2) || (argc > 3)) + if (argc < 2) + { + return ERROR_COMMAND_SYNTAX_ERROR; + } + bool physical=strcmp(args[0], "phys")==0; + int (*fn)(struct target_s *target, + uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); + if (physical) + { + argc--; + args++; + fn=target_write_phys_memory; + } else + { + fn=target_write_memory; + } + if ((argc < 2) || (argc > 3)) return ERROR_COMMAND_SYNTAX_ERROR; uint32_t address; - int retval = parse_u32(args[0], &address); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[0], address); uint32_t value; - retval = parse_u32(args[1], &value); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[1], value); unsigned count = 1; if (argc == 3) - { - retval = parse_uint(args[2], &count); - if (ERROR_OK != retval) - return retval; - } + COMMAND_PARSE_NUMBER(uint, args[2], count); target_t *target = get_current_target(cmd_ctx); unsigned wordsize; @@ -2222,7 +2449,7 @@ static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char } for (unsigned i = 0; i < count; i++) { - retval = target_write_memory(target, + int retval = fn(target, address + i * wordsize, wordsize, 1, value_buf); if (ERROR_OK != retval) return retval; @@ -2233,8 +2460,9 @@ static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char } -static int parse_load_image_command_args(char **args, int argc, - image_t *image, uint32_t *min_address, uint32_t *max_address) +static int parse_load_image_command_args(struct command_context_s *cmd_ctx, + char **args, int argc, image_t *image, + uint32_t *min_address, uint32_t *max_address) { if (argc < 1 || argc > 5) return ERROR_COMMAND_SYNTAX_ERROR; @@ -2244,9 +2472,7 @@ static int parse_load_image_command_args(char **args, int argc, if (argc >= 2) { uint32_t addr; - int retval = parse_u32(args[1], &addr); - if (ERROR_OK != retval) - return ERROR_COMMAND_SYNTAX_ERROR; + COMMAND_PARSE_NUMBER(u32, args[1], addr); image->base_address = addr; image->base_address_set = 1; } @@ -2257,15 +2483,11 @@ static int parse_load_image_command_args(char **args, int argc, if (argc >= 4) { - int retval = parse_u32(args[3], min_address); - if (ERROR_OK != retval) - return ERROR_COMMAND_SYNTAX_ERROR; + COMMAND_PARSE_NUMBER(u32, args[3], *min_address); } if (argc == 5) { - int retval = parse_u32(args[4], max_address); - if (ERROR_OK != retval) - return ERROR_COMMAND_SYNTAX_ERROR; + COMMAND_PARSE_NUMBER(u32, args[4], *max_address); // use size (given) to find max (required) *max_address += *min_address; } @@ -2291,7 +2513,7 @@ static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cm duration_t duration; char *duration_text; - int retval = parse_load_image_command_args(args, argc, + int retval = parse_load_image_command_args(cmd_ctx, args, argc, &image, &min_address, &max_address); if (ERROR_OK != retval) return retval; @@ -2396,14 +2618,9 @@ static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cm } uint32_t address; - int retval = parse_u32(args[1], &address); - if (ERROR_OK != retval) - return retval; - + COMMAND_PARSE_NUMBER(u32, args[1], address); uint32_t size; - retval = parse_u32(args[2], &size); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[2], size); if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK) { @@ -2412,11 +2629,11 @@ static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cm duration_start_measure(&duration); + int retval = ERROR_OK; while (size > 0) { uint32_t size_written; uint32_t this_run_size = (size > 560) ? 560 : size; - retval = target_read_buffer(target, address, this_run_size, buffer); if (retval != ERROR_OK) { @@ -2482,9 +2699,7 @@ static int handle_verify_image_command_internal(struct command_context_s *cmd_ct if (argc >= 2) { uint32_t addr; - retval = parse_u32(args[1], &addr); - if (ERROR_OK != retval) - return ERROR_COMMAND_SYNTAX_ERROR; + COMMAND_PARSE_NUMBER(u32, args[1], addr); image.base_address = addr; image.base_address_set = 1; } @@ -2669,14 +2884,9 @@ static int handle_bp_command(struct command_context_s *cmd_ctx, } uint32_t addr; - int retval = parse_u32(args[0], &addr); - if (ERROR_OK != retval) - return retval; - + COMMAND_PARSE_NUMBER(u32, args[0], addr); uint32_t length; - retval = parse_u32(args[1], &length); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[1], length); int hw = BKPT_SOFT; if (argc == 3) @@ -2696,9 +2906,7 @@ static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char return ERROR_COMMAND_SYNTAX_ERROR; uint32_t addr; - int retval = parse_u32(args[0], &addr); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[0], addr); target_t *target = get_current_target(cmd_ctx); breakpoint_remove(target, addr); @@ -2733,19 +2941,14 @@ static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char uint32_t length = 0; uint32_t data_value = 0x0; uint32_t data_mask = 0xffffffff; - int retval; switch (argc) { case 5: - retval = parse_u32(args[4], &data_mask); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[4], data_mask); // fall through case 4: - retval = parse_u32(args[3], &data_value); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[3], data_value); // fall through case 3: switch (args[2][0]) @@ -2765,20 +2968,17 @@ static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char } // fall through case 2: - retval = parse_u32(args[1], &length); - if (ERROR_OK != retval) - return retval; - retval = parse_u32(args[0], &addr); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[1], length); + COMMAND_PARSE_NUMBER(u32, args[0], addr); break; default: - command_print(cmd_ctx, "usage: wp
[r/w/a] [value] [mask]"); + command_print(cmd_ctx, "usage: wp [address length " + "[(r|w|a) [value [mask]]]]"); return ERROR_COMMAND_SYNTAX_ERROR; } - retval = watchpoint_add(target, addr, length, type, + int retval = watchpoint_add(target, addr, length, type, data_value, data_mask); if (ERROR_OK != retval) LOG_ERROR("Failure setting watchpoints"); @@ -2792,9 +2992,7 @@ static int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char return ERROR_COMMAND_SYNTAX_ERROR; uint32_t addr; - int retval = parse_u32(args[0], &addr); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[0], addr); target_t *target = get_current_target(cmd_ctx); watchpoint_remove(target, addr); @@ -2816,13 +3014,11 @@ static int handle_virt2phys_command(command_context_t *cmd_ctx, return ERROR_COMMAND_SYNTAX_ERROR; uint32_t va; - int retval = parse_u32(args[0], &va); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(u32, args[0], va); uint32_t pa; target_t *target = get_current_target(cmd_ctx); - retval = target->type->virt2phys(target, va, &pa); + int retval = target->type->virt2phys(target, va, &pa); if (retval == ERROR_OK) command_print(cmd_ctx, "Physical address 0x%08" PRIx32 "", pa); @@ -2957,9 +3153,7 @@ static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_COMMAND_SYNTAX_ERROR; } unsigned offset; - int retval = parse_uint(args[0], &offset); - if (ERROR_OK != retval) - return retval; + COMMAND_PARSE_NUMBER(uint, args[0], offset); timeval_add_time(&timeout, offset, 0); @@ -2976,6 +3170,7 @@ static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, for (;;) { + int retval; target_poll(target); if (target->state == TARGET_HALTED) { @@ -3266,7 +3461,6 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return target_array2mem(interp,target, argc-1, argv + 1); } - static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv) { long l; @@ -3419,6 +3613,10 @@ void target_all_handle_event(enum target_event e) } } + +/* FIX? should we propagate errors here rather than printing them + * and continuing? + */ void target_handle_event(target_t *target, enum target_event e) { target_event_action_t *teap; @@ -3602,6 +3800,7 @@ static int target_configure(Jim_GetOptInfo *goi, target_t *target) return e; } target->working_area_virt = w; + target->working_area_virt_spec = true; } else { if (goi->argc != 0) { goto no_params; @@ -3619,6 +3818,7 @@ static int target_configure(Jim_GetOptInfo *goi, target_t *target) return e; } target->working_area_phys = w; + target->working_area_phys_spec = true; } else { if (goi->argc != 0) { goto no_params; @@ -4060,11 +4260,11 @@ static int tcl_target_func(Jim_Interp *interp, int argc, Jim_Obj *const *argv) /* do the assert */ if (n->value == NVP_ASSERT) { - target->type->assert_reset(target); + e = target->type->assert_reset(target); } else { - target->type->deassert_reset(target); + e = target->type->deassert_reset(target); } - return JIM_OK; + return (e == ERROR_OK) ? JIM_OK : JIM_ERR; case TS_CMD_HALT: if (goi.argc) { Jim_WrongNumArgs(goi.interp, 0, argv, "halt [no parameters]"); @@ -4072,8 +4272,8 @@ static int tcl_target_func(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } if (!target->tap->enabled) goto err_tap_disabled; - target->type->halt(target); - return JIM_OK; + e = target->type->halt(target); + return (e == ERROR_OK) ? JIM_OK : JIM_ERR; case TS_CMD_WAITSTATE: /* params: statename timeoutmsecs */ if (goi.argc != 2) { @@ -4236,6 +4436,8 @@ static int target_create(Jim_GetOptInfo *goi) target->display = 1; + target->halt_issued = false; + /* initialize trace information */ target->trace_info = malloc(sizeof(trace_t)); target->trace_info->num_trace_points = 0; @@ -4472,7 +4674,7 @@ static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, cha duration_t duration; char *duration_text; - int retval = parse_load_image_command_args(args, argc, + int retval = parse_load_image_command_args(cmd_ctx, args, argc, &image, &min_address, &max_address); if (ERROR_OK != retval) return retval; @@ -4598,10 +4800,88 @@ static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd return retval; } +static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + command_context_t *context; + target_t *target; + int retval; -/* - * Local Variables: - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ + context = Jim_GetAssocData(interp, "context"); + if (context == NULL) { + LOG_ERROR("array2mem: no command context"); + return JIM_ERR; + } + target = get_current_target(context); + if (target == NULL) { + LOG_ERROR("array2mem: no current target"); + return JIM_ERR; + } + + if ((argc < 6) || (argc > 7)) + { + return JIM_ERR; + } + + int cpnum; + uint32_t op1; + uint32_t op2; + uint32_t CRn; + uint32_t CRm; + uint32_t value; + + int e; + long l; + e = Jim_GetLong(interp, argv[1], &l); + if (e != JIM_OK) { + return e; + } + cpnum = l; + + e = Jim_GetLong(interp, argv[2], &l); + if (e != JIM_OK) { + return e; + } + op1 = l; + + e = Jim_GetLong(interp, argv[3], &l); + if (e != JIM_OK) { + return e; + } + CRn = l; + + e = Jim_GetLong(interp, argv[4], &l); + if (e != JIM_OK) { + return e; + } + CRm = l; + + e = Jim_GetLong(interp, argv[5], &l); + if (e != JIM_OK) { + return e; + } + op2 = l; + + value = 0; + + if (argc == 7) + { + e = Jim_GetLong(interp, argv[6], &l); + if (e != JIM_OK) { + return e; + } + value = l; + + retval = target_mcr(target, cpnum, op1, op2, CRn, CRm, value); + if (retval != ERROR_OK) + return JIM_ERR; + } else + { + retval = target_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; +}