]> rtime.felk.cvut.cz Git - linux-imx.git/commitdiff
powerpc: Add the DAWR support to the set_break()
authorMichael Neuling <mikey@neuling.org>
Thu, 20 Dec 2012 14:06:45 +0000 (14:06 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 10 Jan 2013 06:01:47 +0000 (17:01 +1100)
This adds DAWR supoprt to the set_break().

It does both bare metal and PAPR versions of setting the DAWR.

There is still some work we can do to make full use of the watchpoint but that
will come later.

Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/machdep.h
arch/powerpc/kernel/process.c
arch/powerpc/platforms/pseries/setup.c

index 19d9d96eb8d357129e4db6b4cfeb521d44cabfa7..3d6b4100dac1a913588ff2698036de94126ace9a 100644 (file)
@@ -180,6 +180,10 @@ struct machdep_calls {
        int             (*set_dabr)(unsigned long dabr,
                                    unsigned long dabrx);
 
+       /* Set DAWR for this platform, leave empty for default implemenation */
+       int             (*set_dawr)(unsigned long dawr,
+                                   unsigned long dawrx);
+
 #ifdef CONFIG_PPC32    /* XXX for now */
        /* A general init function, called by ppc_init in init/main.c.
           May be NULL. */
index c16c1c2abeeabf86264a0ca29b9ee6d46c58302a..8d56452e1dbd36bff6bd3ad48f0b073717a48f9a 100644 (file)
@@ -407,10 +407,33 @@ static inline int set_dabr(struct arch_hw_breakpoint *brk)
        return __set_dabr(dabr, dabrx);
 }
 
+static inline int set_dawr(struct arch_hw_breakpoint *brk)
+{
+       unsigned long dawr, dawrx;
+
+       dawr = brk->address;
+
+       dawrx  = (brk->type & (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE)) \
+                                  << (63 - 58); //* read/write bits */
+       dawrx |= ((brk->type & (HW_BRK_TYPE_TRANSLATE)) >> 2) \
+                                  << (63 - 59); //* translate */
+       dawrx |= (brk->type & (HW_BRK_TYPE_PRIV_ALL)) \
+                                  >> 3; //* PRIM bits */
+
+       if (ppc_md.set_dawr)
+               return ppc_md.set_dawr(dawr, dawrx);
+       mtspr(SPRN_DAWR, dawr);
+       mtspr(SPRN_DAWRX, dawrx);
+       return 0;
+}
+
 int set_break(struct arch_hw_breakpoint *brk)
 {
        __get_cpu_var(current_brk) = *brk;
 
+       if (cpu_has_feature(CPU_FTR_DAWR))
+               return set_dawr(brk);
+
        return set_dabr(brk);
 }
 
index 1890730354bb23070452d3b9a111719e7cab5792..b1f60d162bb617618d56654855b63598380d7f8c 100644 (file)
@@ -65,6 +65,7 @@
 #include <asm/smp.h>
 #include <asm/firmware.h>
 #include <asm/eeh.h>
+#include <asm/reg.h>
 
 #include "plpar_wrappers.h"
 #include "pseries.h"
@@ -500,6 +501,14 @@ static int pseries_set_xdabr(unsigned long dabr, unsigned long dabrx)
        return plpar_hcall_norets(H_SET_XDABR, dabr, dabrx);
 }
 
+static int pseries_set_dawr(unsigned long dawr, unsigned long dawrx)
+{
+       /* PAPR says we can't set HYP */
+       dawrx &= ~DAWRX_HYP;
+
+       return  plapr_set_watchpoint0(dawr, dawrx);
+}
+
 #define CMO_CHARACTERISTICS_TOKEN 44
 #define CMO_MAXLENGTH 1026
 
@@ -606,6 +615,9 @@ static void __init pSeries_init_early(void)
        else if (firmware_has_feature(FW_FEATURE_DABR))
                ppc_md.set_dabr = pseries_set_dabr;
 
+       if (firmware_has_feature(FW_FEATURE_SET_MODE))
+               ppc_md.set_dawr = pseries_set_dawr;
+
        pSeries_cmo_feature_init();
        iommu_init_early_pSeries();