提交 bf99de36 编写于 作者: M Michael Neuling 提交者: Benjamin Herrenschmidt

powerpc: Add the DAWR support to the set_break()

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: NMichael Neuling <mikey@neuling.org>
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 9422de3e
...@@ -180,6 +180,10 @@ struct machdep_calls { ...@@ -180,6 +180,10 @@ struct machdep_calls {
int (*set_dabr)(unsigned long dabr, int (*set_dabr)(unsigned long dabr,
unsigned long dabrx); 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 */ #ifdef CONFIG_PPC32 /* XXX for now */
/* A general init function, called by ppc_init in init/main.c. /* A general init function, called by ppc_init in init/main.c.
May be NULL. */ May be NULL. */
......
...@@ -407,10 +407,33 @@ static inline int set_dabr(struct arch_hw_breakpoint *brk) ...@@ -407,10 +407,33 @@ static inline int set_dabr(struct arch_hw_breakpoint *brk)
return __set_dabr(dabr, dabrx); 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) int set_break(struct arch_hw_breakpoint *brk)
{ {
__get_cpu_var(current_brk) = *brk; __get_cpu_var(current_brk) = *brk;
if (cpu_has_feature(CPU_FTR_DAWR))
return set_dawr(brk);
return set_dabr(brk); return set_dabr(brk);
} }
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/eeh.h> #include <asm/eeh.h>
#include <asm/reg.h>
#include "plpar_wrappers.h" #include "plpar_wrappers.h"
#include "pseries.h" #include "pseries.h"
...@@ -500,6 +501,14 @@ static int pseries_set_xdabr(unsigned long dabr, unsigned long dabrx) ...@@ -500,6 +501,14 @@ static int pseries_set_xdabr(unsigned long dabr, unsigned long dabrx)
return plpar_hcall_norets(H_SET_XDABR, dabr, 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_CHARACTERISTICS_TOKEN 44
#define CMO_MAXLENGTH 1026 #define CMO_MAXLENGTH 1026
...@@ -606,6 +615,9 @@ static void __init pSeries_init_early(void) ...@@ -606,6 +615,9 @@ static void __init pSeries_init_early(void)
else if (firmware_has_feature(FW_FEATURE_DABR)) else if (firmware_has_feature(FW_FEATURE_DABR))
ppc_md.set_dabr = pseries_set_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(); pSeries_cmo_feature_init();
iommu_init_early_pSeries(); iommu_init_early_pSeries();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册