summaryrefslogtreecommitdiff
path: root/src/target/mips32.c
diff options
context:
space:
mode:
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2008-11-17 17:56:44 +0000
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2008-11-17 17:56:44 +0000
commit5711203e20fb11fa6d0f1acac714bca5833f17d8 (patch)
treeb612bfb7976110916b46420c7f72526e52650464 /src/target/mips32.c
parent76b3c6ece6f853daca937652df78b61df11c47f3 (diff)
downloadopenocd+libswd-5711203e20fb11fa6d0f1acac714bca5833f17d8.tar.gz
openocd+libswd-5711203e20fb11fa6d0f1acac714bca5833f17d8.tar.bz2
openocd+libswd-5711203e20fb11fa6d0f1acac714bca5833f17d8.tar.xz
openocd+libswd-5711203e20fb11fa6d0f1acac714bca5833f17d8.zip
- add support for hardware breakpoints to mips32 target
git-svn-id: svn://svn.berlios.de/openocd/trunk@1173 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/target/mips32.c')
-rw-r--r--src/target/mips32.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/target/mips32.c b/src/target/mips32.c
index 47b069e6..4d3705be 100644
--- a/src/target/mips32.c
+++ b/src/target/mips32.c
@@ -325,6 +325,10 @@ int mips32_init_arch_info(target_t *target, mips32_common_t *mips32, int chain_p
target->arch_info = mips32;
mips32->common_magic = MIPS32_COMMON_MAGIC;
+ /* has breakpoint/watchpint unit been scanned */
+ mips32->bp_scanned = 0;
+ mips32->data_break_list = NULL;
+
mips32->ejtag_info.chain_pos = chain_pos;
mips32->read_core_reg = mips32_read_core_reg;
mips32->write_core_reg = mips32_write_core_reg;
@@ -342,3 +346,82 @@ int mips32_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
/*TODO*/
return ERROR_OK;
}
+
+int mips32_examine(struct target_s *target)
+{
+ mips32_common_t *mips32 = target->arch_info;
+
+ if (!target->type->examined)
+ {
+ target->type->examined = 1;
+
+ /* we will configure later */
+ mips32->bp_scanned = 0;
+ mips32->num_inst_bpoints = 0;
+ mips32->num_data_bpoints = 0;
+ mips32->num_inst_bpoints_avail = 0;
+ mips32->num_data_bpoints_avail = 0;
+ }
+
+ return ERROR_OK;
+}
+
+int mips32_configure_break_unit(struct target_s *target)
+{
+ /* get pointers to arch-specific information */
+ mips32_common_t *mips32 = target->arch_info;
+ int retval;
+ u32 dcr, bpinfo;
+ int i;
+
+ if (mips32->bp_scanned)
+ return ERROR_OK;
+
+ /* get info about breakpoint support */
+ if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK)
+ return retval;
+
+ if (dcr & (1 << 16))
+ {
+ /* get number of inst breakpoints */
+ if ((retval = target_read_u32(target, EJTAG_IBS, &bpinfo)) != ERROR_OK)
+ return retval;
+
+ mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
+ mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
+ mips32->inst_break_list = calloc(mips32->num_inst_bpoints, sizeof(mips32_comparator_t));
+ for (i = 0; i < mips32->num_inst_bpoints; i++)
+ {
+ mips32->inst_break_list[i].reg_address = EJTAG_IBA1 + (0x100 * i);
+ }
+
+ /* clear IBIS reg */
+ if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
+ return retval;
+ }
+
+ if (dcr & (1 << 17))
+ {
+ /* get number of data breakpoints */
+ if ((retval = target_read_u32(target, EJTAG_DBS, &bpinfo)) != ERROR_OK)
+ return retval;
+
+ mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
+ mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
+ mips32->data_break_list = calloc(mips32->num_data_bpoints, sizeof(mips32_comparator_t));
+ for (i = 0; i < mips32->num_data_bpoints; i++)
+ {
+ mips32->data_break_list[i].reg_address = EJTAG_DBA1 + (0x100 * i);
+ }
+
+ /* clear DBIS reg */
+ if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK)
+ return retval;
+ }
+
+ LOG_DEBUG("DCR 0x%x numinst %i numdata %i", dcr, mips32->num_inst_bpoints, mips32->num_data_bpoints);
+
+ mips32->bp_scanned = 1;
+
+ return ERROR_OK;
+}