diff options
| -rw-r--r-- | arch/powerpc/lib/sstep.c | 17 | ||||
| -rw-r--r-- | include/asm-powerpc/reg.h | 8 | ||||
| -rw-r--r-- | include/asm-powerpc/sstep.h (renamed from include/asm-ppc64/sstep.h) | 4 |
3 files changed, 28 insertions, 1 deletions
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index e79123d1485c..666c2aa55016 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c | |||
| @@ -10,13 +10,18 @@ | |||
| 10 | */ | 10 | */ |
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/ptrace.h> | 12 | #include <linux/ptrace.h> |
| 13 | #include <linux/config.h> | ||
| 13 | #include <asm/sstep.h> | 14 | #include <asm/sstep.h> |
| 14 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
| 15 | 16 | ||
| 16 | extern char system_call_common[]; | 17 | extern char system_call_common[]; |
| 17 | 18 | ||
| 19 | #ifdef CONFIG_PPC64 | ||
| 18 | /* Bits in SRR1 that are copied from MSR */ | 20 | /* Bits in SRR1 that are copied from MSR */ |
| 19 | #define MSR_MASK 0xffffffff87c0ffff | 21 | #define MSR_MASK 0xffffffff87c0ffff |
| 22 | #else | ||
| 23 | #define MSR_MASK 0x87c0ffff | ||
| 24 | #endif | ||
| 20 | 25 | ||
| 21 | /* | 26 | /* |
| 22 | * Determine whether a conditional branch instruction would branch. | 27 | * Determine whether a conditional branch instruction would branch. |
| @@ -66,6 +71,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 66 | if (branch_taken(instr, regs)) | 71 | if (branch_taken(instr, regs)) |
| 67 | regs->nip = imm; | 72 | regs->nip = imm; |
| 68 | return 1; | 73 | return 1; |
| 74 | #ifdef CONFIG_PPC64 | ||
| 69 | case 17: /* sc */ | 75 | case 17: /* sc */ |
| 70 | /* | 76 | /* |
| 71 | * N.B. this uses knowledge about how the syscall | 77 | * N.B. this uses knowledge about how the syscall |
| @@ -79,6 +85,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 79 | regs->nip = (unsigned long) &system_call_common; | 85 | regs->nip = (unsigned long) &system_call_common; |
| 80 | regs->msr = MSR_KERNEL; | 86 | regs->msr = MSR_KERNEL; |
| 81 | return 1; | 87 | return 1; |
| 88 | #endif | ||
| 82 | case 18: /* b */ | 89 | case 18: /* b */ |
| 83 | imm = instr & 0x03fffffc; | 90 | imm = instr & 0x03fffffc; |
| 84 | if (imm & 0x02000000) | 91 | if (imm & 0x02000000) |
| @@ -121,6 +128,15 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 121 | if ((regs->msr & MSR_SF) == 0) | 128 | if ((regs->msr & MSR_SF) == 0) |
| 122 | regs->nip &= 0xffffffffUL; | 129 | regs->nip &= 0xffffffffUL; |
| 123 | return 1; | 130 | return 1; |
| 131 | case 0x124: /* mtmsr */ | ||
| 132 | imm = regs->gpr[rd]; | ||
| 133 | if ((imm & MSR_RI) == 0) | ||
| 134 | /* can't step mtmsr that would clear MSR_RI */ | ||
| 135 | return -1; | ||
| 136 | regs->msr = imm; | ||
| 137 | regs->nip += 4; | ||
| 138 | return 1; | ||
| 139 | #ifdef CONFIG_PPC64 | ||
| 124 | case 0x164: /* mtmsrd */ | 140 | case 0x164: /* mtmsrd */ |
| 125 | /* only MSR_EE and MSR_RI get changed if bit 15 set */ | 141 | /* only MSR_EE and MSR_RI get changed if bit 15 set */ |
| 126 | /* mtmsrd doesn't change MSR_HV and MSR_ME */ | 142 | /* mtmsrd doesn't change MSR_HV and MSR_ME */ |
| @@ -135,6 +151,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 135 | if ((imm & MSR_SF) == 0) | 151 | if ((imm & MSR_SF) == 0) |
| 136 | regs->nip &= 0xffffffffUL; | 152 | regs->nip &= 0xffffffffUL; |
| 137 | return 1; | 153 | return 1; |
| 154 | #endif | ||
| 138 | } | 155 | } |
| 139 | } | 156 | } |
| 140 | return 0; | 157 | return 0; |
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index 68058d72d8da..bfb45a4523d3 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h | |||
| @@ -51,9 +51,17 @@ | |||
| 51 | #define __MASK(X) (1UL<<(X)) | 51 | #define __MASK(X) (1UL<<(X)) |
| 52 | #endif | 52 | #endif |
| 53 | 53 | ||
| 54 | #ifdef CONFIG_PPC64 | ||
| 54 | #define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */ | 55 | #define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */ |
| 55 | #define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */ | 56 | #define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */ |
| 56 | #define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */ | 57 | #define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */ |
| 58 | #else | ||
| 59 | /* so tests for these bits fail on 32-bit */ | ||
| 60 | #define MSR_SF 0 | ||
| 61 | #define MSR_ISF 0 | ||
| 62 | #define MSR_HV 0 | ||
| 63 | #endif | ||
| 64 | |||
| 57 | #define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ | 65 | #define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ |
| 58 | #define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ | 66 | #define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ |
| 59 | #define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */ | 67 | #define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */ |
diff --git a/include/asm-ppc64/sstep.h b/include/asm-powerpc/sstep.h index 4a68db50ee6f..630a9889c07c 100644 --- a/include/asm-ppc64/sstep.h +++ b/include/asm-powerpc/sstep.h | |||
| @@ -16,8 +16,10 @@ struct pt_regs; | |||
| 16 | * we don't allow putting a breakpoint on an mtmsrd instruction. | 16 | * we don't allow putting a breakpoint on an mtmsrd instruction. |
| 17 | * Similarly we don't allow breakpoints on rfid instructions. | 17 | * Similarly we don't allow breakpoints on rfid instructions. |
| 18 | * These macros tell us if an instruction is a mtmsrd or rfid. | 18 | * These macros tell us if an instruction is a mtmsrd or rfid. |
| 19 | * Note that IS_MTMSRD returns true for both an mtmsr (32-bit) | ||
| 20 | * and an mtmsrd (64-bit). | ||
| 19 | */ | 21 | */ |
| 20 | #define IS_MTMSRD(instr) (((instr) & 0xfc0007fe) == 0x7c000164) | 22 | #define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124) |
| 21 | #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024) | 23 | #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024) |
| 22 | 24 | ||
| 23 | /* Emulate instructions that cause a transfer of control. */ | 25 | /* Emulate instructions that cause a transfer of control. */ |
