+/* Target to_can_use_hw_breakpoint implementation. Return 1 if we can
+ handle the specified watch type. */
+
+int
+mips_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
+ int cnt, int ot)
+{
+ int i;
+ uint32_t wanted_mask, irw_mask;
+
+ if (!mips_linux_read_watch_registers (inferior_ptid.lwp (),
+ &watch_readback,
+ &watch_readback_valid, 0))
+ return 0;
+
+ switch (type)
+ {
+ case bp_hardware_watchpoint:
+ wanted_mask = W_MASK;
+ break;
+ case bp_read_watchpoint:
+ wanted_mask = R_MASK;
+ break;
+ case bp_access_watchpoint:
+ wanted_mask = R_MASK | W_MASK;
+ break;
+ default:
+ return 0;
+ }
+
+ for (i = 0;
+ i < mips_linux_watch_get_num_valid (&watch_readback) && cnt;
+ i++)
+ {
+ irw_mask = mips_linux_watch_get_irw_mask (&watch_readback, i);
+ if ((irw_mask & wanted_mask) == wanted_mask)
+ cnt--;
+ }
+ return (cnt == 0) ? 1 : 0;
+}
+
+/* Target to_stopped_by_watchpoint implementation. Return 1 if
+ stopped by watchpoint. The watchhi R and W bits indicate the watch
+ register triggered. */
+
+bool
+mips_linux_nat_target::stopped_by_watchpoint ()
+{
+ int n;
+ int num_valid;
+
+ if (!mips_linux_read_watch_registers (inferior_ptid.lwp (),
+ &watch_readback,
+ &watch_readback_valid, 1))
+ return false;
+
+ num_valid = mips_linux_watch_get_num_valid (&watch_readback);
+
+ for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++)
+ if (mips_linux_watch_get_watchhi (&watch_readback, n) & (R_MASK | W_MASK))
+ return true;
+
+ return false;
+}
+
+/* Target to_stopped_data_address implementation. Set the address
+ where the watch triggered (if known). Return 1 if the address was
+ known. */
+
+bool
+mips_linux_nat_target::stopped_data_address (CORE_ADDR *paddr)
+{
+ /* On mips we don't know the low order 3 bits of the data address,
+ so we must return false. */
+ return false;
+}
+
+/* Target to_region_ok_for_hw_watchpoint implementation. Return 1 if
+ the specified region can be covered by the watch registers. */
+
+int
+mips_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
+{
+ struct pt_watch_regs dummy_regs;
+ int i;
+
+ if (!mips_linux_read_watch_registers (inferior_ptid.lwp (),
+ &watch_readback,
+ &watch_readback_valid, 0))
+ return 0;
+
+ dummy_regs = watch_readback;
+ /* Clear them out. */
+ for (i = 0; i < mips_linux_watch_get_num_valid (&dummy_regs); i++)
+ mips_linux_watch_set_watchlo (&dummy_regs, i, 0);
+ return mips_linux_watch_try_one_watch (&dummy_regs, addr, len, 0);
+}
+
+/* Write the mirrored watch register values for each thread. */
+
+static int
+write_watchpoint_regs (void)
+{
+ struct lwp_info *lp;
+ int tid;
+
+ ALL_LWPS (lp)
+ {
+ tid = lp->ptid.lwp ();
+ if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror, NULL) == -1)
+ perror_with_name (_("Couldn't write debug register"));
+ }
+ return 0;
+}
+
+/* linux_nat_target::low_new_thread implementation. Write the
+ mirrored watch register values for the new thread. */