The OpenRISC 1000 can support hardware breakpoints and watchpoints, if matchpoints are free in the debug unit.
or1k_set_breakpoint
. This is the underlying
OpenRISC 1000 function which sets a hardware breakpoint if one
is available. This is controlled through the Debug Value
Register and Debug Control Register. This function is used by
the target operation functions
or1k_insert_breakpoint
and
or1k_insert_hw_breakpoint
.
The first free hardware matchpoint is found by searching
through the Debug Control Registers for a register without its
DVR/DCR Preset (DP) flag set using
or1k_first_free_matchpoint
.
The Debug Value Register is set to the address of the breakpoint and the Debug Control Register to trigger when the unsigned effective address of the fetched instruction is equal to the Debug Value Register. The corresponding OpenRISC 1000 watchpoint is marked as unchained in Debug Mode Register 1 and set to trigger a trap exception in Debug Mode Register 2.
or1k_clear_breakpoint
. This is the
counterpart to or1k_set_breakpoint
. It is
called by the target operation functions
remove_breakpoint
and
remove_hw_breakpoint
.
The Debug Control Registers are searched for an entry matching
the given address (using
or1k_matchpoint_equal
). If a register is
found, its DVR/DCR Present flag is cleared, and the
matchpoint marked unused in Debug Mode Register 2.
or1k_insert_breakpoint
. This function
inserts a breakpoint. It tries to insert a hardware breakpoint
using or1k_set_breakpoint
. If this fails,
the generic memory_insert_breakpoint
is
used to set a software breakpoint.
or1k_remove_breakpoint
. This is the
counterpart to or1k_insert_breakpoint
. It
tries to clear a hardware breakpoint, and if that fails tries
to clear a software breakpoint using the generic
memory_remove_breakpoint
.
or1k_insert_hw_breakpoint
and
or1k_remove_hw_breakpoint
. These
functions are similar to
or1k_insert_breakpoint
and
or1k_remove_breakpoint
. However if a
hardware breakpoint is not available, they do not attempt to
use a software (memory) breakpoint instead.
or1k_insert_watchpoint
. This function
attempts to insert a GDB hardware watchpoint. For this it
requires a pair of OpenRISC 1000 watchpoints chained
together. The first will check for a memory access greater than
or equal to the start address of interest. The second will check
for a memory access less than or equal to the end address of
interest. If both criteria are met. The access type can be the
load effective address (for GDB rwatch
watchpoints), store effective address (for GDB
watch watchpoints) or both (for GDB
awatch watchpoints).
The pair of OpenRISC 1000 watchpoints must be adjacent (so they
can be chained together using Debug Mode Register 1), but it is
possible that successive breakpoints have fragmented the use of
OpenRISC 1000
watchpoints. or1k_watchpoint_gc
is used to
shuffle up all the existing OpenRISC 1000 watchpoints which can
be moved, to find a pair if possible.
or1k_remove_watchpoint
. This is the
counterpart of or1k_insert_watchpoint
. It
searches for an adjacent pair of OpenRISC 1000 watchpoints that
match using or1k_matchpoint_equal
. If found
both are marked unused in their Debug Control Register and
cleared from triggering in Debug Mode Register 2.
or1k_stopped_by_watchpoint
and
or1k_stopped_data_address
. These functions
are called to find out about GDB watchpoints which may have
triggered. Both make use of the utility function,
or1k_stopped_watchpoint_info
, which
determines if a GDB watchpoint was triggered, if so which
watchpoint and for what
address. or1k_stopped_watchpoint
just
returns a Boolean to indicate if a watchpoint was
triggered. or1k_stopped_data_address
is
called once for each watchpoint that has triggered. It returns
the address that triggered the watchpoint and must also clear
the watchpoint (in Debug Mode Register 2).