1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1996, 97, 2000, 2001 by Ralf Baechle 7 * Copyright (C) 2001 MIPS Technologies, Inc. 8 */ 9 #include <linux/kernel.h> 10 #include <linux/sched.h> 11 #include <linux/signal.h> 12 #include <asm/branch.h> 13 #include <asm/cpu.h> 14 #include <asm/cpu-features.h> 15 #include <asm/fpu.h> 16 #include <asm/inst.h> 17 #include <asm/ptrace.h> 18 #include <asm/uaccess.h> 19 20 /* 21 * Compute the return address and do emulate branch simulation, if required. 22 */ 23 int __compute_return_epc(struct pt_regs *regs) 24 { 25 unsigned int __user *addr; 26 unsigned int bit, fcr31, dspcontrol; 27 long epc; 28 union mips_instruction insn; 29 30 epc = regs->cp0_epc; 31 if (epc & 3) 32 goto unaligned; 33 34 /* 35 * Read the instruction 36 */ 37 addr = (unsigned int __user *) epc; 38 if (__get_user(insn.word, addr)) { 39 force_sig(SIGSEGV, current); 40 return -EFAULT; 41 } 42 43 switch (insn.i_format.opcode) { 44 /* 45 * jr and jalr are in r_format format. 46 */ 47 case spec_op: 48 switch (insn.r_format.func) { 49 case jalr_op: 50 regs->regs[insn.r_format.rd] = epc + 8; 51 /* Fall through */ 52 case jr_op: 53 regs->cp0_epc = regs->regs[insn.r_format.rs]; 54 break; 55 } 56 break; 57 58 /* 59 * This group contains: 60 * bltz_op, bgez_op, bltzl_op, bgezl_op, 61 * bltzal_op, bgezal_op, bltzall_op, bgezall_op. 62 */ 63 case bcond_op: 64 switch (insn.i_format.rt) { 65 case bltz_op: 66 case bltzl_op: 67 if ((long)regs->regs[insn.i_format.rs] < 0) 68 epc = epc + 4 + (insn.i_format.simmediate << 2); 69 else 70 epc += 8; 71 regs->cp0_epc = epc; 72 break; 73 74 case bgez_op: 75 case bgezl_op: 76 if ((long)regs->regs[insn.i_format.rs] >= 0) 77 epc = epc + 4 + (insn.i_format.simmediate << 2); 78 else 79 epc += 8; 80 regs->cp0_epc = epc; 81 break; 82 83 case bltzal_op: 84 case bltzall_op: 85 regs->regs[31] = epc + 8; 86 if ((long)regs->regs[insn.i_format.rs] < 0) 87 epc = epc + 4 + (insn.i_format.simmediate << 2); 88 else 89 epc += 8; 90 regs->cp0_epc = epc; 91 break; 92 93 case bgezal_op: 94 case bgezall_op: 95 regs->regs[31] = epc + 8; 96 if ((long)regs->regs[insn.i_format.rs] >= 0) 97 epc = epc + 4 + (insn.i_format.simmediate << 2); 98 else 99 epc += 8; 100 regs->cp0_epc = epc; 101 break; 102 case bposge32_op: 103 if (!cpu_has_dsp) 104 goto sigill; 105 106 dspcontrol = rddsp(0x01); 107 108 if (dspcontrol >= 32) { 109 epc = epc + 4 + (insn.i_format.simmediate << 2); 110 } else 111 epc += 8; 112 regs->cp0_epc = epc; 113 break; 114 } 115 break; 116 117 /* 118 * These are unconditional and in j_format. 119 */ 120 case jal_op: 121 regs->regs[31] = regs->cp0_epc + 8; 122 case j_op: 123 epc += 4; 124 epc >>= 28; 125 epc <<= 28; 126 epc |= (insn.j_format.target << 2); 127 regs->cp0_epc = epc; 128 break; 129 130 /* 131 * These are conditional and in i_format. 132 */ 133 case beq_op: 134 case beql_op: 135 if (regs->regs[insn.i_format.rs] == 136 regs->regs[insn.i_format.rt]) 137 epc = epc + 4 + (insn.i_format.simmediate << 2); 138 else 139 epc += 8; 140 regs->cp0_epc = epc; 141 break; 142 143 case bne_op: 144 case bnel_op: 145 if (regs->regs[insn.i_format.rs] != 146 regs->regs[insn.i_format.rt]) 147 epc = epc + 4 + (insn.i_format.simmediate << 2); 148 else 149 epc += 8; 150 regs->cp0_epc = epc; 151 break; 152 153 case blez_op: /* not really i_format */ 154 case blezl_op: 155 /* rt field assumed to be zero */ 156 if ((long)regs->regs[insn.i_format.rs] <= 0) 157 epc = epc + 4 + (insn.i_format.simmediate << 2); 158 else 159 epc += 8; 160 regs->cp0_epc = epc; 161 break; 162 163 case bgtz_op: 164 case bgtzl_op: 165 /* rt field assumed to be zero */ 166 if ((long)regs->regs[insn.i_format.rs] > 0) 167 epc = epc + 4 + (insn.i_format.simmediate << 2); 168 else 169 epc += 8; 170 regs->cp0_epc = epc; 171 break; 172 173 /* 174 * And now the FPA/cp1 branch instructions. 175 */ 176 case cop1_op: 177 preempt_disable(); 178 if (is_fpu_owner()) 179 asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); 180 else 181 fcr31 = current->thread.fpu.fcr31; 182 preempt_enable(); 183 184 bit = (insn.i_format.rt >> 2); 185 bit += (bit != 0); 186 bit += 23; 187 switch (insn.i_format.rt & 3) { 188 case 0: /* bc1f */ 189 case 2: /* bc1fl */ 190 if (~fcr31 & (1 << bit)) 191 epc = epc + 4 + (insn.i_format.simmediate << 2); 192 else 193 epc += 8; 194 regs->cp0_epc = epc; 195 break; 196 197 case 1: /* bc1t */ 198 case 3: /* bc1tl */ 199 if (fcr31 & (1 << bit)) 200 epc = epc + 4 + (insn.i_format.simmediate << 2); 201 else 202 epc += 8; 203 regs->cp0_epc = epc; 204 break; 205 } 206 break; 207 #ifdef CONFIG_CPU_CAVIUM_OCTEON 208 case lwc2_op: /* This is bbit0 on Octeon */ 209 if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) 210 == 0) 211 epc = epc + 4 + (insn.i_format.simmediate << 2); 212 else 213 epc += 8; 214 regs->cp0_epc = epc; 215 break; 216 case ldc2_op: /* This is bbit032 on Octeon */ 217 if ((regs->regs[insn.i_format.rs] & 218 (1ull<<(insn.i_format.rt+32))) == 0) 219 epc = epc + 4 + (insn.i_format.simmediate << 2); 220 else 221 epc += 8; 222 regs->cp0_epc = epc; 223 break; 224 case swc2_op: /* This is bbit1 on Octeon */ 225 if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) 226 epc = epc + 4 + (insn.i_format.simmediate << 2); 227 else 228 epc += 8; 229 regs->cp0_epc = epc; 230 break; 231 case sdc2_op: /* This is bbit132 on Octeon */ 232 if (regs->regs[insn.i_format.rs] & 233 (1ull<<(insn.i_format.rt+32))) 234 epc = epc + 4 + (insn.i_format.simmediate << 2); 235 else 236 epc += 8; 237 regs->cp0_epc = epc; 238 break; 239 #endif 240 } 241 242 return 0; 243 244 unaligned: 245 printk("%s: unaligned epc - sending SIGBUS.\n", current->comm); 246 force_sig(SIGBUS, current); 247 return -EFAULT; 248 249 sigill: 250 printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm); 251 force_sig(SIGBUS, current); 252 return -EFAULT; 253 } 254