From: David B. <dbr...@us...> - 2009-12-05 01:52:08
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 32f961daba1301ac22ed53c9bc0822effff168cf (commit) via bdde9460b923ab61fad678bf1e3f0da04e1d94ee (commit) from acd6d3399486110e69db8d5ec752e10067c29ad0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 32f961daba1301ac22ed53c9bc0822effff168cf Author: David Brownell <dbr...@us...> Date: Fri Dec 4 16:51:48 2009 -0800 ARM: semihosting entry cleanup Clean up arm_semihosting() entry a bit, comment some issues and just which SVC opcodes are getting intercepted. Microcontroller profile cores will need a new entry, since they use BKPT instead (and don't have either SVC mode or an SPSR register). Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index 4788686..7fe0a97 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -56,6 +56,9 @@ static int do_semihosting(struct target *target) * - no validation on target provided file descriptors * - no safety checks on opened/deleted/renamed file paths * Beware the target app you use this support with. + * + * TODO: explore mapping requests to GDB's "File-I/O Remote + * Protocol Extension" ... when GDB is active. */ switch (r0) { case 0x01: /* SYS_OPEN */ @@ -396,42 +399,70 @@ static int do_semihosting(struct target *target) * or an error was encountered, in which case the caller must return * immediately. * - * @param target Pointer to the ARM target to process + * @param target Pointer to the ARM target to process. This target must + * not represent an ARMv6-M or ARMv7-M processor. * @param retval Pointer to a location where the return code will be stored * @return non-zero value if a request was processed or an error encountered */ int arm_semihosting(struct target *target, int *retval) { - struct arm *armv4_5 = target_to_armv4_5(target); + struct arm *arm = target_to_armv4_5(target); uint32_t lr, spsr; + struct reg *r; + + if (!arm->is_semihosting || arm->core_mode != ARMV4_5_MODE_SVC) + return 0; - if (!armv4_5->is_semihosting || - armv4_5->core_mode != ARMV4_5_MODE_SVC || - buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != 0x08) + /* Check for PC == 8: Supervisor Call vector + * REVISIT: assumes low exception vectors, not hivecs... + * safer to test "was this entry from a vector catch". + */ + r = arm->core_cache->reg_list + 15; + if (buf_get_u32(r->value, 0, 32) != 0x08) return 0; - lr = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, ARMV4_5_MODE_SVC, 14).value, 0, 32); - spsr = buf_get_u32(armv4_5->spsr->value, 0, 32); + r = arm_reg_current(arm, 14); + lr = buf_get_u32(r->value, 0, 32); + + /* Core-specific code should make sure SPSR is retrieved + * when the above checks pass... + */ + if (!arm->spsr->valid) { + LOG_ERROR("SPSR not valid!"); + *retval = ERROR_FAIL; + return 1; + } + + spsr = buf_get_u32(arm->spsr->value, 0, 32); /* check instruction that triggered this trap */ if (spsr & (1 << 5)) { - /* was in Thumb mode */ + /* was in Thumb (or ThumbEE) mode */ uint8_t insn_buf[2]; uint16_t insn; + *retval = target_read_memory(target, lr-2, 2, 1, insn_buf); if (*retval != ERROR_OK) return 1; insn = target_buffer_get_u16(target, insn_buf); + + /* SVC 0xab */ if (insn != 0xDFAB) return 0; + } else if (spsr & (1 << 24)) { + /* was in Jazelle mode */ + return 0; } else { /* was in ARM mode */ uint8_t insn_buf[4]; uint32_t insn; + *retval = target_read_memory(target, lr-4, 4, 1, insn_buf); if (*retval != ERROR_OK) return 1; insn = target_buffer_get_u32(target, insn_buf); + + /* SVC 0x123456 */ if (insn != 0xEF123456) return 0; } commit bdde9460b923ab61fad678bf1e3f0da04e1d94ee Author: David Brownell <dbr...@us...> Date: Fri Dec 4 16:51:48 2009 -0800 ARM: remove semihosting globals Store a flag and errno in in "struct arm". Have "poll" output report when semihosting is active. Shrink some of the affected lines. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 7318b5f..b411672 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2831,22 +2831,32 @@ COMMAND_HANDLER(handle_arm7_9_semihosting_command) if (CMD_ARGC > 0) { - COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting_active); + int semihosting; + + COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting); /* TODO: support other methods if vector catch is unavailable */ if (arm7_9->has_vector_catch) { - struct reg *vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]; + struct reg *vector_catch = &arm7_9->eice_cache + ->reg_list[EICE_VEC_CATCH]; + if (!vector_catch->valid) embeddedice_read_reg(vector_catch); - buf_set_u32(vector_catch->value, 2, 1, semihosting_active); + buf_set_u32(vector_catch->value, 2, 1, semihosting); embeddedice_store_reg(vector_catch); - } else if (semihosting_active) { + + /* FIXME never let that "catch" be dropped! */ + + arm7_9->armv4_5_common.is_semihosting = semihosting; + + } else if (semihosting) { command_print(CMD_CTX, "vector catch unavailable"); - semihosting_active = 0; } } - command_print(CMD_CTX, "semihosting is %s", (semihosting_active) ? "enabled" : "disabled"); + command_print(CMD_CTX, "semihosting is %s", + arm7_9->armv4_5_common.is_semihosting + ? "enabled" : "disabled"); return ERROR_OK; } diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index 2aa684f..4788686 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -40,9 +40,6 @@ #include <helper/binarybuffer.h> #include <helper/log.h> -/* TODO: this needs to be per target */ -int semihosting_active; -int semihosting_errno; static int do_semihosting(struct target *target) { @@ -93,10 +90,10 @@ static int do_semihosting(struct target *target) result = dup(1); } else result = open((char *)fn, mode); - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; } else { result = -1; - semihosting_errno = EINVAL; + armv4_5->semihosting_errno = EINVAL; } } break; @@ -108,7 +105,7 @@ static int do_semihosting(struct target *target) else { int fd = target_buffer_get_u32(target, params+0); result = close(fd); - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; } break; @@ -147,7 +144,7 @@ static int do_semihosting(struct target *target) uint8_t *buf = malloc(l); if (!buf) { result = -1; - semihosting_errno = ENOMEM; + armv4_5->semihosting_errno = ENOMEM; } else { retval = target_read_buffer(target, a, l, buf); if (retval != ERROR_OK) { @@ -155,7 +152,7 @@ static int do_semihosting(struct target *target) return retval; } result = write(fd, buf, l); - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; if (result >= 0) result = l - result; free(buf); @@ -174,10 +171,10 @@ static int do_semihosting(struct target *target) uint8_t *buf = malloc(l); if (!buf) { result = -1; - semihosting_errno = ENOMEM; + armv4_5->semihosting_errno = ENOMEM; } else { result = read(fd, buf, l); - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; if (result > 0) { retval = target_write_buffer(target, a, result, buf); if (retval != ERROR_OK) { @@ -217,7 +214,7 @@ static int do_semihosting(struct target *target) int fd = target_buffer_get_u32(target, params+0); off_t pos = target_buffer_get_u32(target, params+4); result = lseek(fd, pos, SEEK_SET); - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; if (result == pos) result = 0; } @@ -231,14 +228,14 @@ static int do_semihosting(struct target *target) int fd = target_buffer_get_u32(target, params+0); off_t cur = lseek(fd, 0, SEEK_CUR); if (cur == (off_t)-1) { - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; result = -1; break; } result = lseek(fd, 0, SEEK_END); - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; if (lseek(fd, cur, SEEK_SET) == (off_t)-1) { - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; result = -1; } } @@ -258,10 +255,10 @@ static int do_semihosting(struct target *target) return retval; fn[l] = 0; result = remove((char *)fn); - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; } else { result = -1; - semihosting_errno = EINVAL; + armv4_5->semihosting_errno = EINVAL; } } break; @@ -286,10 +283,10 @@ static int do_semihosting(struct target *target) fn1[l1] = 0; fn2[l2] = 0; result = rename((char *)fn1, (char *)fn2); - semihosting_errno = errno; + armv4_5->semihosting_errno = errno; } else { result = -1; - semihosting_errno = EINVAL; + armv4_5->semihosting_errno = EINVAL; } } break; @@ -299,7 +296,7 @@ static int do_semihosting(struct target *target) break; case 0x13: /* SYS_ERRNO */ - result = semihosting_errno; + result = armv4_5->semihosting_errno; break; case 0x15: /* SYS_GET_CMDLINE */ @@ -375,7 +372,7 @@ static int do_semihosting(struct target *target) fprintf(stderr, "semihosting: unsupported call %#x\n", (unsigned) r0); result = -1; - semihosting_errno = ENOTSUP; + armv4_5->semihosting_errno = ENOTSUP; } /* resume execution to the original mode */ @@ -408,7 +405,7 @@ int arm_semihosting(struct target *target, int *retval) struct arm *armv4_5 = target_to_armv4_5(target); uint32_t lr, spsr; - if (!semihosting_active || + if (!armv4_5->is_semihosting || armv4_5->core_mode != ARMV4_5_MODE_SVC || buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != 0x08) return 0; diff --git a/src/target/arm_semihosting.h b/src/target/arm_semihosting.h index 6b9ac56..80cad39 100644 --- a/src/target/arm_semihosting.h +++ b/src/target/arm_semihosting.h @@ -21,8 +21,6 @@ #ifndef ARM_SEMIHOSTING_H #define ARM_SEMIHOSTING_H -extern int semihosting_active; - int arm_semihosting(struct target *target, int *retval); #endif diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 80c06ef..412b829 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -587,16 +587,20 @@ int armv4_5_arch_state(struct target *target) if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC) { - LOG_ERROR("BUG: called for a non-ARMv4/5 target"); + LOG_ERROR("BUG: called for a non-ARM target"); return ERROR_FAIL; } - LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "", + LOG_USER("target halted in %s state due to %s, current mode: %s\n" + "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s", armv4_5_state_strings[armv4_5->core_state], - Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name, + Jim_Nvp_value2name_simple(nvp_target_debug_reason, + target->debug_reason)->name, arm_mode_name(armv4_5->core_mode), buf_get_u32(armv4_5->cpsr->value, 0, 32), - buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); + buf_get_u32(armv4_5->core_cache->reg_list[15].value, + 0, 32), + armv4_5->is_semihosting ? ", semihosting" : ""); return ERROR_OK; } diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h index 6c83c3b..615e486 100644 --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -103,6 +103,12 @@ struct arm /** Flag reporting unavailability of the BKPT instruction. */ bool is_armv4; + /** Flag reporting whether semihosting is active. */ + bool is_semihosting; + + /** Value to be returned by semihosting SYS_ERRNO request. */ + int semihosting_errno; + /** Backpointer to the target. */ struct target *target; ----------------------------------------------------------------------- Summary of changes: src/target/arm7_9_common.c | 22 ++++++++--- src/target/arm_semihosting.c | 84 ++++++++++++++++++++++++++++-------------- src/target/arm_semihosting.h | 2 - src/target/armv4_5.c | 12 ++++-- src/target/armv4_5.h | 6 +++ 5 files changed, 86 insertions(+), 40 deletions(-) hooks/post-receive -- Main OpenOCD repository |