From 30268bc40fb5f238b056a10b465cb9c13f466672 Mon Sep 17 00:00:00 2001 From: kc8apf Date: Wed, 20 May 2009 05:07:34 +0000 Subject: [PATCH] Author: Spencer Oliver - Bring the mips step/resume interrupt handling inline with the rest of openocd. git-svn-id: svn://svn.berlios.de/openocd/trunk@1850 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/target/mips32.c | 38 ++++++++++++++++++++++++++++++++++++++ src/target/mips32.h | 1 + src/target/mips_ejtag.c | 6 ++---- src/target/mips_ejtag.h | 2 +- src/target/mips_m4k.c | 17 +++++++++++++---- 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/target/mips32.c b/src/target/mips32.c index c109ed20ff..084e627681 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -420,3 +420,41 @@ int mips32_configure_break_unit(struct target_s *target) return ERROR_OK; } + +int mips32_enable_interrupts(struct target_s *target, int enable) +{ + int retval; + int update = 0; + u32 dcr; + + /* read debug control register */ + if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK) + return retval; + + if (enable) + { + if (!(dcr & (1<<4))) + { + /* enable interrupts */ + dcr |= (1<<4); + update = 1; + } + } + else + { + if (dcr & (1<<4)) + { + /* disable interrupts */ + dcr &= ~(1<<4); + update = 1; + } + } + + if (update) + { + if ((retval = target_write_u32(target, EJTAG_DCR, dcr)) != ERROR_OK) + return retval; + } + + return ERROR_OK; +} diff --git a/src/target/mips32.h b/src/target/mips32.h index 56c33faa9b..2eb8282322 100644 --- a/src/target/mips32.h +++ b/src/target/mips32.h @@ -131,6 +131,7 @@ extern int mips32_save_context(target_t *target); extern reg_cache_t *mips32_build_reg_cache(target_t *target); extern int mips32_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info); extern int mips32_configure_break_unit(struct target_s *target); +extern int mips32_enable_interrupts(struct target_s *target, int enable); extern int mips32_examine(struct target_s *target); extern int mips32_register_commands(struct command_context_s *cmd_ctx); diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index 09c3aaf062..02dc653b86 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -216,13 +216,11 @@ int mips_ejtag_enter_debug(mips_ejtag_t *ejtag_info) return ERROR_OK; } -int mips_ejtag_exit_debug(mips_ejtag_t *ejtag_info, int enable_interrupts) +int mips_ejtag_exit_debug(mips_ejtag_t *ejtag_info) { u32 inst; inst = MIPS32_DRET; - - /* TODO : enable/disable interrrupts */ - + /* execute our dret instruction */ mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0); diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h index e9d076820a..5ac994ac29 100644 --- a/src/target/mips_ejtag.h +++ b/src/target/mips_ejtag.h @@ -108,7 +108,7 @@ typedef struct mips_ejtag_s extern int mips_ejtag_set_instr(mips_ejtag_t *ejtag_info, int new_instr, void *delete_me_and_submit_patch); extern int mips_ejtag_enter_debug(mips_ejtag_t *ejtag_info); -extern int mips_ejtag_exit_debug(mips_ejtag_t *ejtag_info, int enable_interrupts); +extern int mips_ejtag_exit_debug(mips_ejtag_t *ejtag_info); extern int mips_ejtag_get_impcode(mips_ejtag_t *ejtag_info, u32 *impcode, in_handler_t handler); extern int mips_ejtag_get_idcode(mips_ejtag_t *ejtag_info, u32 *idcode, in_handler_t handler); extern int mips_ejtag_drscan_32(mips_ejtag_t *ejtag_info, u32 *data); diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index f29d8ec7bb..6d331d4e4b 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -344,8 +344,11 @@ int mips_m4k_single_step_core(target_t *target) /* configure single step mode */ mips_ejtag_config_step(ejtag_info, 1); + /* disable interrupts while stepping */ + mips32_enable_interrupts(target, 0); + /* exit debug mode */ - mips_ejtag_exit_debug(ejtag_info, 1); + mips_ejtag_exit_debug(ejtag_info); mips_m4k_debug_entry(target); @@ -397,8 +400,11 @@ int mips_m4k_resume(struct target_s *target, int current, u32 address, int handl } } - /* exit debug mode - enable interrupts if required */ - mips_ejtag_exit_debug(ejtag_info, !debug_execution); + /* enable interrupts if we are running */ + mips32_enable_interrupts(target, !debug_execution); + + /* exit debug mode */ + mips_ejtag_exit_debug(ejtag_info); target->debug_reason = DBG_REASON_NOTHALTED; /* registers are now invalid */ @@ -452,8 +458,11 @@ int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_ target_call_event_callbacks(target, TARGET_EVENT_RESUMED); + /* disable interrupts while stepping */ + mips32_enable_interrupts(target, 0); + /* exit debug mode */ - mips_ejtag_exit_debug(ejtag_info, 1); + mips_ejtag_exit_debug(ejtag_info); /* registers are now invalid */ mips32_invalidate_core_regs(target); -- 2.30.2