diff --git a/src/target/xscale.c b/src/target/xscale.c index 37f9b641e..ec49a8c6b 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -3579,6 +3579,96 @@ int xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx return ERROR_OK; } +int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int argc) +{ + target_t *target = get_current_target(cmd_ctx); + armv4_5_common_t *armv4_5; + xscale_common_t *xscale; + + if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK) + { + command_print(cmd_ctx, "target isn't an XScale target"); + return ERROR_OK; + } + + if (target->state != TARGET_HALTED) + { + command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd); + return ERROR_OK; + } + u32 reg_no = 0; + reg_t *reg = NULL; + if(argc > 0) + { + reg_no = strtoul(args[0], NULL, 0); + /*translate from xscale cp15 register no to openocd register*/ + switch(reg_no) + { + case 0: + reg_no = XSCALE_MAINID; + break; + case 1: + reg_no = XSCALE_CTRL; + break; + case 2: + reg_no = XSCALE_TTB; + break; + case 3: + reg_no = XSCALE_DAC; + break; + case 5: + reg_no = XSCALE_FSR; + break; + case 6: + reg_no = XSCALE_FAR; + break; + case 13: + reg_no = XSCALE_PID; + break; + case 15: + reg_no = XSCALE_CPACCESS; + break; + default: + command_print(cmd_ctx, "invalid register number"); + return ERROR_INVALID_ARGUMENTS; + } + reg = &xscale->reg_cache->reg_list[reg_no]; + + } + if(argc == 1) + { + u32 value; + + /* read cp15 control register */ + xscale_get_reg(reg); + value = buf_get_u32(reg->value, 0, 32); + command_print(cmd_ctx, "%s (/%i): 0x%x", reg->name, reg->size, value); + } + else if(argc == 2) + { + + u32 value = strtoul(args[1], NULL, 0); + + /* send CP write request (command 0x41) */ + xscale_send_u32(target, 0x41); + + /* send CP register number */ + xscale_send_u32(target, reg_no); + + /* send CP register value */ + xscale_send_u32(target, value); + + /* execute cpwait to ensure outstanding operations complete */ + xscale_send_u32(target, 0x53); + } + else + { + command_print(cmd_ctx, "usage: cp15 [register]<, [value]>"); + } + + return ERROR_OK; +} + int xscale_register_commands(struct command_context_s *cmd_ctx) { command_t *xscale_cmd; @@ -3603,6 +3693,8 @@ int xscale_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command, COMMAND_EXEC, "load image from [base address]"); + register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 [value]"); + armv4_5_register_commands(cmd_ctx); return ERROR_OK;