|
@@ -51,6 +51,12 @@
|
|
|
#include <asm/paca.h>
|
|
|
#endif
|
|
|
|
|
|
+#if defined(CONFIG_PPC_SPLPAR)
|
|
|
+#include <asm/plpar_wrappers.h>
|
|
|
+#else
|
|
|
+static inline long plapr_set_ciabr(unsigned long ciabr) {return 0; };
|
|
|
+#endif
|
|
|
+
|
|
|
#include "nonstdio.h"
|
|
|
#include "dis-asm.h"
|
|
|
|
|
@@ -270,6 +276,45 @@ static inline void cinval(void *p)
|
|
|
asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * write_ciabr() - write the CIABR SPR
|
|
|
+ * @ciabr: The value to write.
|
|
|
+ *
|
|
|
+ * This function writes a value to the CIARB register either directly
|
|
|
+ * through mtspr instruction if the kernel is in HV privilege mode or
|
|
|
+ * call a hypervisor function to achieve the same in case the kernel
|
|
|
+ * is in supervisor privilege mode.
|
|
|
+ */
|
|
|
+static void write_ciabr(unsigned long ciabr)
|
|
|
+{
|
|
|
+ if (!cpu_has_feature(CPU_FTR_ARCH_207S))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (cpu_has_feature(CPU_FTR_HVMODE)) {
|
|
|
+ mtspr(SPRN_CIABR, ciabr);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ plapr_set_ciabr(ciabr);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * set_ciabr() - set the CIABR
|
|
|
+ * @addr: The value to set.
|
|
|
+ *
|
|
|
+ * This function sets the correct privilege value into the the HW
|
|
|
+ * breakpoint address before writing it up in the CIABR register.
|
|
|
+ */
|
|
|
+static void set_ciabr(unsigned long addr)
|
|
|
+{
|
|
|
+ addr &= ~CIABR_PRIV;
|
|
|
+
|
|
|
+ if (cpu_has_feature(CPU_FTR_HVMODE))
|
|
|
+ addr |= CIABR_PRIV_HYPER;
|
|
|
+ else
|
|
|
+ addr |= CIABR_PRIV_SUPER;
|
|
|
+ write_ciabr(addr);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Disable surveillance (the service processor watchdog function)
|
|
|
* while we are in xmon.
|
|
@@ -764,9 +809,9 @@ static void insert_cpu_bpts(void)
|
|
|
brk.len = 8;
|
|
|
__set_breakpoint(&brk);
|
|
|
}
|
|
|
- if (iabr && cpu_has_feature(CPU_FTR_IABR))
|
|
|
- mtspr(SPRN_IABR, iabr->address
|
|
|
- | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
|
|
|
+
|
|
|
+ if (iabr)
|
|
|
+ set_ciabr(iabr->address);
|
|
|
}
|
|
|
|
|
|
static void remove_bpts(void)
|
|
@@ -792,8 +837,7 @@ static void remove_bpts(void)
|
|
|
static void remove_cpu_bpts(void)
|
|
|
{
|
|
|
hw_breakpoint_disable();
|
|
|
- if (cpu_has_feature(CPU_FTR_IABR))
|
|
|
- mtspr(SPRN_IABR, 0);
|
|
|
+ write_ciabr(0);
|
|
|
}
|
|
|
|
|
|
/* Command interpreting routine */
|
|
@@ -1128,7 +1172,7 @@ static char *breakpoint_help_string =
|
|
|
"b <addr> [cnt] set breakpoint at given instr addr\n"
|
|
|
"bc clear all breakpoints\n"
|
|
|
"bc <n/addr> clear breakpoint number n or at addr\n"
|
|
|
- "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
|
|
|
+ "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
|
|
|
"bd <addr> [cnt] set hardware data breakpoint\n"
|
|
|
"";
|
|
|
|
|
@@ -1167,7 +1211,7 @@ bpt_cmds(void)
|
|
|
break;
|
|
|
|
|
|
case 'i': /* bi - hardware instr breakpoint */
|
|
|
- if (!cpu_has_feature(CPU_FTR_IABR)) {
|
|
|
+ if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
|
|
|
printf("Hardware instruction breakpoint "
|
|
|
"not supported on this cpu\n");
|
|
|
break;
|