]> git.sur5r.net Git - openocd/blobdiff - src/target/arm_semihosting.c
ZY1000 help/usage fixups
[openocd] / src / target / arm_semihosting.c
index dd6a669597ca827587198de181fa6f17098d42ea..f4244c84d11c15985590e2abda59317f1db34fb3 100644 (file)
@@ -34,6 +34,7 @@
 #include "config.h"
 #endif
 
+#include "arm.h"
 #include "armv4_5.h"
 #include "register.h"
 #include "arm_semihosting.h"
@@ -43,7 +44,7 @@
 
 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, ARM_MODE_SVC, 14).value, 0, 32);
@@ -379,15 +380,22 @@ static int do_semihosting(struct target *target)
        }
 
        /* 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;
-       buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, spsr);
-       armv4_5->core_cache->reg_list[ARMV4_5_CPSR].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);
 }
 
@@ -406,19 +414,17 @@ static int do_semihosting(struct target *target)
  */
 int arm_semihosting(struct target *target, int *retval)
 {
-       struct arm *arm = target_to_armv4_5(target);
-       uint32_t lr, spsr;
+       struct arm *arm = target_to_arm(target);
+       uint32_t pc, lr, spsr;
        struct reg *r;
 
        if (!arm->is_semihosting || arm->core_mode != ARM_MODE_SVC)
                return 0;
 
-       /* Check for PC == 8:  Supervisor Call vector
-        * REVISIT:  assumes low exception vectors, not hivecs...
-        * safer to test "was this entry from a vector catch".
-        */
+       /* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */
        r = arm->core_cache->reg_list + 15;
-       if (buf_get_u32(r->value, 0, 32) != 0x08)
+       pc = buf_get_u32(r->value, 0, 32);
+       if (pc != 0x00000008 && pc != 0xffff0008)
                return 0;
 
        r = arm_reg_current(arm, 14);