#ifndef _ASM_POWERPC_DEBUG_H
 #define _ASM_POWERPC_DEBUG_H
 
+#include <asm/hw_breakpoint.h>
+
 struct pt_regs;
 
 extern struct dentry *powerpc_debugfs_root;
 extern int (*__debugger_bpt)(struct pt_regs *regs);
 extern int (*__debugger_sstep)(struct pt_regs *regs);
 extern int (*__debugger_iabr_match)(struct pt_regs *regs);
-extern int (*__debugger_dabr_match)(struct pt_regs *regs);
+extern int (*__debugger_break_match)(struct pt_regs *regs);
 extern int (*__debugger_fault_handler)(struct pt_regs *regs);
 
 #define DEBUGGER_BOILERPLATE(__NAME) \
 DEBUGGER_BOILERPLATE(debugger_bpt)
 DEBUGGER_BOILERPLATE(debugger_sstep)
 DEBUGGER_BOILERPLATE(debugger_iabr_match)
-DEBUGGER_BOILERPLATE(debugger_dabr_match)
+DEBUGGER_BOILERPLATE(debugger_break_match)
 DEBUGGER_BOILERPLATE(debugger_fault_handler)
 
 #else
 static inline int debugger_bpt(struct pt_regs *regs) { return 0; }
 static inline int debugger_sstep(struct pt_regs *regs) { return 0; }
 static inline int debugger_iabr_match(struct pt_regs *regs) { return 0; }
-static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
+static inline int debugger_break_match(struct pt_regs *regs) { return 0; }
 static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
 #endif
 
-extern int set_dabr(unsigned long dabr, unsigned long dabrx);
+int set_break(struct arch_hw_breakpoint *brk);
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 extern void do_send_trap(struct pt_regs *regs, unsigned long address,
                         unsigned long error_code, int signal_code, int brkpt);
 #else
-extern void do_dabr(struct pt_regs *regs, unsigned long address,
-                   unsigned long error_code);
+
+extern void do_break(struct pt_regs *regs, unsigned long address,
+                    unsigned long error_code);
 #endif
 
 #endif /* _ASM_POWERPC_DEBUG_H */
 
 #define _PPC_BOOK3S_64_HW_BREAKPOINT_H
 
 #ifdef __KERNEL__
-#ifdef CONFIG_HAVE_HW_BREAKPOINT
-
 struct arch_hw_breakpoint {
        unsigned long   address;
-       unsigned long   dabrx;
-       int             type;
-       u8              len; /* length of the target data symbol */
-       bool            extraneous_interrupt;
+       u16             type;
+       u16             len; /* length of the target data symbol */
 };
 
+/* Note: Don't change the the first 6 bits below as they are in the same order
+ * as the dabr and dabrx.
+ */
+#define HW_BRK_TYPE_READ               0x01
+#define HW_BRK_TYPE_WRITE              0x02
+#define HW_BRK_TYPE_TRANSLATE          0x04
+#define HW_BRK_TYPE_USER               0x08
+#define HW_BRK_TYPE_KERNEL             0x10
+#define HW_BRK_TYPE_HYP                        0x20
+#define HW_BRK_TYPE_EXTRANEOUS_IRQ     0x80
+
+/* bits that overlap with the bottom 3 bits of the dabr */
+#define HW_BRK_TYPE_RDWR       (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE)
+#define HW_BRK_TYPE_DABR       (HW_BRK_TYPE_RDWR | HW_BRK_TYPE_TRANSLATE)
+#define HW_BRK_TYPE_PRIV_ALL   (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
+                                HW_BRK_TYPE_HYP)
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
 #include <linux/kdebug.h>
 #include <asm/reg.h>
 #include <asm/debug.h>
                        struct perf_sample_data *data, struct pt_regs *regs);
 static inline void hw_breakpoint_disable(void)
 {
-       set_dabr(0, 0);
+       struct arch_hw_breakpoint brk;
+
+       brk.address = 0;
+       brk.type = 0;
+       brk.len = 0;
+       set_break(&brk);
 }
 extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
 
 
 #include <linux/cache.h>
 #include <asm/ptrace.h>
 #include <asm/types.h>
