/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2014 Lemote Corporation. * written by Huacai Chen <chenhc@lemote.com> * * based on arch/mips/cavium-octeon/cpu.c * Copyright (C) 2009 Wind River Systems, * written by Ralf Baechle <ralf@linux-mips.org>
*/ #include <linux/init.h> #include <linux/sched.h> #include <linux/notifier.h> #include <linux/ptrace.h> #include <linux/uaccess.h> #include <linux/sched/signal.h>
case CU2_SDC2_OP: switch (insn.loongson3_lsdc2_format.opcode1) { /* * Loongson-3 overridden sdc2 instructions. * opcode1 instruction * 0x1 gsshx: store 2 bytes from GPR * 0x2 gsswx: store 4 bytes from GPR * 0x3 gssdx: store 8 bytes from GPR * 0x6 gsswxc1: store 4 bytes from FPR * 0x7 gssdxc1: store 8 bytes from FPR
*/ case 0x1: if (!access_ok(addr, 2)) goto sigbus;
compute_return_epc(regs);
value = regs->regs[insn.loongson3_lsdc2_format.rt];
StoreHW(addr, value, res); if (res) goto fault;
break; case 0x2: if (!access_ok(addr, 4)) goto sigbus;
compute_return_epc(regs);
value = regs->regs[insn.loongson3_lsdc2_format.rt];
StoreW(addr, value, res); if (res) goto fault;
break; case 0x3: if (!access_ok(addr, 8)) goto sigbus;
compute_return_epc(regs);
value = regs->regs[insn.loongson3_lsdc2_format.rt];
StoreDW(addr, value, res); if (res) goto fault;
break;
case 0x6:
die_if_kernel("Unaligned FP access in kernel code", regs);
BUG_ON(!used_math());
if (!access_ok(addr, 4)) goto sigbus;
lose_fpu(1);
value = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0);
StoreW(addr, value, res); if (res) goto fault;
compute_return_epc(regs);
own_fpu(1);
break; case 0x7:
die_if_kernel("Unaligned FP access in kernel code", regs);
BUG_ON(!used_math());
if (!access_ok(addr, 8)) goto sigbus;
lose_fpu(1);
value = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0);
return NOTIFY_OK; /* Let default notifier send signals */
fault: /* roll back jump/branch */
regs->regs[31] = ra;
regs->cp0_epc = (unsignedlong)pc; /* Did we have an exception handler installed? */ if (fixup_exception(regs)) return NOTIFY_STOP; /* Don't call default notifier */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.