1 /* 2 * vectors.c 3 * 4 * Copyright (C) 1993, 1994 by Hamish Macdonald 5 * 6 * 68040 fixes by Michael Rausch 7 * 68040 fixes by Martin Apel 8 * 68040 fixes and writeback by Richard Zidlicky 9 * 68060 fixes by Roman Hodek 10 * 68060 fixes by Jesper Skov 11 * 12 * This file is subject to the terms and conditions of the GNU General Public 13 * License. See the file COPYING in the main directory of this archive 14 * for more details. 15 */ 16 17 /* 18 * Sets up all exception vectors 19 */ 20 #include <linux/cpu.h> 21 #include <linux/sched.h> 22 #include <linux/kernel.h> 23 #include <linux/linkage.h> 24 #include <linux/init.h> 25 #include <linux/kallsyms.h> 26 27 #include <asm/setup.h> 28 #include <asm/fpu.h> 29 #include <asm/traps.h> 30 31 #include "vectors.h" 32 33 /* assembler routines */ 34 asmlinkage void system_call(void); 35 asmlinkage void buserr(void); 36 asmlinkage void trap(void); 37 asmlinkage void nmihandler(void); 38 #ifdef CONFIG_M68KFPU_EMU 39 asmlinkage void fpu_emu(void); 40 #endif 41 42 e_vector vectors[256]; 43 44 /* nmi handler for the Amiga */ 45 asm(".text\n" 46 __ALIGN_STR "\n" 47 "nmihandler: rte"); 48 49 /* 50 * this must be called very early as the kernel might 51 * use some instruction that are emulated on the 060 52 * and so we're prepared for early probe attempts (e.g. nf_init). 53 */ 54 void __init base_trap_init(void) 55 { 56 if (MACH_IS_SUN3X) { 57 extern e_vector *sun3x_prom_vbr; 58 59 __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr)); 60 } 61 62 /* setup the exception vector table */ 63 __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); 64 65 if (CPU_IS_060) { 66 /* set up ISP entry points */ 67 asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); 68 69 vectors[VEC_UNIMPII] = unimp_vec; 70 } 71 72 vectors[VEC_BUSERR] = buserr; 73 vectors[VEC_ILLEGAL] = trap; 74 vectors[VEC_SYS] = system_call; 75 } 76 77 void __init trap_init (void) 78 { 79 int i; 80 81 for (i = VEC_SPUR; i <= VEC_INT7; i++) 82 vectors[i] = bad_inthandler; 83 84 for (i = 0; i < VEC_USER; i++) 85 if (!vectors[i]) 86 vectors[i] = trap; 87 88 for (i = VEC_USER; i < 256; i++) 89 vectors[i] = bad_inthandler; 90 91 #ifdef CONFIG_M68KFPU_EMU 92 if (FPU_IS_EMU) 93 vectors[VEC_LINE11] = fpu_emu; 94 #endif 95 96 if (CPU_IS_040 && !FPU_IS_EMU) { 97 /* set up FPSP entry points */ 98 asmlinkage void dz_vec(void) asm ("dz"); 99 asmlinkage void inex_vec(void) asm ("inex"); 100 asmlinkage void ovfl_vec(void) asm ("ovfl"); 101 asmlinkage void unfl_vec(void) asm ("unfl"); 102 asmlinkage void snan_vec(void) asm ("snan"); 103 asmlinkage void operr_vec(void) asm ("operr"); 104 asmlinkage void bsun_vec(void) asm ("bsun"); 105 asmlinkage void fline_vec(void) asm ("fline"); 106 asmlinkage void unsupp_vec(void) asm ("unsupp"); 107 108 vectors[VEC_FPDIVZ] = dz_vec; 109 vectors[VEC_FPIR] = inex_vec; 110 vectors[VEC_FPOVER] = ovfl_vec; 111 vectors[VEC_FPUNDER] = unfl_vec; 112 vectors[VEC_FPNAN] = snan_vec; 113 vectors[VEC_FPOE] = operr_vec; 114 vectors[VEC_FPBRUC] = bsun_vec; 115 vectors[VEC_LINE11] = fline_vec; 116 vectors[VEC_FPUNSUP] = unsupp_vec; 117 } 118 119 if (CPU_IS_060 && !FPU_IS_EMU) { 120 /* set up IFPSP entry points */ 121 asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan"); 122 asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr"); 123 asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl"); 124 asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl"); 125 asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz"); 126 asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex"); 127 asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline"); 128 asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp"); 129 asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd"); 130 131 vectors[VEC_FPNAN] = snan_vec6; 132 vectors[VEC_FPOE] = operr_vec6; 133 vectors[VEC_FPOVER] = ovfl_vec6; 134 vectors[VEC_FPUNDER] = unfl_vec6; 135 vectors[VEC_FPDIVZ] = dz_vec6; 136 vectors[VEC_FPIR] = inex_vec6; 137 vectors[VEC_LINE11] = fline_vec6; 138 vectors[VEC_FPUNSUP] = unsupp_vec6; 139 vectors[VEC_UNIMPEA] = effadd_vec6; 140 } 141 142 /* if running on an amiga, make the NMI interrupt do nothing */ 143 if (MACH_IS_AMIGA) { 144 vectors[VEC_INT7] = nmihandler; 145 } 146 } 147 148