semihosting patch has been split up a little bit. updated to latest git master.
Cheers Spen
>From e94f8ef0802d7abf2798d9967dc14caf00bda4c5 Mon Sep 17 00:00:00 2001 From: Spencer Oliver <[email protected]> Date: Tue, 2 Feb 2010 13:01:50 +0000 Subject: [PATCH 1/3] ARM semihosting: split do_semihosting Remove any target specific code from do_semihosting. Add arm_semi_hosting structure to hold semihosting variables. Rename arm_semihosting to armv4_5_semihosting, ready for armv7m semihosting support. Signed-off-by: Spencer Oliver <[email protected]> --- src/helper/system.h | 1 - src/target/arm.h | 9 +-- src/target/arm7_9_common.c | 8 +- src/target/arm_semihosting.c | 169 ++++++++++++++++++++++------------------- src/target/arm_semihosting.h | 11 +++- src/target/armv4_5.c | 2 +- src/target/target.h | 1 - 7 files changed, 109 insertions(+), 92 deletions(-) diff --git a/src/helper/system.h b/src/helper/system.h index 8ff3532..f03c850 100644 --- a/src/helper/system.h +++ b/src/helper/system.h @@ -51,7 +51,6 @@ #include <winsock2.h> #include <ws2tcpip.h> #include <sys/types.h> -#include <sys/stat.h> #endif // --- platform specific headers --- diff --git a/src/target/arm.h b/src/target/arm.h index 988266e..54fd698 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -28,7 +28,7 @@ #include <helper/command.h> #include "target.h" - +#include "arm_semihosting.h" /** * @file @@ -108,11 +108,8 @@ 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; + /** info about semi hosting config. */ + struct arm_semi_hosting semi_hosting_info; /** Backpointer to the target. */ struct target *target; diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 509e91e..81ea81c 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -896,7 +896,7 @@ int arm7_9_poll(struct target *target) if ((retval = arm7_9_debug_entry(target)) != ERROR_OK) return retval; - if (arm_semihosting(target, &retval) != 0) + if (armv4_5_semihosting(target, &retval) != 0) return retval; if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK) @@ -2866,16 +2866,16 @@ COMMAND_HANDLER(handle_arm7_9_semihosting_command) if (semihosting) breakpoint_add(target, 8, 4, BKPT_SOFT); else - breakpoint_remove(target, 8); + breakpoint_remove(target, 8); } /* FIXME never let that "catch" be dropped! */ - arm7_9->armv4_5_common.is_semihosting = semihosting; + arm7_9->armv4_5_common.semi_hosting_info.is_semihosting = semihosting; } command_print(CMD_CTX, "semihosting is %s", - arm7_9->armv4_5_common.is_semihosting + arm7_9->armv4_5_common.semi_hosting_info.is_semihosting ? "enabled" : "disabled"); return ERROR_OK; diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index 9b853d9..438084e 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -60,15 +60,11 @@ static int open_modeflags[12] = { O_RDWR | O_CREAT | O_APPEND | O_BINARY }; -static int do_semihosting(struct target *target) +static int do_semihosting(struct target *target, uint32_t r0, uint32_t r1, + struct arm_semi_hosting *info, int *result) { - struct arm *armv4_5 = target_to_arm(target); - uint32_t r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32); - uint32_t r1 = buf_get_u32(armv4_5->core_cache->reg_list[1].value, 0, 32); - uint32_t lr = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, ARM_MODE_SVC, 14).value, 0, 32); - uint32_t spsr = buf_get_u32(armv4_5->spsr->value, 0, 32);; uint8_t params[16]; - int retval, result; + int retval; /* * TODO: lots of security issues are not considered yet, such as: @@ -96,19 +92,19 @@ static int do_semihosting(struct target *target) fn[l] = 0; if (strcmp((char *)fn, ":tt") == 0) { if (m < 4) - result = dup(STDIN_FILENO); + *result = dup(STDIN_FILENO); else - result = dup(STDOUT_FILENO); + *result = dup(STDOUT_FILENO); } else { /* cygwin requires the permission setting * otherwise it will fail to reopen a previously * written file */ - result = open((char *)fn, open_modeflags[m], 0644); + *result = open((char *)fn, open_modeflags[m], 0644); } - armv4_5->semihosting_errno = errno; + info->semihosting_errno = errno; } else { - result = -1; - armv4_5->semihosting_errno = EINVAL; + *result = -1; + info->semihosting_errno = EINVAL; } } break; @@ -119,8 +115,8 @@ static int do_semihosting(struct target *target) return retval; else { int fd = target_buffer_get_u32(target, params+0); - result = close(fd); - armv4_5->semihosting_errno = errno; + *result = close(fd); + info->semihosting_errno = errno; } break; @@ -131,7 +127,7 @@ static int do_semihosting(struct target *target) if (retval != ERROR_OK) return retval; putchar(c); - result = 0; + *result = 0; } break; @@ -145,7 +141,7 @@ static int do_semihosting(struct target *target) break; putchar(c); } while (1); - result = 0; + *result = 0; break; case 0x05: /* SYS_WRITE */ @@ -158,18 +154,18 @@ static int do_semihosting(struct target *target) size_t l = target_buffer_get_u32(target, params+8); uint8_t *buf = malloc(l); if (!buf) { - result = -1; - armv4_5->semihosting_errno = ENOMEM; + *result = -1; + info->semihosting_errno = ENOMEM; } else { retval = target_read_buffer(target, a, l, buf); if (retval != ERROR_OK) { free(buf); return retval; } - result = write(fd, buf, l); - armv4_5->semihosting_errno = errno; - if (result >= 0) - result = l - result; + *result = write(fd, buf, l); + info->semihosting_errno = errno; + if (*result >= 0) + *result = l - *result; free(buf); } } @@ -185,18 +181,18 @@ static int do_semihosting(struct target *target) ssize_t l = target_buffer_get_u32(target, params+8); uint8_t *buf = malloc(l); if (!buf) { - result = -1; - armv4_5->semihosting_errno = ENOMEM; + *result = -1; + info->semihosting_errno = ENOMEM; } else { - result = read(fd, buf, l); - armv4_5->semihosting_errno = errno; - if (result >= 0) { - retval = target_write_buffer(target, a, result, buf); + *result = read(fd, buf, l); + info->semihosting_errno = errno; + if (*result >= 0) { + retval = target_write_buffer(target, a, *result, buf); if (retval != ERROR_OK) { free(buf); return retval; } - result = l - result; + *result = l - *result; } free(buf); } @@ -204,21 +200,21 @@ static int do_semihosting(struct target *target) break; case 0x07: /* SYS_READC */ - result = getchar(); + *result = getchar(); break; case 0x08: /* SYS_ISERROR */ retval = target_read_memory(target, r1, 4, 1, params); if (retval != ERROR_OK) return retval; - result = (target_buffer_get_u32(target, params+0) != 0); + *result = (target_buffer_get_u32(target, params+0) != 0); break; case 0x09: /* SYS_ISTTY */ retval = target_read_memory(target, r1, 4, 1, params); if (retval != ERROR_OK) return retval; - result = isatty(target_buffer_get_u32(target, params+0)); + *result = isatty(target_buffer_get_u32(target, params+0)); break; case 0x0a: /* SYS_SEEK */ @@ -228,10 +224,10 @@ static int do_semihosting(struct target *target) else { 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); - armv4_5->semihosting_errno = errno; - if (result == pos) - result = 0; + *result = lseek(fd, pos, SEEK_SET); + info->semihosting_errno = errno; + if (*result == pos) + *result = 0; } break; @@ -242,13 +238,13 @@ static int do_semihosting(struct target *target) else { int fd = target_buffer_get_u32(target, params+0); struct stat buf; - result = fstat(fd, &buf); - if (result == -1) { - armv4_5->semihosting_errno = errno; - result = -1; + *result = fstat(fd, &buf); + if (*result == -1) { + info->semihosting_errno = errno; + *result = -1; break; } - result = buf.st_size; + *result = buf.st_size; } break; @@ -265,11 +261,11 @@ static int do_semihosting(struct target *target) if (retval != ERROR_OK) return retval; fn[l] = 0; - result = remove((char *)fn); - armv4_5->semihosting_errno = errno; + *result = remove((char *)fn); + info->semihosting_errno = errno; } else { - result = -1; - armv4_5->semihosting_errno = EINVAL; + *result = -1; + info->semihosting_errno = EINVAL; } } break; @@ -293,21 +289,21 @@ static int do_semihosting(struct target *target) return retval; fn1[l1] = 0; fn2[l2] = 0; - result = rename((char *)fn1, (char *)fn2); - armv4_5->semihosting_errno = errno; + *result = rename((char *)fn1, (char *)fn2); + info->semihosting_errno = errno; } else { - result = -1; - armv4_5->semihosting_errno = EINVAL; + *result = -1; + info->semihosting_errno = EINVAL; } } break; case 0x11: /* SYS_TIME */ - result = time(NULL); + *result = time(NULL); break; case 0x13: /* SYS_ERRNO */ - result = armv4_5->semihosting_errno; + *result = info->semihosting_errno; break; case 0x15: /* SYS_GET_CMDLINE */ @@ -320,12 +316,12 @@ static int do_semihosting(struct target *target) char *arg = "foobar"; uint32_t s = strlen(arg) + 1; if (l < s) - result = -1; + *result = -1; else { retval = target_write_buffer(target, a, s, (void*)arg); if (retval != ERROR_OK) return retval; - result = 0; + *result = 0; } } break; @@ -341,7 +337,7 @@ static int do_semihosting(struct target *target) retval = target_write_memory(target, a, 4, 4, params); if (retval != ERROR_OK) return retval; - result = 0; + *result = 0; } break; @@ -382,28 +378,11 @@ static int do_semihosting(struct target *target) default: fprintf(stderr, "semihosting: unsupported call %#x\n", (unsigned) r0); - result = -1; - armv4_5->semihosting_errno = ENOTSUP; + *result = -1; + info->semihosting_errno = ENOTSUP; } - /* resume execution to the original mode */ - - /* return value in R0 */ - buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, result); - armv4_5->core_cache->reg_list[0].dirty = 1; - - /* LR --> PC */ - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, lr); - armv4_5->core_cache->reg_list[15].dirty = 1; - - /* saved PSR --> current PSR */ - buf_set_u32(armv4_5->cpsr->value, 0, 32, spsr); - armv4_5->cpsr->dirty = 1; - armv4_5->core_mode = spsr & 0x1f; - if (spsr & 0x20) - armv4_5->core_state = ARM_STATE_THUMB; - - return target_resume(target, 1, 0, 0, 0); + return ERROR_OK; } /** @@ -419,13 +398,14 @@ static int do_semihosting(struct target *target) * @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) +int armv4_5_semihosting(struct target *target, int *retval) { struct arm *arm = target_to_arm(target); uint32_t pc, lr, spsr; struct reg *r; + int result; - if (!arm->is_semihosting || arm->core_mode != ARM_MODE_SVC) + if (!arm->semi_hosting_info.is_semihosting || arm->core_mode != ARM_MODE_SVC) return 0; /* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */ @@ -480,6 +460,39 @@ int arm_semihosting(struct target *target, int *retval) return 0; } - *retval = do_semihosting(target); + lr = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, ARM_MODE_SVC, 14).value, 0, 32); + spsr = buf_get_u32(arm->spsr->value, 0, 32); + + *retval = do_semihosting(target, + buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32), + buf_get_u32(arm->core_cache->reg_list[1].value, 0, 32), + &arm->semi_hosting_info, + &result); + + if (*retval != ERROR_OK) + return 1; + + /* resume execution to the original mode */ + + /* return value in R0 */ + buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, result); + arm->core_cache->reg_list[0].dirty = 1; + + /* LR --> PC */ + buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32, lr); + arm->core_cache->reg_list[15].dirty = 1; + + /* saved PSR --> current PSR */ + buf_set_u32(arm->cpsr->value, 0, 32, spsr); + arm->cpsr->dirty = 1; + arm->core_mode = spsr & 0x1f; + if (spsr & 0x20) + arm->core_state = ARM_STATE_THUMB; + + *retval = target_resume(target, 1, 0, 0, 0); + + return 1; +} + return 1; } diff --git a/src/target/arm_semihosting.h b/src/target/arm_semihosting.h index 80cad39..c7c992b 100644 --- a/src/target/arm_semihosting.h +++ b/src/target/arm_semihosting.h @@ -21,6 +21,15 @@ #ifndef ARM_SEMIHOSTING_H #define ARM_SEMIHOSTING_H -int arm_semihosting(struct target *target, int *retval); +struct arm_semi_hosting { + + /** Flag reporting whether semihosting is active. */ + bool is_semihosting; + + /** Value to be returned by semihosting SYS_ERRNO request. */ + int semihosting_errno; +}; + +int armv4_5_semihosting(struct target *target, int *retval); #endif diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index c7b7367..1dcfe88 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -600,7 +600,7 @@ int arm_arch_state(struct target *target) buf_get_u32(armv4_5->cpsr->value, 0, 32), buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32), - armv4_5->is_semihosting ? ", semihosting" : ""); + armv4_5->semi_hosting_info.is_semihosting ? ", semihosting" : ""); return ERROR_OK; } diff --git a/src/target/target.h b/src/target/target.h index da91d46..0131575 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -36,7 +36,6 @@ struct watchpoint; struct mem_param; struct reg_param; - /* * TARGET_UNKNOWN = 0: we don't know anything about the target yet * TARGET_RUNNING = 1: the target is executing user code -- 1.6.5.1.1367.gcd48
_______________________________________________ Openocd-development mailing list [email protected] https://lists.berlios.de/mailman/listinfo/openocd-development
