diff options
Diffstat (limited to 'arch/powerpc/lib/sstep.c')
-rw-r--r-- | arch/powerpc/lib/sstep.c | 17 |
1 files changed, 17 insertions, 0 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; |