Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Michael Neuling and committed by
Benjamin Herrenschmidt
bf99de36 9422de3e

+39
+4
arch/powerpc/include/asm/machdep.h
··· 180 180 int (*set_dabr)(unsigned long dabr, 181 181 unsigned long dabrx); 182 182 183 + /* Set DAWR for this platform, leave empty for default implemenation */ 184 + int (*set_dawr)(unsigned long dawr, 185 + unsigned long dawrx); 186 + 183 187 #ifdef CONFIG_PPC32 /* XXX for now */ 184 188 /* A general init function, called by ppc_init in init/main.c. 185 189 May be NULL. */
+23
arch/powerpc/kernel/process.c
··· 407 407 return __set_dabr(dabr, dabrx); 408 408 } 409 409 410 + static inline int set_dawr(struct arch_hw_breakpoint *brk) 411 + { 412 + unsigned long dawr, dawrx; 413 + 414 + dawr = brk->address; 415 + 416 + dawrx = (brk->type & (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE)) \ 417 + << (63 - 58); //* read/write bits */ 418 + dawrx |= ((brk->type & (HW_BRK_TYPE_TRANSLATE)) >> 2) \ 419 + << (63 - 59); //* translate */ 420 + dawrx |= (brk->type & (HW_BRK_TYPE_PRIV_ALL)) \ 421 + >> 3; //* PRIM bits */ 422 + 423 + if (ppc_md.set_dawr) 424 + return ppc_md.set_dawr(dawr, dawrx); 425 + mtspr(SPRN_DAWR, dawr); 426 + mtspr(SPRN_DAWRX, dawrx); 427 + return 0; 428 + } 429 + 410 430 int set_break(struct arch_hw_breakpoint *brk) 411 431 { 412 432 __get_cpu_var(current_brk) = *brk; 433 + 434 + if (cpu_has_feature(CPU_FTR_DAWR)) 435 + return set_dawr(brk); 413 436 414 437 return set_dabr(brk); 415 438 }
+12
arch/powerpc/platforms/pseries/setup.c
··· 65 65 #include <asm/smp.h> 66 66 #include <asm/firmware.h> 67 67 #include <asm/eeh.h> 68 + #include <asm/reg.h> 68 69 69 70 #include "plpar_wrappers.h" 70 71 #include "pseries.h" ··· 501 500 return plpar_hcall_norets(H_SET_XDABR, dabr, dabrx); 502 501 } 503 502 503 + static int pseries_set_dawr(unsigned long dawr, unsigned long dawrx) 504 + { 505 + /* PAPR says we can't set HYP */ 506 + dawrx &= ~DAWRX_HYP; 507 + 508 + return plapr_set_watchpoint0(dawr, dawrx); 509 + } 510 + 504 511 #define CMO_CHARACTERISTICS_TOKEN 44 505 512 #define CMO_MAXLENGTH 1026 506 513 ··· 614 605 ppc_md.set_dabr = pseries_set_xdabr; 615 606 else if (firmware_has_feature(FW_FEATURE_DABR)) 616 607 ppc_md.set_dabr = pseries_set_dabr; 608 + 609 + if (firmware_has_feature(FW_FEATURE_SET_MODE)) 610 + ppc_md.set_dawr = pseries_set_dawr; 617 611 618 612 pSeries_cmo_feature_init(); 619 613 iommu_init_early_pSeries();