linux/arch/mips/kernel/branch.c
<<
>>
Prefs
   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/fpu_emulator.h>
  18#include <asm/inst.h>
  19#include <asm/ptrace.h>
  20#include <asm/uaccess.h>
  21
  22/*
  23 * Calculate and return exception PC in case of branch delay slot
  24 * for microMIPS and MIPS16e. It does not clear the ISA mode bit.
  25 */
  26int __isa_exception_epc(struct pt_regs *regs)
  27{
  28        unsigned short inst;
  29        long epc = regs->cp0_epc;
  30
  31        /* Calculate exception PC in branch delay slot. */
  32        if (__get_user(inst, (u16 __user *) msk_isa16_mode(epc))) {
  33                /* This should never happen because delay slot was checked. */
  34                force_sig(SIGSEGV, current);
  35                return epc;
  36        }
  37        if (cpu_has_mips16) {
  38                if (((union mips16e_instruction)inst).ri.opcode
  39                                == MIPS16e_jal_op)
  40                        epc += 4;
  41                else
  42                        epc += 2;
  43        } else if (mm_insn_16bit(inst))
  44                epc += 2;
  45        else
  46                epc += 4;
  47
  48        return epc;
  49}
  50
  51/*
  52 * Compute return address and emulate branch in microMIPS mode after an
  53 * exception only. It does not handle compact branches/jumps and cannot
  54 * be used in interrupt context. (Compact branches/jumps do not cause
  55 * exceptions.)
  56 */
  57int __microMIPS_compute_return_epc(struct pt_regs *regs)
  58{
  59        u16 __user *pc16;
  60        u16 halfword;
  61        unsigned int word;
  62        unsigned long contpc;
  63        struct mm_decoded_insn mminsn = { 0 };
  64
  65        mminsn.micro_mips_mode = 1;
  66
  67        /* This load never faults. */
  68        pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc);
  69        __get_user(halfword, pc16);
  70        pc16++;
  71        contpc = regs->cp0_epc + 2;
  72        word = ((unsigned int)halfword << 16);
  73        mminsn.pc_inc = 2;
  74
  75        if (!mm_insn_16bit(halfword)) {
  76                __get_user(halfword, pc16);
  77                pc16++;
  78                contpc = regs->cp0_epc + 4;
  79                mminsn.pc_inc = 4;
  80                word |= halfword;
  81        }
  82        mminsn.insn = word;
  83
  84        if (get_user(halfword, pc16))
  85                goto sigsegv;
  86        mminsn.next_pc_inc = 2;
  87        word = ((unsigned int)halfword << 16);
  88
  89        if (!mm_insn_16bit(halfword)) {
  90                pc16++;
  91                if (get_user(halfword, pc16))
  92                        goto sigsegv;
  93                mminsn.next_pc_inc = 4;
  94                word |= halfword;
  95        }
  96        mminsn.next_insn = word;
  97
  98        mm_isBranchInstr(regs, mminsn, &contpc);
  99
 100        regs->cp0_epc = contpc;
 101
 102        return 0;
 103
 104sigsegv:
 105        force_sig(SIGSEGV, current);
 106        return -EFAULT;
 107}
 108
 109/*
 110 * Compute return address and emulate branch in MIPS16e mode after an
 111 * exception only. It does not handle compact branches/jumps and cannot
 112 * be used in interrupt context. (Compact branches/jumps do not cause
 113 * exceptions.)
 114 */
 115int __MIPS16e_compute_return_epc(struct pt_regs *regs)
 116{
 117        u16 __user *addr;
 118        union mips16e_instruction inst;
 119        u16 inst2;
 120        u32 fullinst;
 121        long epc;
 122
 123        epc = regs->cp0_epc;
 124
 125        /* Read the instruction. */
 126        addr = (u16 __user *)msk_isa16_mode(epc);
 127        if (__get_user(inst.full, addr)) {
 128                force_sig(SIGSEGV, current);
 129                return -EFAULT;
 130        }
 131
 132        switch (inst.ri.opcode) {
 133        case MIPS16e_extend_op:
 134                regs->cp0_epc += 4;
 135                return 0;
 136
 137                /*
 138                 *  JAL and JALX in MIPS16e mode
 139                 */
 140        case MIPS16e_jal_op:
 141                addr += 1;
 142                if (__get_user(inst2, addr)) {
 143                        force_sig(SIGSEGV, current);
 144                        return -EFAULT;
 145                }
 146                fullinst = ((unsigned)inst.full << 16) | inst2;
 147                regs->regs[31] = epc + 6;
 148                epc += 4;
 149                epc >>= 28;
 150                epc <<= 28;
 151                /*
 152                 * JAL:5 X:1 TARGET[20-16]:5 TARGET[25:21]:5 TARGET[15:0]:16
 153                 *
 154                 * ......TARGET[15:0].................TARGET[20:16]...........
 155                 * ......TARGET[25:21]
 156                 */
 157                epc |=
 158                    ((fullinst & 0xffff) << 2) | ((fullinst & 0x3e00000) >> 3) |
 159                    ((fullinst & 0x1f0000) << 7);
 160                if (!inst.jal.x)
 161                        set_isa16_mode(epc);    /* Set ISA mode bit. */
 162                regs->cp0_epc = epc;
 163                return 0;
 164
 165                /*
 166                 *  J(AL)R(C)
 167                 */
 168        case MIPS16e_rr_op:
 169                if (inst.rr.func == MIPS16e_jr_func) {
 170
 171                        if (inst.rr.ra)
 172                                regs->cp0_epc = regs->regs[31];
 173                        else
 174                                regs->cp0_epc =
 175                                    regs->regs[reg16to32[inst.rr.rx]];
 176
 177                        if (inst.rr.l) {
 178                                if (inst.rr.nd)
 179                                        regs->regs[31] = epc + 2;
 180                                else
 181                                        regs->regs[31] = epc + 4;
 182                        }
 183                        return 0;
 184                }
 185                break;
 186        }
 187
 188        /*
 189         * All other cases have no branch delay slot and are 16-bits.
 190         * Branches do not cause an exception.
 191         */
 192        regs->cp0_epc += 2;
 193
 194        return 0;
 195}
 196
 197/**
 198 * __compute_return_epc_for_insn - Computes the return address and do emulate
 199 *                                  branch simulation, if required.
 200 *
 201 * @regs:       Pointer to pt_regs
 202 * @insn:       branch instruction to decode
 203 * @returns:    -EFAULT on error and forces SIGBUS, and on success
 204 *              returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
 205 *              evaluating the branch.
 206 */
 207int __compute_return_epc_for_insn(struct pt_regs *regs,
 208                                   union mips_instruction insn)
 209{
 210        unsigned int bit, fcr31, dspcontrol;
 211        long epc = regs->cp0_epc;
 212        int ret = 0;
 213
 214        switch (insn.i_format.opcode) {
 215        /*
 216         * jr and jalr are in r_format format.
 217         */
 218        case spec_op:
 219                switch (insn.r_format.func) {
 220                case jalr_op:
 221                        regs->regs[insn.r_format.rd] = epc + 8;
 222                        /* Fall through */
 223                case jr_op:
 224                        regs->cp0_epc = regs->regs[insn.r_format.rs];
 225                        break;
 226                }
 227                break;
 228
 229        /*
 230         * This group contains:
 231         * bltz_op, bgez_op, bltzl_op, bgezl_op,
 232         * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
 233         */
 234        case bcond_op:
 235                switch (insn.i_format.rt) {
 236                case bltz_op:
 237                case bltzl_op:
 238                        if ((long)regs->regs[insn.i_format.rs] < 0) {
 239                                epc = epc + 4 + (insn.i_format.simmediate << 2);
 240                                if (insn.i_format.rt == bltzl_op)
 241                                        ret = BRANCH_LIKELY_TAKEN;
 242                        } else
 243                                epc += 8;
 244                        regs->cp0_epc = epc;
 245                        break;
 246
 247                case bgez_op:
 248                case bgezl_op:
 249                        if ((long)regs->regs[insn.i_format.rs] >= 0) {
 250                                epc = epc + 4 + (insn.i_format.simmediate << 2);
 251                                if (insn.i_format.rt == bgezl_op)
 252                                        ret = BRANCH_LIKELY_TAKEN;
 253                        } else
 254                                epc += 8;
 255                        regs->cp0_epc = epc;
 256                        break;
 257
 258                case bltzal_op:
 259                case bltzall_op:
 260                        regs->regs[31] = epc + 8;
 261                        if ((long)regs->regs[insn.i_format.rs] < 0) {
 262                                epc = epc + 4 + (insn.i_format.simmediate << 2);
 263                                if (insn.i_format.rt == bltzall_op)
 264                                        ret = BRANCH_LIKELY_TAKEN;
 265                        } else
 266                                epc += 8;
 267                        regs->cp0_epc = epc;
 268                        break;
 269
 270                case bgezal_op:
 271                case bgezall_op:
 272                        regs->regs[31] = epc + 8;
 273                        if ((long)regs->regs[insn.i_format.rs] >= 0) {
 274                                epc = epc + 4 + (insn.i_format.simmediate << 2);
 275                                if (insn.i_format.rt == bgezall_op)
 276                                        ret = BRANCH_LIKELY_TAKEN;
 277                        } else
 278                                epc += 8;
 279                        regs->cp0_epc = epc;
 280                        break;
 281
 282                case bposge32_op:
 283                        if (!cpu_has_dsp)
 284                                goto sigill;
 285
 286                        dspcontrol = rddsp(0x01);
 287
 288                        if (dspcontrol >= 32) {
 289                                epc = epc + 4 + (insn.i_format.simmediate << 2);
 290                        } else
 291                                epc += 8;
 292                        regs->cp0_epc = epc;
 293                        break;
 294                }
 295                break;
 296
 297        /*
 298         * These are unconditional and in j_format.
 299         */
 300        case jal_op:
 301                regs->regs[31] = regs->cp0_epc + 8;
 302        case j_op:
 303                epc += 4;
 304                epc >>= 28;
 305                epc <<= 28;
 306                epc |= (insn.j_format.target << 2);
 307                regs->cp0_epc = epc;
 308                if (insn.i_format.opcode == jalx_op)
 309                        set_isa16_mode(regs->cp0_epc);
 310                break;
 311
 312        /*
 313         * These are conditional and in i_format.
 314         */
 315        case beq_op:
 316        case beql_op:
 317                if (regs->regs[insn.i_format.rs] ==
 318                    regs->regs[insn.i_format.rt]) {
 319                        epc = epc + 4 + (insn.i_format.simmediate << 2);
 320                        if (insn.i_format.rt == beql_op)
 321                                ret = BRANCH_LIKELY_TAKEN;
 322                } else
 323                        epc += 8;
 324                regs->cp0_epc = epc;
 325                break;
 326
 327        case bne_op:
 328        case bnel_op:
 329                if (regs->regs[insn.i_format.rs] !=
 330                    regs->regs[insn.i_format.rt]) {
 331                        epc = epc + 4 + (insn.i_format.simmediate << 2);
 332                        if (insn.i_format.rt == bnel_op)
 333                                ret = BRANCH_LIKELY_TAKEN;
 334                } else
 335                        epc += 8;
 336                regs->cp0_epc = epc;
 337                break;
 338
 339        case blez_op: /* not really i_format */
 340        case blezl_op:
 341                /* rt field assumed to be zero */
 342                if ((long)regs->regs[insn.i_format.rs] <= 0) {
 343                        epc = epc + 4 + (insn.i_format.simmediate << 2);
 344                        if (insn.i_format.rt == bnel_op)
 345                                ret = BRANCH_LIKELY_TAKEN;
 346                } else
 347                        epc += 8;
 348                regs->cp0_epc = epc;
 349                break;
 350
 351        case bgtz_op:
 352        case bgtzl_op:
 353                /* rt field assumed to be zero */
 354                if ((long)regs->regs[insn.i_format.rs] > 0) {
 355                        epc = epc + 4 + (insn.i_format.simmediate << 2);
 356                        if (insn.i_format.rt == bnel_op)
 357                                ret = BRANCH_LIKELY_TAKEN;
 358                } else
 359                        epc += 8;
 360                regs->cp0_epc = epc;
 361                break;
 362
 363        /*
 364         * And now the FPA/cp1 branch instructions.
 365         */
 366        case cop1_op:
 367                preempt_disable();
 368                if (is_fpu_owner())
 369                        asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
 370                else
 371                        fcr31 = current->thread.fpu.fcr31;
 372                preempt_enable();
 373
 374                bit = (insn.i_format.rt >> 2);
 375                bit += (bit != 0);
 376                bit += 23;
 377                switch (insn.i_format.rt & 3) {
 378                case 0: /* bc1f */
 379                case 2: /* bc1fl */
 380                        if (~fcr31 & (1 << bit)) {
 381                                epc = epc + 4 + (insn.i_format.simmediate << 2);
 382                                if (insn.i_format.rt == 2)
 383                                        ret = BRANCH_LIKELY_TAKEN;
 384                        } else
 385                                epc += 8;
 386                        regs->cp0_epc = epc;
 387                        break;
 388
 389                case 1: /* bc1t */
 390                case 3: /* bc1tl */
 391                        if (fcr31 & (1 << bit)) {
 392                                epc = epc + 4 + (insn.i_format.simmediate << 2);
 393                                if (insn.i_format.rt == 3)
 394                                        ret = BRANCH_LIKELY_TAKEN;
 395                        } else
 396                                epc += 8;
 397                        regs->cp0_epc = epc;
 398                        break;
 399                }
 400                break;
 401#ifdef CONFIG_CPU_CAVIUM_OCTEON
 402        case lwc2_op: /* This is bbit0 on Octeon */
 403                if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
 404                     == 0)
 405                        epc = epc + 4 + (insn.i_format.simmediate << 2);
 406                else
 407                        epc += 8;
 408                regs->cp0_epc = epc;
 409                break;
 410        case ldc2_op: /* This is bbit032 on Octeon */
 411                if ((regs->regs[insn.i_format.rs] &
 412                    (1ull<<(insn.i_format.rt+32))) == 0)
 413                        epc = epc + 4 + (insn.i_format.simmediate << 2);
 414                else
 415                        epc += 8;
 416                regs->cp0_epc = epc;
 417                break;
 418        case swc2_op: /* This is bbit1 on Octeon */
 419                if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
 420                        epc = epc + 4 + (insn.i_format.simmediate << 2);
 421                else
 422                        epc += 8;
 423                regs->cp0_epc = epc;
 424                break;
 425        case sdc2_op: /* This is bbit132 on Octeon */
 426                if (regs->regs[insn.i_format.rs] &
 427                    (1ull<<(insn.i_format.rt+32)))
 428                        epc = epc + 4 + (insn.i_format.simmediate << 2);
 429                else
 430                        epc += 8;
 431                regs->cp0_epc = epc;
 432                break;
 433#endif
 434        }
 435
 436        return ret;
 437
 438sigill:
 439        printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
 440        force_sig(SIGBUS, current);
 441        return -EFAULT;
 442}
 443EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn);
 444
 445int __compute_return_epc(struct pt_regs *regs)
 446{
 447        unsigned int __user *addr;
 448        long epc;
 449        union mips_instruction insn;
 450
 451        epc = regs->cp0_epc;
 452        if (epc & 3)
 453                goto unaligned;
 454
 455        /*
 456         * Read the instruction
 457         */
 458        addr = (unsigned int __user *) epc;
 459        if (__get_user(insn.word, addr)) {
 460                force_sig(SIGSEGV, current);
 461                return -EFAULT;
 462        }
 463
 464        return __compute_return_epc_for_insn(regs, insn);
 465
 466unaligned:
 467        printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
 468        force_sig(SIGBUS, current);
 469        return -EFAULT;
 470
 471}
 472