18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 38c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 48c2ecf20Sopenharmony_ci * for more details. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2009 Wind River Systems, 78c2ecf20Sopenharmony_ci * written by Ralf Baechle <ralf@linux-mips.org> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci#include <linux/init.h> 108c2ecf20Sopenharmony_ci#include <linux/irqflags.h> 118c2ecf20Sopenharmony_ci#include <linux/notifier.h> 128c2ecf20Sopenharmony_ci#include <linux/prefetch.h> 138c2ecf20Sopenharmony_ci#include <linux/ptrace.h> 148c2ecf20Sopenharmony_ci#include <linux/sched.h> 158c2ecf20Sopenharmony_ci#include <linux/sched/task_stack.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <asm/cop2.h> 188c2ecf20Sopenharmony_ci#include <asm/current.h> 198c2ecf20Sopenharmony_ci#include <asm/mipsregs.h> 208c2ecf20Sopenharmony_ci#include <asm/page.h> 218c2ecf20Sopenharmony_ci#include <asm/octeon/octeon.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action, 248c2ecf20Sopenharmony_ci void *data) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci unsigned long flags; 278c2ecf20Sopenharmony_ci unsigned int status; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci switch (action) { 308c2ecf20Sopenharmony_ci case CU2_EXCEPTION: 318c2ecf20Sopenharmony_ci prefetch(¤t->thread.cp2); 328c2ecf20Sopenharmony_ci local_irq_save(flags); 338c2ecf20Sopenharmony_ci KSTK_STATUS(current) |= ST0_CU2; 348c2ecf20Sopenharmony_ci status = read_c0_status(); 358c2ecf20Sopenharmony_ci write_c0_status(status | ST0_CU2); 368c2ecf20Sopenharmony_ci octeon_cop2_restore(&(current->thread.cp2)); 378c2ecf20Sopenharmony_ci write_c0_status(status & ~ST0_CU2); 388c2ecf20Sopenharmony_ci local_irq_restore(flags); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci return NOTIFY_BAD; /* Don't call default notifier */ 418c2ecf20Sopenharmony_ci } 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci return NOTIFY_OK; /* Let default notifier send signals */ 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic int __init cnmips_cu2_setup(void) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci return cu2_notifier(cnmips_cu2_call, 0); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ciearly_initcall(cnmips_cu2_setup); 51