summaryrefslogtreecommitdiffstats
path: root/interf.c
diff options
context:
space:
mode:
Diffstat (limited to 'interf.c')
-rw-r--r--interf.c94
1 files changed, 68 insertions, 26 deletions
diff --git a/interf.c b/interf.c
index 8062021..259e793 100644
--- a/interf.c
+++ b/interf.c
@@ -135,6 +135,41 @@ sim_stop (SIM_DESC sd)
}
static int
+sis_insert_hw_breakpoint (int addr)
+{
+ if (ebase.wprnum < BPT_MAX)
+ {
+ ebase.bpts[ebase.bptnum] = addr;
+ ebase.bptnum++;
+ if (sis_verbose)
+ printf ("inserted hw breakpoint at %x\n", addr);
+ return SIM_RC_OK;
+ }
+ else
+ return SIM_RC_FAIL;
+}
+
+static int
+sis_remove_hw_breakpoint (int addr)
+{
+ int i = 0;
+
+ if (!ebase.bptnum)
+ return 1;
+ while ((i < ebase.bptnum) && (ebase.bpts[i] != addr))
+ i++;
+ if (addr == ebase.bpts[i])
+ {
+ for (; i < ebase.bptnum - 1; i++)
+ ebase.wprs[i] = ebase.bpts[i + 1];
+ ebase.bptnum -= 1;
+ if (sis_verbose)
+ printf ("removed hw breakpoint at %x\n", addr);
+ }
+ return 1;
+}
+
+static int
sis_insert_watchpoint_read (int addr, unsigned char mask)
{
if (ebase.wprnum < WPR_MAX)
@@ -155,6 +190,8 @@ sis_remove_watchpoint_read (int addr)
{
int i = 0;
+ if (!ebase.wprnum)
+ return 1;
while ((i < ebase.wprnum) && (ebase.wprs[i] != addr))
i++;
if (addr == ebase.wprs[i])
@@ -164,7 +201,6 @@ sis_remove_watchpoint_read (int addr)
ebase.wprnum -= 1;
if (sis_verbose)
printf ("removed read watchpoint at %x\n", addr);
- return 0;
}
return 1;
}
@@ -190,6 +226,8 @@ sis_remove_watchpoint_write (int addr)
{
int i = 0;
+ if (!ebase.wpwnum)
+ return 1;
while ((i < ebase.wpwnum) && (ebase.wpws[i] != addr))
i++;
if (addr == ebase.wpws[i])
@@ -199,9 +237,8 @@ sis_remove_watchpoint_write (int addr)
ebase.wpwnum -= 1;
if (sis_verbose)
printf ("removed write watchpoint at %x\n", addr);
- return SIM_RC_OK;
}
- return SIM_RC_FAIL;
+ return SIM_RC_OK;
}
int
@@ -215,68 +252,73 @@ sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
int
-sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+sim_set_watchpoint (uint32 mem, int length, int type)
{
int res;
unsigned char mask;
- switch (length)
- {
- case 1:
- mask = 0;
- break;
- case 2:
- mask = 1;
- break;
- case 4:
- mask = 3;
- break;
- default:
- mask = 7;
- break;
- }
+ if (!length)
+ return 1; /* used by gdb for probing of watchpoints */
+
+ mask = length - 1;
switch (type)
{
case 0:
- res = sis_insert_watchpoint_write (mem, mask);
+ res = sim_insert_swbreakpoint (mem, length);
break;
case 1:
- res = sis_insert_watchpoint_read (mem, mask);
+ res = sis_insert_hw_breakpoint (mem);
break;
case 2:
+ res = sis_insert_watchpoint_write (mem, mask);
+ break;
+ case 3:
+ res = sis_insert_watchpoint_read (mem, mask);
+ break;
+ case 4:
if ((res = sis_insert_watchpoint_write (mem, mask)) == SIM_RC_OK)
res = sis_insert_watchpoint_read (mem, mask);
if (res == SIM_RC_FAIL)
sis_remove_watchpoint_read (mem);
break;
default:
- res = -1;
+ res = 0;
}
return (res);
}
int
-sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+sim_clear_watchpoint (uint32 mem, int length, int type)
{
int res;
+
+ if (!length)
+ return 1;
+
switch (type)
{
case 0:
- res = sis_remove_watchpoint_write (mem);
+ res = sim_remove_swbreakpoint (mem, length);
break;
case 1:
- res = sis_remove_watchpoint_read (mem);
+ res = sis_remove_hw_breakpoint (mem);
break;
case 2:
+ res = sis_remove_watchpoint_write (mem);
+ break;
+ case 3:
+ res = sis_remove_watchpoint_read (mem);
+ break;
+ case 4:
if ((res = sis_remove_watchpoint_write (mem)) == SIM_RC_OK)
res = sis_remove_watchpoint_read (mem);
else
sis_remove_watchpoint_read (mem);
break;
default:
- res = -1;
+ res = 0;
}
return (res);
}