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