sim: watchpoints: use common sim_pc_get

Few arches implement STATE_WATCHPOINTS()->pc while all of them implement
sim_pc_get.  Lets switch the sim-watch core for monitoring pc events to
the sim_pc_get API so this module works for all ports, and then we can
delete this old back channel of snooping in the port's cpu state -- the
code needs the pointer to the pc storage so that it can read out bytes
and compare them to the watchrange.

This also fixes the logic on multi-cpu sims by removing the limitation
of only being able to watch CPU0's state.
This commit is contained in:
Mike Frysinger
2015-03-23 00:44:54 -04:00
parent cd89c53f6d
commit 4c0d76b9c4
25 changed files with 129 additions and 54 deletions

View File

@@ -25,6 +25,7 @@
#include "sim-main.h"
#include "sim-assert.h"
#include "sim-cpu.h"
#include "libiberty.h"
#include <string.h>
@@ -66,6 +67,9 @@ typedef enum {
watch_sim_le_4,
watch_sim_le_8,
/* pc */
watch_pc,
/* wallclock */
watch_clock,
@@ -608,6 +612,45 @@ sim_events_watch_clock (SIM_DESC sd,
#endif
#if EXTERN_SIM_EVENTS_P
sim_event *
sim_events_watch_pc (SIM_DESC sd,
int is_within,
unsigned64 lb,
unsigned64 ub,
sim_event_handler *handler,
void *data)
{
sim_events *events = STATE_EVENTS (sd);
sim_event *new_event = sim_events_zalloc (sd);
/* type */
new_event->watching = watch_pc;
/* handler */
new_event->data = data;
new_event->handler = handler;
/* data */
new_event->lb = lb;
new_event->lb64 = lb;
new_event->ub = ub;
new_event->ub64 = ub;
new_event->is_within = (is_within != 0);
/* insert */
new_event->next = events->watchpoints;
events->watchpoints = new_event;
events->work_pending = 1;
ETRACE ((_ETRACE,
"event watching pc at %ld - tag 0x%lx - pc 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
(long)sim_events_time (sd),
(long)new_event,
(long)new_event->lb,
(long)new_event->ub,
(long)new_event->handler,
(long)new_event->data));
return new_event;
}
#endif
#if EXTERN_SIM_EVENTS_P
sim_event *
sim_events_watch_sim (SIM_DESC sd,
@@ -965,6 +1008,21 @@ sim_watch_valid (SIM_DESC sd,
}
#undef WATCH_SIM
case watch_pc:
{
int c;
for (c = 0; c < MAX_NR_PROCESSORS; ++c)
{
sim_cpu *cpu = STATE_CPU (sd, c);
sim_cia cia = sim_pc_get (cpu);
if (to_do->is_within == (cia >= to_do->lb64 && cia <= to_do->ub64))
return 1;
}
return 0;
}
case watch_clock: /* wallclock */
{
unsigned long elapsed_time = sim_events_elapsed_time (sd);