Michael Bruck:

- Added simulate_reset_on_next_halt that can be extended to do all sorts
of cleanups for systems without proper reset. Right now it just writes 0
to the control register to disable caches.
- Step skips over Wait for Interrupt instruction
- fix for count
- fix for printf format errors


git-svn-id: svn://svn.berlios.de/openocd/trunk@439 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
oharboe 2008-03-04 06:46:44 +00:00
parent 5c2b85dfec
commit 58cccae639
3 changed files with 77 additions and 51 deletions

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -47,8 +48,8 @@
static void arm11_on_enter_debug_state(arm11_common_t * arm11); static void arm11_on_enter_debug_state(arm11_common_t * arm11);
int arm11_config_memwrite_burst = 1; bool arm11_config_memwrite_burst = true;
int arm11_config_memwrite_error_fatal = 1; bool arm11_config_memwrite_error_fatal = true;
u32 arm11_vcr = 0; u32 arm11_vcr = 0;
@ -404,16 +405,6 @@ static void arm11_on_enter_debug_state(arm11_common_t * arm11)
arm11_write_DSCR(arm11, new_dscr); arm11_write_DSCR(arm11, new_dscr);
/* jtag_execute_queue(); */
/*
DEBUG("SAVE DSCR %08x", R(DSCR));
if (R(DSCR) & ARM11_DSCR_WDTR_FULL)
DEBUG("SAVE wDTR %08x", R(WDTR));
*/
/* From the spec: /* From the spec:
Before executing any instruction in debug state you have to drain the write buffer. Before executing any instruction in debug state you have to drain the write buffer.
@ -425,7 +416,7 @@ static void arm11_on_enter_debug_state(arm11_common_t * arm11)
while (1) while (1)
{ {
/* MRC p14,0,R0,c5,c10,0 */ /* MRC p14,0,R0,c5,c10,0 */
/* arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000); */ // arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000);
/* mcr 15, 0, r0, cr7, cr10, {4} */ /* mcr 15, 0, r0, cr7, cr10, {4} */
arm11_run_instr_no_data1(arm11, 0xee070f9a); arm11_run_instr_no_data1(arm11, 0xee070f9a);
@ -502,7 +493,20 @@ static void arm11_on_enter_debug_state(arm11_common_t * arm11)
arm11->reg_values[ARM11_RC_PC] -= 8; arm11->reg_values[ARM11_RC_PC] -= 8;
} }
/* DEBUG("SAVE PC %08x", R(PC)); */ if (arm11->simulate_reset_on_next_halt)
{
arm11->simulate_reset_on_next_halt = false;
DEBUG("Reset c1 Control Register");
/* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */
/* MCR p15,0,R0,c1,c0,0 */
arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);
}
arm11_run_instr_data_finish(arm11); arm11_run_instr_data_finish(arm11);
@ -558,7 +562,7 @@ void arm11_leave_debug_state(arm11_common_t * arm11)
/* MRC p14,0,r?,c0,c5,0 */ /* MRC p14,0,r?,c0,c5,0 */
arm11_run_instr_data_to_core1(arm11, 0xee100e15 | (i << 12), R(RX + i)); arm11_run_instr_data_to_core1(arm11, 0xee100e15 | (i << 12), R(RX + i));
/* DEBUG("RESTORE R%d %08x", i, R(RX + i)); */ // DEBUG("RESTORE R%d %08x", i, R(RX + i));
}} }}
arm11_run_instr_data_finish(arm11); arm11_run_instr_data_finish(arm11);
@ -719,6 +723,11 @@ int arm11_halt(struct target_s *target)
DEBUG("target->state: %s", target_state_strings[target->state]); DEBUG("target->state: %s", target_state_strings[target->state]);
if (target->state == TARGET_UNKNOWN)
{
arm11->simulate_reset_on_next_halt = true;
}
if (target->state == TARGET_HALTED) if (target->state == TARGET_HALTED)
{ {
WARNING("target was already halted"); WARNING("target was already halted");
@ -727,7 +736,7 @@ int arm11_halt(struct target_s *target)
if (arm11->trst_active) if (arm11->trst_active)
{ {
arm11->halt_requested = 1; arm11->halt_requested = true;
return ERROR_OK; return ERROR_OK;
} }
@ -763,10 +772,8 @@ int arm11_resume(struct target_s *target, int current, u32 address, int handle_b
{ {
FNC_INFO; FNC_INFO;
/* // DEBUG("current %d address %08x handle_breakpoints %d debug_execution %d",
DEBUG("current %d address %08x handle_breakpoints %d debug_execution %d", // current, address, handle_breakpoints, debug_execution);
current, address, handle_breakpoints, debug_execution);
*/
arm11_common_t * arm11 = target->arch_info; arm11_common_t * arm11 = target->arch_info;
@ -820,7 +827,7 @@ int arm11_resume(struct target_s *target, int current, u32 address, int handle_b
arm11_sc7_run(arm11, brp, asizeof(brp)); arm11_sc7_run(arm11, brp, asizeof(brp));
DEBUG("Add BP %d at %08x", brp_num, bp->address); DEBUG("Add BP %zd at %08x", brp_num, bp->address);
brp_num++; brp_num++;
} }
@ -886,7 +893,7 @@ int arm11_step(struct target_s *target, int current, u32 address, int handle_bre
arm11_read_memory_word(arm11, R(PC), &next_instruction); arm11_read_memory_word(arm11, R(PC), &next_instruction);
/** skip over BKPT */ /* skip over BKPT */
if ((next_instruction & 0xFFF00070) == 0xe1200070) if ((next_instruction & 0xFFF00070) == 0xe1200070)
{ {
R(PC) += 4; R(PC) += 4;
@ -894,6 +901,15 @@ int arm11_step(struct target_s *target, int current, u32 address, int handle_bre
arm11->reg_list[ARM11_RC_PC].dirty = 0; arm11->reg_list[ARM11_RC_PC].dirty = 0;
INFO("Skipping BKPT"); INFO("Skipping BKPT");
} }
/* skip over Wait for interrupt / Standby */
/* mcr 15, 0, r?, cr7, cr0, {4} */
else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90)
{
R(PC) += 4;
arm11->reg_list[ARM11_RC_PC].valid = 1;
arm11->reg_list[ARM11_RC_PC].dirty = 0;
INFO("Skipping WFI");
}
/* ignore B to self */ /* ignore B to self */
else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe) else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
{ {
@ -951,7 +967,7 @@ int arm11_step(struct target_s *target, int current, u32 address, int handle_bre
arm11_on_enter_debug_state(arm11); arm11_on_enter_debug_state(arm11);
} }
/* target->state = TARGET_HALTED; */ // target->state = TARGET_HALTED;
target->debug_reason = DBG_REASON_SINGLESTEP; target->debug_reason = DBG_REASON_SINGLESTEP;
target_call_event_callbacks(target, TARGET_EVENT_HALTED); target_call_event_callbacks(target, TARGET_EVENT_HALTED);
@ -973,7 +989,7 @@ int arm11_assert_reset(struct target_s *target)
jtag_add_sleep(5000); jtag_add_sleep(5000);
arm11_common_t * arm11 = target->arch_info; arm11_common_t * arm11 = target->arch_info;
arm11->trst_active = 1; arm11->trst_active = true;
#endif #endif
return ERROR_OK; return ERROR_OK;
@ -1076,7 +1092,8 @@ int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count,
/** \todo TODO: check if dirty is the right choice to force a rewrite on arm11_resume() */ /** \todo TODO: check if dirty is the right choice to force a rewrite on arm11_resume() */
arm11->reg_list[ARM11_RC_R1].dirty = 1; arm11->reg_list[ARM11_RC_R1].dirty = 1;
while (count--) {size_t i;
for (i = 0; i < count; i++)
{ {
/* ldrb r1, [r0], #1 */ /* ldrb r1, [r0], #1 */
arm11_run_instr_no_data1(arm11, 0xe4d01001); arm11_run_instr_no_data1(arm11, 0xe4d01001);
@ -1086,7 +1103,8 @@ int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count,
arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1); arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
*buffer++ = res; *buffer++ = res;
} }}
break; break;
case 2: case 2:
@ -1095,7 +1113,8 @@ int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count,
u16 * buf16 = (u16*)buffer; u16 * buf16 = (u16*)buffer;
while (count--) {size_t i;
for (i = 0; i < count; i++)
{ {
/* ldrh r1, [r0], #2 */ /* ldrh r1, [r0], #2 */
arm11_run_instr_no_data1(arm11, 0xe0d010b2); arm11_run_instr_no_data1(arm11, 0xe0d010b2);
@ -1106,7 +1125,8 @@ int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count,
arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1); arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
*buf16++ = res; *buf16++ = res;
} }}
break; break;
} }
@ -1138,17 +1158,21 @@ int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count
switch (size) switch (size)
{ {
case 1: case 1:
{
arm11->reg_list[ARM11_RC_R1].dirty = 1; arm11->reg_list[ARM11_RC_R1].dirty = 1;
while (count--) {size_t i;
for (i = 0; i < count; i++)
{ {
/* MRC p14,0,r1,c0,c5,0 */ /* MRC p14,0,r1,c0,c5,0 */
arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++); arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
/* strb r1, [r0], #1 */ /* strb r1, [r0], #1 */
arm11_run_instr_no_data1(arm11, 0xe4c01001); arm11_run_instr_no_data1(arm11, 0xe4c01001);
} }}
break; break;
}
case 2: case 2:
{ {
@ -1156,14 +1180,16 @@ int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count
u16 * buf16 = (u16*)buffer; u16 * buf16 = (u16*)buffer;
while (count--) {size_t i;
for (i = 0; i < count; i++)
{ {
/* MRC p14,0,r1,c0,c5,0 */ /* MRC p14,0,r1,c0,c5,0 */
arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buf16++); arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buf16++);
/* strh r1, [r0], #2 */ /* strh r1, [r0], #2 */
arm11_run_instr_no_data1(arm11, 0xe0c010b2); arm11_run_instr_no_data1(arm11, 0xe0c010b2);
} }}
break; break;
} }
@ -1450,7 +1476,7 @@ int arm11_set_reg(reg_t *reg, u8 *buf)
target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target; target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target;
arm11_common_t *arm11 = target->arch_info; arm11_common_t *arm11 = target->arch_info;
/* const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index; */ // const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index;
arm11->reg_values[((arm11_reg_state_t *)reg->arch_info)->def_index] = buf_get_u32(buf, 0, 32); arm11->reg_values[((arm11_reg_state_t *)reg->arch_info)->def_index] = buf_get_u32(buf, 0, 32);
reg->valid = 1; reg->valid = 1;
@ -1482,8 +1508,8 @@ void arm11_build_reg_cache(target_t *target)
reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache); reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
(*cache_p) = cache; (*cache_p) = cache;
/* armv7m->core_cache = cache; */ // armv7m->core_cache = cache;
/* armv7m->process_context = cache; */ // armv7m->process_context = cache;
size_t i; size_t i;
@ -1492,7 +1518,7 @@ void arm11_build_reg_cache(target_t *target)
ARM11_REGCACHE_COUNT != asizeof(arm11_reg_defs) || ARM11_REGCACHE_COUNT != asizeof(arm11_reg_defs) ||
ARM11_REGCACHE_COUNT != ARM11_RC_MAX) ARM11_REGCACHE_COUNT != ARM11_RC_MAX)
{ {
ERROR("arm11->reg_values inconsistent (%d %d %d %d)", ARM11_REGCACHE_COUNT, asizeof(arm11->reg_values), asizeof(arm11_reg_defs), ARM11_RC_MAX); ERROR("arm11->reg_values inconsistent (%d %zd %zd %d)", ARM11_REGCACHE_COUNT, asizeof(arm11->reg_values), asizeof(arm11_reg_defs), ARM11_RC_MAX);
exit(-1); exit(-1);
} }
@ -1519,7 +1545,7 @@ void arm11_build_reg_cache(target_t *target)
int arm11_handle_bool(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, int * var, char * name) int arm11_handle_bool(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, bool * var, char * name)
{ {
if (argc == 0) if (argc == 0)
{ {
@ -1537,7 +1563,7 @@ int arm11_handle_bool(struct command_context_s *cmd_ctx, char *cmd, char **args,
case 'F': case 'F':
case 'd': /* disable */ case 'd': /* disable */
case 'D': case 'D':
*var = 0; *var = false;
break; break;
case '1': /* 1 */ case '1': /* 1 */
@ -1545,7 +1571,7 @@ int arm11_handle_bool(struct command_context_s *cmd_ctx, char *cmd, char **args,
case 'T': case 'T':
case 'e': /* enable */ case 'e': /* enable */
case 'E': case 'E':
*var = 1; *var = true;
break; break;
} }

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM11_H #ifndef ARM11_H
#define ARM11_H #define ARM11_H
@ -23,12 +24,13 @@
#include "register.h" #include "register.h"
#include "embeddedice.h" #include "embeddedice.h"
#include "arm_jtag.h" #include "arm_jtag.h"
#include <stdbool.h>
#define asizeof(x) (sizeof(x) / sizeof((x)[0])) #define asizeof(x) (sizeof(x) / sizeof((x)[0]))
#define NEW(type, variable, items) \ #define NEW(type, variable, items) \
type * variable = malloc(sizeof(type) * items) type * variable = calloc(1, sizeof(type) * items)
#define ARM11_REGCACHE_MODEREGS 0 #define ARM11_REGCACHE_MODEREGS 0
@ -77,8 +79,9 @@ typedef struct arm11_common_s
u32 last_dscr; /**< Last retrieved DSCR value; u32 last_dscr; /**< Last retrieved DSCR value;
* Can be used to detect changes */ * Can be used to detect changes */
u8 trst_active; bool trst_active;
u8 halt_requested; bool halt_requested;
bool simulate_reset_on_next_halt;
/** \name Shadow registers to save processor state */ /** \name Shadow registers to save processor state */
/*@{*/ /*@{*/
@ -254,7 +257,7 @@ int arm11_add_ir_scan_vc(int num_fields, scan_field_t *fields, enum tap_state st
*/ */
typedef struct arm11_sc7_action_s typedef struct arm11_sc7_action_s
{ {
int write; /**< Access mode: true for write, false for read. */ bool write; /**< Access mode: true for write, false for read. */
u8 address; /**< Register address mode. Use enum #arm11_sc7 */ u8 address; /**< Register address mode. Use enum #arm11_sc7 */
u32 value; /**< If write then set this to value to be written. u32 value; /**< If write then set this to value to be written.
In read mode this receives the read value when the In read mode this receives the read value when the

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -28,13 +29,9 @@
#include <string.h> #include <string.h>
#if 0 #if 0
#define JTAG_DEBUG(expr ...) \ #define JTAG_DEBUG(expr ...) DEBUG(expr)
do { \
log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#else #else
#define JTAG_DEBUG(expr ...) \ #define JTAG_DEBUG(expr ...) do {} while(0)
do {} while(0)
#endif #endif
enum tap_state arm11_move_pi_to_si_via_ci[] = enum tap_state arm11_move_pi_to_si_via_ci[] =
@ -727,7 +724,7 @@ void arm11_sc7_clear_vbw(arm11_common_t * arm11)
{size_t i; {size_t i;
for (i = 0; i < asizeof(clear_bw); i++) for (i = 0; i < asizeof(clear_bw); i++)
{ {
clear_bw[i].write = 1; clear_bw[i].write = true;
clear_bw[i].value = 0; clear_bw[i].value = 0;
}} }}