+#include <asm/hw_breakpoint.h>
 
 /* We do _not_ want to define new machine types at all, those must die
  * in favor of using the device-tree
        struct perf_event *last_hit_ubp;
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif
-       unsigned long   dabr;           /* Data address breakpoint register */
-       unsigned long   dabrx;          /*      ... extension  */
+       struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
        unsigned long   trap_nr;        /* last trap # on this thread */
 #ifdef CONFIG_ALTIVEC
        /* Complete AltiVec register set */
 
 #define   DAWRX_KERNEL (1UL << 1)
 #define   DAWRX_HYP    (1UL << 2)
 #define SPRN_DABR      0x3F5   /* Data Address Breakpoint Register */
-#define   DABR_TRANSLATION     (1UL << 2)
-#define   DABR_DATA_WRITE      (1UL << 1)
-#define   DABR_DATA_READ       (1UL << 0)
 #define SPRN_DABR2     0x13D   /* e300 */
 #define SPRN_DABRX     0x3F7   /* Data Address Breakpoint Register Extension */
 #define   DABRX_USER   (1UL << 0)
 
        ld      r4,_DAR(r1)
        ld      r5,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_dabr
+       bl      .do_break
 12:    b       .ret_from_except_lite
 
 
 
         * If so, DABR will be populated in single_step_dabr_instruction().
         */
        if (current->thread.last_hit_ubp != bp)
-               set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
+               set_break(info);
 
        return 0;
 }
        }
 
        *slot = NULL;
-       set_dabr(0, 0);
+       hw_breakpoint_disable();
 }
 
 /*
 
 int arch_bp_generic_fields(int type, int *gen_bp_type)
 {
-       switch (type) {
-       case DABR_DATA_READ:
-               *gen_bp_type = HW_BREAKPOINT_R;
-               break;
-       case DABR_DATA_WRITE:
-               *gen_bp_type = HW_BREAKPOINT_W;
-               break;
-       case (DABR_DATA_WRITE | DABR_DATA_READ):
-               *gen_bp_type = (HW_BREAKPOINT_W | HW_BREAKPOINT_R);
-               break;
-       default:
+       *gen_bp_type = 0;
+       if (type & HW_BRK_TYPE_READ)
+               *gen_bp_type |= HW_BREAKPOINT_R;
+       if (type & HW_BRK_TYPE_WRITE)
+               *gen_bp_type |= HW_BREAKPOINT_W;
+       if (*gen_bp_type == 0)
                return -EINVAL;
-       }
        return 0;
 }
 
        if (!bp)
                return ret;
 
-       switch (bp->attr.bp_type) {
-       case HW_BREAKPOINT_R:
-               info->type = DABR_DATA_READ;
-               break;
-       case HW_BREAKPOINT_W:
-               info->type = DABR_DATA_WRITE;
-               break;
-       case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
-               info->type = (DABR_DATA_READ | DABR_DATA_WRITE);
-               break;
-       default:
+       info->type = HW_BRK_TYPE_TRANSLATE;
+       if (bp->attr.bp_type & HW_BREAKPOINT_R)
+               info->type |= HW_BRK_TYPE_READ;
+       if (bp->attr.bp_type & HW_BREAKPOINT_W)
+               info->type |= HW_BRK_TYPE_WRITE;
+       if (info->type == HW_BRK_TYPE_TRANSLATE)
+               /* must set alteast read or write */
                return ret;
-       }
-
+       if (!(bp->attr.exclude_user))
+               info->type |= HW_BRK_TYPE_USER;
+       if (!(bp->attr.exclude_kernel))
+               info->type |= HW_BRK_TYPE_KERNEL;
+       if (!(bp->attr.exclude_hv))
+               info->type |= HW_BRK_TYPE_HYP;
        info->address = bp->attr.bp_addr;
        info->len = bp->attr.bp_len;
