>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