X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farm_semihosting.c;h=d71fbaef02bd0544f6ad0cceec5021604507ec1d;hb=87589043faf8cdb954c602c988698c40fcf9c108;hp=4788686296f265f333f8145ef73d15aef5c5c398;hpb=bdde9460b923ab61fad678bf1e3f0da04e1d94ee;p=openocd.git diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index 4788686296..d71fbaef02 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -43,10 +43,10 @@ static int do_semihosting(struct target *target) { - struct arm *armv4_5 = target_to_armv4_5(target); + 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, ARMV4_5_MODE_SVC, 14).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; @@ -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 */ @@ -384,7 +387,7 @@ static int do_semihosting(struct target *target) armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1; armv4_5->core_mode = spsr & 0x1f; if (spsr & 0x20) - armv4_5->core_state = ARMV4_5_STATE_THUMB; + armv4_5->core_state = ARM_STATE_THUMB; return target_resume(target, 1, 0, 0, 0); } @@ -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_arm(target); uint32_t lr, spsr; + struct reg *r; - 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) + if (!arm->is_semihosting || arm->core_mode != ARM_MODE_SVC) 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); + /* 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; + + 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; }