-       info->dabrx = DABRX_ALL;
-       if (bp->attr.exclude_user)
-               info->dabrx &= ~DABRX_USER;
-       if (bp->attr.exclude_kernel)
-               info->dabrx &= ~DABRX_KERNEL;
-       if (bp->attr.exclude_hv)
-               info->dabrx &= ~DABRX_HYP;
 
        /*
         * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8)
 
        info = counter_arch_bp(tsk->thread.last_hit_ubp);
        regs->msr &= ~MSR_SE;
-       set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
+       set_break(info);
        tsk->thread.last_hit_ubp = NULL;
 }
 
        unsigned long dar = regs->dar;
 
        /* Disable breakpoints during exception handling */
-       set_dabr(0, 0);
+       hw_breakpoint_disable();
 
        /*
         * The counter may be concurrently released but that can only
         * we still need to single-step the instruction, but we don't
         * generate an event.
         */
-       info->extraneous_interrupt = !((bp->attr.bp_addr <= dar) &&
-                       (dar - bp->attr.bp_addr < bp->attr.bp_len));
+       if (!((bp->attr.bp_addr <= dar) &&
+             (dar - bp->attr.bp_addr < bp->attr.bp_len)))
+               info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
 
        /* Do not emulate user-space instructions, instead single-step them */
        if (user_mode(regs)) {
         * As a policy, the callback is invoked in a 'trigger-after-execute'
         * fashion
         */
-       if (!info->extraneous_interrupt)
+       if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ))
                perf_bp_event(bp, regs);
 
-       set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
+       set_break(info);
 out:
        rcu_read_unlock();
        return rc;
         * We shall invoke the user-defined callback function in the single
         * stepping handler to confirm to 'trigger-after-execute' semantics
         */
-       if (!info->extraneous_interrupt)
+       if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ))
                perf_bp_event(bp, regs);
 
-       set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
+       set_break(info);
        current->thread.last_hit_ubp = NULL;
 
        /*
 
        return 1;
 }
 
-static int kgdb_dabr_match(struct pt_regs *regs)
+static int kgdb_break_match(struct pt_regs *regs)
 {
        if (user_mode(regs))
                return 0;
 static void *old__debugger_bpt;
 static void *old__debugger_sstep;
 static void *old__debugger_iabr_match;
-static void *old__debugger_dabr_match;
+static void *old__debugger_break_match;
 static void *old__debugger_fault_handler;
 
 int kgdb_arch_init(void)
        old__debugger_bpt = __debugger_bpt;
        old__debugger_sstep = __debugger_sstep;
        old__debugger_iabr_match = __debugger_iabr_match;
-       old__debugger_dabr_match = __debugger_dabr_match;
+       old__debugger_break_match = __debugger_break_match;
        old__debugger_fault_handler = __debugger_fault_handler;
 
        __debugger_ipi = kgdb_call_nmi_hook;
        __debugger_bpt = kgdb_handle_breakpoint;
        __debugger_sstep = kgdb_singlestep;
        __debugger_iabr_match = kgdb_iabr_match;
-       __debugger_dabr_match = kgdb_dabr_match;
+       __debugger_break_match = kgdb_break_match;
        __debugger_fault_handler = kgdb_not_implemented;
 
        return 0;
        __debugger_bpt = old__debugger_bpt;
        __debugger_sstep = old__debugger_sstep;
        __debugger_iabr_match = old__debugger_iabr_match;
-       __debugger_dabr_match = old__debugger_dabr_match;
+       __debugger_breakx_match = old__debugger_break_match;
        __debugger_fault_handler = old__debugger_fault_handler;
 }
 
        force_sig_info(SIGTRAP, &info, current);
 }
 #else  /* !CONFIG_PPC_ADV_DEBUG_REGS */
-void do_dabr(struct pt_regs *regs, unsigned long address,
+void do_break (struct pt_regs *regs, unsigned long address,
                    unsigned long error_code)
 {
        siginfo_t info;
                        11, SIGSEGV) == NOTIFY_STOP)
                return;
 
-       if (debugger_dabr_match(regs))
+       if (debugger_break_match(regs))
                return;
 
-       /* Clear the DABR */
-       set_dabr(0, 0);
+       /* Clear the breakpoint */
+       hw_breakpoint_disable();
 
        /* Deliver the signal to userspace */
        info.si_signo = SIGTRAP;
 }
 #endif /* CONFIG_PPC_ADV_DEBUG_REGS */
 
