>From a9e610a28430bdc276bd14cb108c1d4ba20b2e05 Mon Sep 17 00:00:00 2001
From: Spencer Oliver <ntfr...@users.sourceforge.net>
Date: Tue, 2 Feb 2010 13:07:28 +0000
Subject: [PATCH 2/3] ARM semihosting: add ARMv7M semihosting support

Add ARMv7M support to current arm semihosting implementation.

armv7m_arch_state will now show semihosting status.

CortexM3 semihosting command added.

Signed-off-by: Spencer Oliver <ntfr...@users.sourceforge.net>
---
 src/target/arm_semihosting.c |   47 ++++++++++++++++++++++++++++++++++++++++++
 src/target/arm_semihosting.h |    1 +
 src/target/armv7m.c          |    8 +++---
 src/target/armv7m.h          |    1 +
 src/target/cortex_m3.c       |   44 ++++++++++++++++++++++++++++++++++++++-
 5 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c
index 438084e..9c4a3ce 100644
--- a/src/target/arm_semihosting.c
+++ b/src/target/arm_semihosting.c
@@ -39,6 +39,8 @@
 
 #include "arm.h"
 #include "armv4_5.h"
+#include "armv7m.h"
+#include "cortex_m3.h"
 #include "register.h"
 #include "arm_semihosting.h"
 #include <helper/binarybuffer.h>
@@ -494,5 +496,50 @@ int armv4_5_semihosting(struct target *target, int *retval)
        return 1;
 }
 
+int armv7m_semihosting(struct target *target, int *retval)
+{
+       struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
+       struct armv7m_common *armv7m = &cortex_m3->armv7m;
+       uint32_t pc;
+       struct reg *r;
+       uint16_t insn;
+       int result;
+
+       if (!armv7m->semi_hosting_info.is_semihosting)
+               return 0;
+
+       if (target->debug_reason != DBG_REASON_BREAKPOINT)
+               return 0;
+
+       r = &armv7m->core_cache->reg_list[ARMV7M_PC];
+       pc = buf_get_u32(r->value, 0, 32);
+
+       pc &= ~1;
+       *retval = target_read_u16(target, pc, &insn);
+       if (*retval != ERROR_OK)
+               return 1;
+
+       /* bkpt 0xAB */
+       if (insn != 0xBEAB)
+               return 0;
+
+       *retval = do_semihosting(target,
+                       buf_get_u32(armv7m->core_cache->reg_list[0].value, 0, 
32),
+                       buf_get_u32(armv7m->core_cache->reg_list[1].value, 0, 
32),
+                       &armv7m->semi_hosting_info,
+                       &result);
+
+       if (*retval != ERROR_OK)
+               return 1;
+
+       /* resume execution, this will be pc+2 to skip over the
+        * bkpt instruction */
+
+       /* return result in R0 */
+       buf_set_u32(armv7m->core_cache->reg_list[0].value, 0, 32, result);
+       armv7m->core_cache->reg_list[0].dirty = 1;
+
+       *retval = target_resume(target, 1, 0, 0, 0);
+
        return 1;
 }
diff --git a/src/target/arm_semihosting.h b/src/target/arm_semihosting.h
index c7c992b..bc308e5 100644
--- a/src/target/arm_semihosting.h
+++ b/src/target/arm_semihosting.h
@@ -31,5 +31,6 @@ struct arm_semi_hosting {
 };
 
 int armv4_5_semihosting(struct target *target, int *retval);
+int armv7m_semihosting(struct target *target, int *retval);
 
 #endif
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index edfcdf9..c6efe51 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -473,20 +473,20 @@ int armv7m_run_algorithm(struct target *target,
 int armv7m_arch_state(struct target *target)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       uint32_t ctrl, sp;
+       uint32_t ctrl;
 
        ctrl = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 
0, 32);
-       sp = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_R13].value, 0, 32);
 
        LOG_USER("target halted due to %s, current mode: %s %s\n"
-               "xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32,
+               "xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32 
"%s",
                debug_reason_name(target),
                armv7m_mode_strings[armv7m->core_mode],
                armv7m_exception_string(armv7m->exception_number),
                buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 
32),
                buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_PC].value, 0, 
32),
                (ctrl & 0x02) ? 'p' : 'm',
-               sp);
+               buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_R13].value, 0, 
32),
+               armv7m->semi_hosting_info.is_semihosting ? ", semihosting" : 
"");
 
        return ERROR_OK;
 }
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 9787e30..d470507 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -105,6 +105,7 @@ struct armv7m_common
        enum armv7m_mode core_mode;
        int exception_number;
        struct swjdp_common swjdp_info;
+       struct arm_semi_hosting semi_hosting_info;
 
        uint32_t demcr;
 
diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c
index 3f34769..b77f578 100644
--- a/src/target/cortex_m3.c
+++ b/src/target/cortex_m3.c
@@ -38,7 +38,7 @@
 #include "arm_disassembler.h"
 #include "register.h"
 #include "arm_opcodes.h"
-
+#include "arm_semihosting.h"
 
 /* NOTE:  most of this should work fine for the Cortex-M1 and
  * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
@@ -464,6 +464,9 @@ static int cortex_m3_poll(struct target *target)
                        if ((retval = cortex_m3_debug_entry(target)) != 
ERROR_OK)
                                return retval;
 
+                       if (armv7m_semihosting(target, &retval) != 0)
+                               return retval;
+
                        target_call_event_callbacks(target, 
TARGET_EVENT_HALTED);
                }
                if (prev_target_state == TARGET_DEBUG_RUNNING)
@@ -2025,6 +2028,38 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_cortex_m3_semihosting_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
+       int retval;
+
+       retval = cortex_m3_verify_pointer(CMD_CTX, cortex_m3);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (CMD_ARGC > 0)
+       {
+               int semihosting;
+
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting);
+
+               if (!target_was_examined(target))
+               {
+                       LOG_ERROR("Target not examined yet");
+                       return ERROR_FAIL;
+               }
+
+               cortex_m3->armv7m.semi_hosting_info.is_semihosting = 
semihosting;
+       }
+
+       command_print(CMD_CTX, "semihosting is %s",
+                       cortex_m3->armv7m.semi_hosting_info.is_semihosting
+                       ? "enabled" : "disabled");
+
+       return ERROR_OK;
+}
+
 static const struct command_registration cortex_m3_exec_command_handlers[] = {
        {
                .name = "disassemble",
@@ -2047,6 +2082,13 @@ static const struct command_registration 
cortex_m3_exec_command_handlers[] = {
                .help = "configure hardware vectors to trigger debug entry",
                .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]",
        },
+       {
+               .name = "semihosting",
+               .handler = handle_cortex_m3_semihosting_command,
+               .mode = COMMAND_EXEC,
+               .help = "activate support for semihosting operations",
+               .usage = "['enable'|'disable']",
+       },
        COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration cortex_m3_command_handlers[] = {
-- 
1.6.5.1.1367.gcd48

_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to