diff options
Diffstat (limited to 'arch/powerpc/xmon/xmon.c')
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index c8efbb37d6e0..5b150f0c5df9 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -51,6 +51,12 @@ | |||
51 | #include <asm/paca.h> | 51 | #include <asm/paca.h> |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #if defined(CONFIG_PPC_SPLPAR) | ||
55 | #include <asm/plpar_wrappers.h> | ||
56 | #else | ||
57 | static inline long plapr_set_ciabr(unsigned long ciabr) {return 0; }; | ||
58 | #endif | ||
59 | |||
54 | #include "nonstdio.h" | 60 | #include "nonstdio.h" |
55 | #include "dis-asm.h" | 61 | #include "dis-asm.h" |
56 | 62 | ||
@@ -88,10 +94,9 @@ struct bpt { | |||
88 | }; | 94 | }; |
89 | 95 | ||
90 | /* Bits in bpt.enabled */ | 96 | /* Bits in bpt.enabled */ |
91 | #define BP_IABR_TE 1 /* IABR translation enabled */ | 97 | #define BP_CIABR 1 |
92 | #define BP_IABR 2 | 98 | #define BP_TRAP 2 |
93 | #define BP_TRAP 8 | 99 | #define BP_DABR 4 |
94 | #define BP_DABR 0x10 | ||
95 | 100 | ||
96 | #define NBPTS 256 | 101 | #define NBPTS 256 |
97 | static struct bpt bpts[NBPTS]; | 102 | static struct bpt bpts[NBPTS]; |
@@ -270,6 +275,45 @@ static inline void cinval(void *p) | |||
270 | asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); | 275 | asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); |
271 | } | 276 | } |
272 | 277 | ||
278 | /** | ||
279 | * write_ciabr() - write the CIABR SPR | ||
280 | * @ciabr: The value to write. | ||
281 | * | ||
282 | * This function writes a value to the CIARB register either directly | ||
283 | * through mtspr instruction if the kernel is in HV privilege mode or | ||
284 | * call a hypervisor function to achieve the same in case the kernel | ||
285 | * is in supervisor privilege mode. | ||
286 | */ | ||
287 | static void write_ciabr(unsigned long ciabr) | ||
288 | { | ||
289 | if (!cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
290 | return; | ||
291 | |||
292 | if (cpu_has_feature(CPU_FTR_HVMODE)) { | ||
293 | mtspr(SPRN_CIABR, ciabr); | ||
294 | return; | ||
295 | } | ||
296 | plapr_set_ciabr(ciabr); | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * set_ciabr() - set the CIABR | ||
301 | * @addr: The value to set. | ||
302 | * | ||
303 | * This function sets the correct privilege value into the the HW | ||
304 | * breakpoint address before writing it up in the CIABR register. | ||
305 | */ | ||
306 | static void set_ciabr(unsigned long addr) | ||
307 | { | ||
308 | addr &= ~CIABR_PRIV; | ||
309 | |||
310 | if (cpu_has_feature(CPU_FTR_HVMODE)) | ||
311 | addr |= CIABR_PRIV_HYPER; | ||
312 | else | ||
313 | addr |= CIABR_PRIV_SUPER; | ||
314 | write_ciabr(addr); | ||
315 | } | ||
316 | |||
273 | /* | 317 | /* |
274 | * Disable surveillance (the service processor watchdog function) | 318 | * Disable surveillance (the service processor watchdog function) |
275 | * while we are in xmon. | 319 | * while we are in xmon. |
@@ -727,7 +771,7 @@ static void insert_bpts(void) | |||
727 | 771 | ||
728 | bp = bpts; | 772 | bp = bpts; |
729 | for (i = 0; i < NBPTS; ++i, ++bp) { | 773 | for (i = 0; i < NBPTS; ++i, ++bp) { |
730 | if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0) | 774 | if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0) |
731 | continue; | 775 | continue; |
732 | if (mread(bp->address, &bp->instr[0], 4) != 4) { | 776 | if (mread(bp->address, &bp->instr[0], 4) != 4) { |
733 | printf("Couldn't read instruction at %lx, " | 777 | printf("Couldn't read instruction at %lx, " |
@@ -742,7 +786,7 @@ static void insert_bpts(void) | |||
742 | continue; | 786 | continue; |
743 | } | 787 | } |
744 | store_inst(&bp->instr[0]); | 788 | store_inst(&bp->instr[0]); |
745 | if (bp->enabled & BP_IABR) | 789 | if (bp->enabled & BP_CIABR) |
746 | continue; | 790 | continue; |
747 | if (mwrite(bp->address, &bpinstr, 4) != 4) { | 791 | if (mwrite(bp->address, &bpinstr, 4) != 4) { |
748 | printf("Couldn't write instruction at %lx, " | 792 | printf("Couldn't write instruction at %lx, " |
@@ -764,9 +808,9 @@ static void insert_cpu_bpts(void) | |||
764 | brk.len = 8; | 808 | brk.len = 8; |
765 | __set_breakpoint(&brk); | 809 | __set_breakpoint(&brk); |
766 | } | 810 | } |
767 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) | 811 | |
768 | mtspr(SPRN_IABR, iabr->address | 812 | if (iabr) |
769 | | (iabr->enabled & (BP_IABR|BP_IABR_TE))); | 813 | set_ciabr(iabr->address); |
770 | } | 814 | } |
771 | 815 | ||
772 | static void remove_bpts(void) | 816 | static void remove_bpts(void) |
@@ -777,7 +821,7 @@ static void remove_bpts(void) | |||
777 | 821 | ||
778 | bp = bpts; | 822 | bp = bpts; |
779 | for (i = 0; i < NBPTS; ++i, ++bp) { | 823 | for (i = 0; i < NBPTS; ++i, ++bp) { |
780 | if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP) | 824 | if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP) |
781 | continue; | 825 | continue; |
782 | if (mread(bp->address, &instr, 4) == 4 | 826 | if (mread(bp->address, &instr, 4) == 4 |
783 | && instr == bpinstr | 827 | && instr == bpinstr |
@@ -792,8 +836,7 @@ static void remove_bpts(void) | |||
792 | static void remove_cpu_bpts(void) | 836 | static void remove_cpu_bpts(void) |
793 | { | 837 | { |
794 | hw_breakpoint_disable(); | 838 | hw_breakpoint_disable(); |
795 | if (cpu_has_feature(CPU_FTR_IABR)) | 839 | write_ciabr(0); |
796 | mtspr(SPRN_IABR, 0); | ||
797 | } | 840 | } |
798 | 841 | ||
799 | /* Command interpreting routine */ | 842 | /* Command interpreting routine */ |
@@ -907,7 +950,7 @@ cmds(struct pt_regs *excp) | |||
907 | case 'u': | 950 | case 'u': |
908 | dump_segments(); | 951 | dump_segments(); |
909 | break; | 952 | break; |
910 | #elif defined(CONFIG_4xx) | 953 | #elif defined(CONFIG_44x) |
911 | case 'u': | 954 | case 'u': |
912 | dump_tlb_44x(); | 955 | dump_tlb_44x(); |
913 | break; | 956 | break; |
@@ -981,7 +1024,8 @@ static void bootcmds(void) | |||
981 | else if (cmd == 'h') | 1024 | else if (cmd == 'h') |
982 | ppc_md.halt(); | 1025 | ppc_md.halt(); |
983 | else if (cmd == 'p') | 1026 | else if (cmd == 'p') |
984 | ppc_md.power_off(); | 1027 | if (pm_power_off) |
1028 | pm_power_off(); | ||
985 | } | 1029 | } |
986 | 1030 | ||
987 | static int cpu_cmd(void) | 1031 | static int cpu_cmd(void) |
@@ -1127,7 +1171,7 @@ static char *breakpoint_help_string = | |||
1127 | "b <addr> [cnt] set breakpoint at given instr addr\n" | 1171 | "b <addr> [cnt] set breakpoint at given instr addr\n" |
1128 | "bc clear all breakpoints\n" | 1172 | "bc clear all breakpoints\n" |
1129 | "bc <n/addr> clear breakpoint number n or at addr\n" | 1173 | "bc <n/addr> clear breakpoint number n or at addr\n" |
1130 | "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n" | 1174 | "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n" |
1131 | "bd <addr> [cnt] set hardware data breakpoint\n" | 1175 | "bd <addr> [cnt] set hardware data breakpoint\n" |
1132 | ""; | 1176 | ""; |
1133 | 1177 | ||
@@ -1166,13 +1210,13 @@ bpt_cmds(void) | |||
1166 | break; | 1210 | break; |
1167 | 1211 | ||
1168 | case 'i': /* bi - hardware instr breakpoint */ | 1212 | case 'i': /* bi - hardware instr breakpoint */ |
1169 | if (!cpu_has_feature(CPU_FTR_IABR)) { | 1213 | if (!cpu_has_feature(CPU_FTR_ARCH_207S)) { |
1170 | printf("Hardware instruction breakpoint " | 1214 | printf("Hardware instruction breakpoint " |
1171 | "not supported on this cpu\n"); | 1215 | "not supported on this cpu\n"); |
1172 | break; | 1216 | break; |
1173 | } | 1217 | } |
1174 | if (iabr) { | 1218 | if (iabr) { |
1175 | iabr->enabled &= ~(BP_IABR | BP_IABR_TE); | 1219 | iabr->enabled &= ~BP_CIABR; |
1176 | iabr = NULL; | 1220 | iabr = NULL; |
1177 | } | 1221 | } |
1178 | if (!scanhex(&a)) | 1222 | if (!scanhex(&a)) |
@@ -1181,7 +1225,7 @@ bpt_cmds(void) | |||
1181 | break; | 1225 | break; |
1182 | bp = new_breakpoint(a); | 1226 | bp = new_breakpoint(a); |
1183 | if (bp != NULL) { | 1227 | if (bp != NULL) { |
1184 | bp->enabled |= BP_IABR | BP_IABR_TE; | 1228 | bp->enabled |= BP_CIABR; |
1185 | iabr = bp; | 1229 | iabr = bp; |
1186 | } | 1230 | } |
1187 | break; | 1231 | break; |
@@ -1238,7 +1282,7 @@ bpt_cmds(void) | |||
1238 | if (!bp->enabled) | 1282 | if (!bp->enabled) |
1239 | continue; | 1283 | continue; |
1240 | printf("%2x %s ", BP_NUM(bp), | 1284 | printf("%2x %s ", BP_NUM(bp), |
1241 | (bp->enabled & BP_IABR)? "inst": "trap"); | 1285 | (bp->enabled & BP_CIABR) ? "inst": "trap"); |
1242 | xmon_print_symbol(bp->address, " ", "\n"); | 1286 | xmon_print_symbol(bp->address, " ", "\n"); |
1243 | } | 1287 | } |
1244 | break; | 1288 | break; |