-static DEFINE_PER_CPU(unsigned long, current_dabr);
+static DEFINE_PER_CPU(struct arch_hw_breakpoint, current_brk);
 
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 /*
 #ifndef CONFIG_HAVE_HW_BREAKPOINT
 static void set_debug_reg_defaults(struct thread_struct *thread)
 {
-       if (thread->dabr) {
-               thread->dabr = 0;
-               thread->dabrx = 0;
-               set_dabr(0, 0);
-       }
+       thread->hw_brk.address = 0;
+       thread->hw_brk.type = 0;
+       set_break(&thread->hw_brk);
 }
 #endif /* !CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* CONFIG_PPC_ADV_DEBUG_REGS */
 
-int set_dabr(unsigned long dabr, unsigned long dabrx)
-{
-       __get_cpu_var(current_dabr) = dabr;
-
-       if (ppc_md.set_dabr)
-               return ppc_md.set_dabr(dabr, dabrx);
-
-       /* XXX should we have a CPU_FTR_HAS_DABR ? */
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
+static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
+{
        mtspr(SPRN_DAC1, dabr);
 #ifdef CONFIG_PPC_47x
        isync();
 #endif
+       return 0;
+}
 #elif defined(CONFIG_PPC_BOOK3S)
+static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
+{
        mtspr(SPRN_DABR, dabr);
        mtspr(SPRN_DABRX, dabrx);
-#endif
        return 0;
 }
+#else
+static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
+{
+       return -EINVAL;
+}
+#endif
+
+static inline int set_dabr(struct arch_hw_breakpoint *brk)
+{
+       unsigned long dabr, dabrx;
+
+       dabr = brk->address | (brk->type & HW_BRK_TYPE_DABR);
+       dabrx = ((brk->type >> 3) & 0x7);
+
+       if (ppc_md.set_dabr)
+               return ppc_md.set_dabr(dabr, dabrx);
+
+       return __set_dabr(dabr, dabrx);
+}
+
+int set_break(struct arch_hw_breakpoint *brk)
+{
+       __get_cpu_var(current_brk) = *brk;
+
+       return set_dabr(brk);
+}
 
 #ifdef CONFIG_PPC64
 DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
 #endif
 
+static inline bool hw_brk_match(struct arch_hw_breakpoint *a,
+                             struct arch_hw_breakpoint *b)
+{
+       if (a->address != b->address)
+               return false;
+       if (a->type != b->type)
+               return false;
+       if (a->len != b->len)
+               return false;
+       return true;
+}
+
 struct task_struct *__switch_to(struct task_struct *prev,
        struct task_struct *new)
 {
  * schedule DABR
  */
 #ifndef CONFIG_HAVE_HW_BREAKPOINT
-       if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
-               set_dabr(new->thread.dabr, new->thread.dabrx);
+       if (unlikely(hw_brk_match(&__get_cpu_var(current_brk), &new->thread.hw_brk)))
+               set_break(&new->thread.hw_brk);
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif
 
 
        struct perf_event *bp;
        struct perf_event_attr attr;
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#ifndef CONFIG_PPC_ADV_DEBUG_REGS
+       struct arch_hw_breakpoint hw_brk;
+#endif
 
        /* For ppc64 we support one DABR and no IABR's at the moment (ppc64).
         *  For embedded processors we support one DAC and no IAC's at the
         */
 
        /* Ensure breakpoint translation bit is set */
-       if (data && !(data & DABR_TRANSLATION))
+       if (data && !(data & HW_BRK_TYPE_TRANSLATE))
                return -EIO;
+       hw_brk.address = data & (~HW_BRK_TYPE_DABR);
+       hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
+       hw_brk.len = 8;
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
        if (ptrace_get_breakpoints(task) < 0)
                return -ESRCH;
 
        bp = thread->ptrace_bps[0];
-       if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) {
+       if ((!data) || !(hw_brk.type & HW_BRK_TYPE_RDWR)) {
                if (bp) {
                        unregister_hw_breakpoint(bp);
                        thread->ptrace_bps[0] = NULL;
        }
        if (bp) {
                attr = bp->attr;
-               attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
-               arch_bp_generic_fields(data &
-                                       (DABR_DATA_WRITE | DABR_DATA_READ),
-                                                       &attr.bp_type);
+               attr.bp_addr = hw_brk.address;
+               arch_bp_generic_fields(hw_brk.type, &attr.bp_type);
 
                /* Enable breakpoint */
                attr.disabled = false;
                }
                thread->ptrace_bps[0] = bp;
                ptrace_put_breakpoints(task);
-               thread->dabr = data;
-               thread->dabrx = DABRX_ALL;
+               thread->hw_brk = hw_brk;
                return 0;
        }
 
        /* Create a new breakpoint request if one doesn't exist already */
        hw_breakpoint_init(&attr);
-       attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
-       arch_bp_generic_fields(data & (DABR_DATA_WRITE | DABR_DATA_READ),
-                                                               &attr.bp_type);
+       attr.bp_addr = hw_brk.address;
+       arch_bp_generic_fields(hw_brk.type,
+                              &attr.bp_type);
 
        thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
                                               ptrace_triggered, NULL, task);
        ptrace_put_breakpoints(task);
 
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
-
-       /* Move contents to the DABR register */
-       task->thread.dabr = data;
-       task->thread.dabrx = DABRX_ALL;
+       task->thread.hw_brk = hw_brk;
 #else /* CONFIG_PPC_ADV_DEBUG_REGS */
        /* As described above, it was assumed 3 bits were passed with the data
         *  address, but we will assume only the mode bits will be passed
        struct perf_event_attr attr;
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #ifndef CONFIG_PPC_ADV_DEBUG_REGS
-       unsigned long dabr;
+       struct arch_hw_breakpoint brk;
 #endif
 
        if (bp_info->version != 1)
        if ((unsigned long)bp_info->addr >= TASK_SIZE)
                return -EIO;
 
-       dabr = (unsigned long)bp_info->addr & ~7UL;
-       dabr |= DABR_TRANSLATION;
+       brk.address = bp_info->addr & ~7UL;
+       brk.type = HW_BRK_TYPE_TRANSLATE;
        if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
-               dabr |= DABR_DATA_READ;
+               brk.type |= HW_BRK_TYPE_READ;
        if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
-               dabr |= DABR_DATA_WRITE;
+               brk.type |= HW_BRK_TYPE_WRITE;
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
        if (ptrace_get_breakpoints(child) < 0)
                return -ESRCH;
        hw_breakpoint_init(&attr);
        attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
        attr.bp_len = len;
-       arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ),
-                                                               &attr.bp_type);
+       arch_bp_generic_fields(brk.type, &attr.bp_type);
 
        thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
                                               ptrace_triggered, NULL, child);
        if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
                return -EINVAL;
 
-       if (child->thread.dabr)
+       if (child->thread.hw_brk.address)
                return -ENOSPC;
 
-       child->thread.dabr = dabr;
-       child->thread.dabrx = DABRX_ALL;
+       child->thread.hw_brk = brk;
 
        return 1;
 #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
        ptrace_put_breakpoints(child);
        return ret;
 #else /* CONFIG_HAVE_HW_BREAKPOINT */
-       if (child->thread.dabr == 0)
+       if (child->thread.hw_brk.address == 0)
                return -ENOENT;
 
-       child->thread.dabr = 0;
+       child->thread.hw_brk.address = 0;
+       child->thread.hw_brk.type = 0;
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
        return 0;
        }
 
        case PTRACE_GET_DEBUGREG: {
+#ifndef CONFIG_PPC_ADV_DEBUG_REGS
+               unsigned long dabr_fake;
+#endif
                ret = -EINVAL;
                /* We only support one DABR and no IABRS at the moment */
                if (addr > 0)
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
                ret = put_user(child->thread.dac1, datalp);
 #else
-               ret = put_user(child->thread.dabr, datalp);
+               dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
+                            (child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
+               ret = put_user(dabr_fake, datalp);
 #endif
                break;
        }
 
        }
 
        case PTRACE_GET_DEBUGREG: {
+#ifndef CONFIG_PPC_ADV_DEBUG_REGS
+               unsigned long dabr_fake;
+#endif
                ret = -EINVAL;
                /* We only support one DABR and no IABRS at the moment */
                if (addr > 0)
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
                ret = put_user(child->thread.dac1, (u32 __user *)data);
 #else
-               ret = put_user(child->thread.dabr, (u32 __user *)data);
+               dabr_fake = (
+                       (child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
+                       (child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
+               ret = put_user(dabr_fake, (u32 __user *)data);
 #endif
                break;
        }
 
         * user space. The DABR will have been cleared if it
         * triggered inside the kernel.
         */
-       if (current->thread.dabr)
-               set_dabr(current->thread.dabr, current->thread.dabrx);
+       if (current->thread.hw_brk.address &&
+               current->thread.hw_brk.type)
+               set_break(¤t->thread.hw_brk);
 #endif
        /* Re-enable the breakpoints for the signal stack */
        thread_change_pc(current, regs);
 
 int (*__debugger_bpt)(struct pt_regs *regs) __read_mostly;
 int (*__debugger_sstep)(struct pt_regs *regs) __read_mostly;
 int (*__debugger_iabr_match)(struct pt_regs *regs) __read_mostly;
-int (*__debugger_dabr_match)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_break_match)(struct pt_regs *regs) __read_mostly;
 int (*__debugger_fault_handler)(struct pt_regs *regs) __read_mostly;
 
 EXPORT_SYMBOL(__debugger);
 EXPORT_SYMBOL(__debugger_bpt);
 EXPORT_SYMBOL(__debugger_sstep);
 EXPORT_SYMBOL(__debugger_iabr_match);
-EXPORT_SYMBOL(__debugger_dabr_match);
+EXPORT_SYMBOL(__debugger_break_match);
 EXPORT_SYMBOL(__debugger_fault_handler);
 #endif
 
 
 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \
                             defined(CONFIG_PPC_BOOK3S_64))
        if (error_code & DSISR_DABRMATCH) {
-               /* DABR match */
-               do_dabr(regs, address, error_code);
+               /* breakpoint match */
+               do_break(regs, address, error_code);
                return 0;
        }
 #endif
 
 #include <asm/setjmp.h>
 #include <asm/reg.h>
 #include <asm/debug.h>
+#include <asm/hw_breakpoint.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
        return 1;
 }
 
