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);
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;
}
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)
{
}
+
+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;
{
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 <cpnum> <op1> <op2> <CRn> <CRm> <value>");
+ }
+
+ if (target->type->mrc == NULL)
+ {
+ target->type->mrc = default_mrc;
+ } else
+ {
+ register_jim(cmd_ctx, "mrc", jim_mcrmrc, "read coprocessor <cpnum> <op1> <op2> <CRn> <CRm>");
+ }
+
+
/* a non-invasive way(in terms of patches) to add some code that
* runs before the type->write/read_memory implementation
*/
{
target->type->mmu = default_mmu;
}
+ if (target->type->has_mmu == NULL)
+ {
+ target->type->has_mmu = default_has_mmu;
+ }
target = target->next;
}
{
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;
+ }
}
}
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)
{
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;
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 <addr> [count]");
- register_command(cmd_ctx, NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words <addr> [count]");
- register_command(cmd_ctx, NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes <addr> [count]");
+ register_command(cmd_ctx, NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words [phys] <addr> [count]");
+ register_command(cmd_ctx, NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words [phys] <addr> [count]");
+ register_command(cmd_ctx, NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes [phys] <addr> [count]");
- register_command(cmd_ctx, NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word <addr> <value> [count]");
- register_command(cmd_ctx, NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word <addr> <value> [count]");
- register_command(cmd_ctx, NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte <addr> <value> [count]");
+ register_command(cmd_ctx, NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word [phys] <addr> <value> [count]");
+ register_command(cmd_ctx, NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word [phys] <addr> <value> [count]");
+ register_command(cmd_ctx, NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte [phys] <addr> <value> [count]");
register_command(cmd_ctx, NULL, "bp",
handle_bp_command, COMMAND_EXEC,
{
int i;
+ command_print(cmd_ctx, "===== %s", cache->name);
+
for (i = 0, reg = cache->reg_list;
i < cache->num_regs;
i++, reg++, count++)
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;
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;
}
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;
}
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);
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;
}
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;
}
-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;
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;
}
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;
}
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;
}
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)
{
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)
{
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;
}
}
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)
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);
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])
}
// 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 <address> <length> [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");
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);
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);
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);
for (;;)
{
+ int retval;
target_poll(target);
if (target->state == TARGET_HALTED)
{
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;
return e;
}
target->working_area_virt = w;
+ target->working_area_virt_spec = true;
} else {
if (goi->argc != 0) {
goto no_params;
return e;
}
target->working_area_phys = w;
+ target->working_area_phys_spec = true;
} else {
if (goi->argc != 0) {
goto no_params;
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;
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;
+}