X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farmv4_5.c;h=80c06ef31d355a7c4f5f523b928935a4066ea06c;hp=7e5bb0a1716123d703bea9235c2ec80ba358ee72;hb=d1bc4375e99ce52b72988494f35beca364234bae;hpb=66ee303456910f684244a20a0ac2e958d40b78cb diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 7e5bb0a171..80c06ef31d 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -31,7 +31,7 @@ #include "arm_jtag.h" #include "breakpoints.h" #include "arm_disassembler.h" -#include "binarybuffer.h" +#include #include "algorithm.h" #include "register.h" @@ -281,20 +281,20 @@ static const struct { { .name = "r11_fiq", .cookie = 11, .mode = ARMV4_5_MODE_FIQ, }, { .name = "r12_fiq", .cookie = 12, .mode = ARMV4_5_MODE_FIQ, }, - { .name = "lr_fiq", .cookie = 13, .mode = ARMV4_5_MODE_FIQ, }, - { .name = "sp_fiq", .cookie = 14, .mode = ARMV4_5_MODE_FIQ, }, + { .name = "sp_fiq", .cookie = 13, .mode = ARMV4_5_MODE_FIQ, }, + { .name = "lr_fiq", .cookie = 14, .mode = ARMV4_5_MODE_FIQ, }, - { .name = "lr_irq", .cookie = 13, .mode = ARMV4_5_MODE_IRQ, }, - { .name = "sp_irq", .cookie = 14, .mode = ARMV4_5_MODE_IRQ, }, + { .name = "sp_irq", .cookie = 13, .mode = ARMV4_5_MODE_IRQ, }, + { .name = "lr_irq", .cookie = 14, .mode = ARMV4_5_MODE_IRQ, }, - { .name = "lr_svc", .cookie = 13, .mode = ARMV4_5_MODE_SVC, }, - { .name = "sp_svc", .cookie = 14, .mode = ARMV4_5_MODE_SVC, }, + { .name = "sp_svc", .cookie = 13, .mode = ARMV4_5_MODE_SVC, }, + { .name = "lr_svc", .cookie = 14, .mode = ARMV4_5_MODE_SVC, }, - { .name = "lr_abt", .cookie = 13, .mode = ARMV4_5_MODE_ABT, }, - { .name = "sp_abt", .cookie = 14, .mode = ARMV4_5_MODE_ABT, }, + { .name = "sp_abt", .cookie = 13, .mode = ARMV4_5_MODE_ABT, }, + { .name = "lr_abt", .cookie = 14, .mode = ARMV4_5_MODE_ABT, }, - { .name = "lr_und", .cookie = 13, .mode = ARMV4_5_MODE_UND, }, - { .name = "sp_und", .cookie = 14, .mode = ARMV4_5_MODE_UND, }, + { .name = "sp_und", .cookie = 13, .mode = ARMV4_5_MODE_UND, }, + { .name = "lr_und", .cookie = 14, .mode = ARMV4_5_MODE_UND, }, { .name = "cpsr", .cookie = 16, .mode = ARMV4_5_MODE_ANY, }, { .name = "spsr_fiq", .cookie = 16, .mode = ARMV4_5_MODE_FIQ, }, @@ -303,8 +303,8 @@ static const struct { { .name = "spsr_abt", .cookie = 16, .mode = ARMV4_5_MODE_ABT, }, { .name = "spsr_und", .cookie = 16, .mode = ARMV4_5_MODE_UND, }, - { .name = "lr_mon", .cookie = 13, .mode = ARM_MODE_MON, }, - { .name = "sp_mon", .cookie = 14, .mode = ARM_MODE_MON, }, + { .name = "sp_mon", .cookie = 13, .mode = ARM_MODE_MON, }, + { .name = "lr_mon", .cookie = 14, .mode = ARM_MODE_MON, }, { .name = "spsr_mon", .cookie = 16, .mode = ARM_MODE_MON, }, }; @@ -390,6 +390,10 @@ void arm_set_cpsr(struct arm *arm, uint32_t cpsr) state = ARMV4_5_STATE_ARM; } arm->core_state = state; + + LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr, + arm_mode_name(mode), + armv4_5_state_strings[arm->core_state]); } /** @@ -786,6 +790,137 @@ usage: return retval; } +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 = Jim_GetAssocData(interp, "context"); + if (context == NULL) { + LOG_ERROR("%s: no command context", __func__); + return JIM_ERR; + } + 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 const struct command_registration arm_exec_command_handlers[] = { { .name = "reg", @@ -807,6 +942,20 @@ static const struct command_registration arm_exec_command_handlers[] = { .usage = "
[ ['thumb']]", .help = "disassemble instructions ", }, + { + .name = "mcr", + .mode = COMMAND_EXEC, + .jim_handler = &jim_mcrmrc, + .help = "write coprocessor register", + .usage = "cpnum op1 CRn op2 CRm value", + }, + { + .name = "mrc", + .jim_handler = &jim_mcrmrc, + .help = "read coprocessor register", + .usage = "cpnum op1 CRn op2 CRm", + }, + COMMAND_REGISTRATION_DONE }; const struct command_registration arm_command_handlers[] = { @@ -875,7 +1024,13 @@ static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit return ERROR_OK; } -int armv4_5_run_algorithm_inner(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info)) +int armv4_5_run_algorithm_inner(struct target *target, + int num_mem_params, struct mem_param *mem_params, + int num_reg_params, struct reg_param *reg_params, + uint32_t entry_point, uint32_t exit_point, + int timeout_ms, void *arch_info, + int (*run_it)(struct target *target, uint32_t exit_point, + int timeout_ms, void *arch_info)) { struct arm *armv4_5 = target_to_armv4_5(target); struct armv4_5_algorithm *armv4_5_algorithm_info = arch_info; @@ -885,6 +1040,7 @@ int armv4_5_run_algorithm_inner(struct target *target, int num_mem_params, struc int exit_breakpoint_size = 0; int i; int retval = ERROR_OK; + LOG_DEBUG("Running algorithm"); if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC) @@ -1241,6 +1397,24 @@ static int arm_full_context(struct target *target) return retval; } +static int arm_default_mrc(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, + uint32_t CRn, uint32_t CRm, + uint32_t *value) +{ + LOG_ERROR("%s doesn't implement MRC", target_type_name(target)); + return ERROR_FAIL; +} + +static int arm_default_mcr(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, + uint32_t CRn, uint32_t CRm, + uint32_t value) +{ + LOG_ERROR("%s doesn't implement MCR", target_type_name(target)); + return ERROR_FAIL; +} + int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5) { target->arch_info = armv4_5; @@ -1256,5 +1430,10 @@ int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5) if (!armv4_5->full_context && armv4_5->read_core_reg) armv4_5->full_context = arm_full_context; + if (!armv4_5->mrc) + armv4_5->mrc = arm_default_mrc; + if (!armv4_5->mcr) + armv4_5->mcr = arm_default_mcr; + return ERROR_OK; }