-static int xmon_dabr_match(struct pt_regs *regs)
+static int xmon_break_match(struct pt_regs *regs)
 {
        if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
                return 0;
 
 static void insert_cpu_bpts(void)
 {
-       if (dabr.enabled)
-               set_dabr(dabr.address | (dabr.enabled & 7), DABRX_ALL);
+       struct arch_hw_breakpoint brk;
+
+       if (dabr.enabled) {
+               brk.address = dabr.address;
+               brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
+               brk.len = 8;
+               set_break(&brk);
+       }
        if (iabr && cpu_has_feature(CPU_FTR_IABR))
                mtspr(SPRN_IABR, iabr->address
                         | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
 
 static void remove_cpu_bpts(void)
 {
-       set_dabr(0, 0);
+       hw_breakpoint_disable();
        if (cpu_has_feature(CPU_FTR_IABR))
                mtspr(SPRN_IABR, 0);
 }
                                printf(badaddr);
                                break;
                        }
-                       dabr.address &= ~7;
+                       dabr.address &= ~HW_BRK_TYPE_DABR;
                        dabr.enabled = mode | BP_DABR;
                }
                break;
                __debugger_bpt = xmon_bpt;
                __debugger_sstep = xmon_sstep;
                __debugger_iabr_match = xmon_iabr_match;
-               __debugger_dabr_match = xmon_dabr_match;
+               __debugger_break_match = xmon_break_match;
                __debugger_fault_handler = xmon_fault_handler;
        } else {
                __debugger = NULL;
                __debugger_bpt = NULL;
                __debugger_sstep = NULL;
                __debugger_iabr_match = NULL;
-               __debugger_dabr_match = NULL;
+               __debugger_break_match = NULL;
                __debugger_fault_handler = NULL;
        }
 }