Browse Source

Oleksandr Tymoshenko <gonzo@bluezbox.com> simple watchpoint support

for MIPS32/EJTAG (no value comparation yet).

git-svn-id: svn://svn.berlios.de/openocd/trunk@2402 b42882b7-edfa-0310-969c-e2dbd0fdcd60
tags/v0.2.0
oharboe 15 years ago
parent
commit
1e8225c738
2 changed files with 116 additions and 4 deletions
  1. +5
    -0
      src/target/mips_ejtag.h
  2. +111
    -4
      src/target/mips_m4k.c

+ 5
- 0
src/target/mips_ejtag.h View File

@@ -96,6 +96,11 @@
#define EJTAG_IBA1 0xFF301100
#define EJTAG_DBS 0xFF302000
#define EJTAG_DBA1 0xFF302100
#define EJTAG_DBCn_NOSB (1 << 13)
#define EJTAG_DBCn_NOLB (1 << 12)
#define EJTAG_DBCn_BLM_MASK 0xff
#define EJTAG_DBCn_BLM_SHIFT 4
#define EJTAG_DBCn_BE (1 << 0)

typedef struct mips_ejtag_s
{


+ 111
- 4
src/target/mips_m4k.c View File

@@ -693,25 +693,132 @@ int mips_m4k_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint

int mips_m4k_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
{
/* TODO */
mips32_common_t *mips32 = target->arch_info;
mips32_comparator_t * comparator_list = mips32->data_break_list;
int wp_num = 0;
/*
* watchpoint enabled, ignore all byte lanes in value register
* and exclude both load and store accesses from watchpoint
* condition evaluation
*/
int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
(0xff << EJTAG_DBCn_BLM_SHIFT);
if (watchpoint->set)
{
LOG_WARNING("watchpoint already set");
return ERROR_OK;
}

while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
wp_num++;
if (wp_num >= mips32->num_data_bpoints)
{
LOG_DEBUG("ERROR Can not find free FP Comparator");
LOG_WARNING("ERROR Can not find free FP Comparator");
exit(-1);
}

if (watchpoint->length != 4)
{
LOG_ERROR("Only watchpoints of length 4 are supported");
return ERROR_TARGET_UNALIGNED_ACCESS;
}

if (watchpoint->address % 4)
{
LOG_ERROR("Watchpoints address should be word aligned");
return ERROR_TARGET_UNALIGNED_ACCESS;
}

switch (watchpoint->rw)
{
case WPT_READ:
enable &= ~EJTAG_DBCn_NOLB;
break;
case WPT_WRITE:
enable &= ~EJTAG_DBCn_NOSB;
break;
case WPT_ACCESS:
enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
break;
default:
LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
}

watchpoint->set = wp_num + 1;
comparator_list[wp_num].used = 1;
comparator_list[wp_num].bp_value = watchpoint->address;
target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value);
target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000);
target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000);
target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable);
target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0);
LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value);
return ERROR_OK;
}

int mips_m4k_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
{
/* TODO */
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
mips32_comparator_t * comparator_list = mips32->data_break_list;
if (!watchpoint->set)
{
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}

int wp_num = watchpoint->set - 1;
if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints))
{
LOG_DEBUG("Invalid FP Comparator number in watchpoint");
return ERROR_OK;
}
comparator_list[wp_num].used = 0;
comparator_list[wp_num].bp_value = 0;
target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0);
watchpoint->set = 0;

return ERROR_OK;
}

int mips_m4k_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
{
/* TODO */
mips32_common_t *mips32 = target->arch_info;

if (mips32->num_data_bpoints_avail < 1)
{
LOG_INFO("no hardware watchpoints available");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
mips32->num_data_bpoints_avail--;

mips_m4k_set_watchpoint(target, watchpoint);
return ERROR_OK;
}

int mips_m4k_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
{
/* TODO */
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;

if (target->state != TARGET_HALTED)
{
LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED;
}

if (watchpoint->set)
{
mips_m4k_unset_watchpoint(target, watchpoint);
}

mips32->num_data_bpoints_avail++;

return ERROR_OK;
}



Loading…
Cancel
Save