diff options
Diffstat (limited to 'src/target')
-rw-r--r-- | src/target/arm7_9_common.c | 22 | ||||
-rw-r--r-- | src/target/arm_semihosting.c | 39 | ||||
-rw-r--r-- | src/target/arm_semihosting.h | 2 | ||||
-rw-r--r-- | src/target/armv4_5.c | 12 | ||||
-rw-r--r-- | src/target/armv4_5.h | 6 |
5 files changed, 48 insertions, 33 deletions
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; |