Greg Ungerer | bc4f4ac | 2011-06-24 16:15:40 +1000 | [diff] [blame] | 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/sched.h> |
| 21 | #include <linux/kernel.h> |
| 22 | #include <linux/linkage.h> |
| 23 | #include <linux/init.h> |
| 24 | #include <linux/kallsyms.h> |
| 25 | |
| 26 | #include <asm/setup.h> |
| 27 | #include <asm/fpu.h> |
Greg Ungerer | bc4f4ac | 2011-06-24 16:15:40 +1000 | [diff] [blame] | 28 | #include <asm/traps.h> |
| 29 | |
| 30 | /* assembler routines */ |
| 31 | asmlinkage void system_call(void); |
| 32 | asmlinkage void buserr(void); |
| 33 | asmlinkage void trap(void); |
| 34 | asmlinkage void nmihandler(void); |
| 35 | #ifdef CONFIG_M68KFPU_EMU |
| 36 | asmlinkage void fpu_emu(void); |
| 37 | #endif |
| 38 | |
| 39 | e_vector vectors[256]; |
| 40 | |
| 41 | /* nmi handler for the Amiga */ |
| 42 | asm(".text\n" |
| 43 | __ALIGN_STR "\n" |
| 44 | "nmihandler: rte"); |
| 45 | |
| 46 | /* |
| 47 | * this must be called very early as the kernel might |
| 48 | * use some instruction that are emulated on the 060 |
| 49 | * and so we're prepared for early probe attempts (e.g. nf_init). |
| 50 | */ |
| 51 | void __init base_trap_init(void) |
| 52 | { |
| 53 | if (MACH_IS_SUN3X) { |
| 54 | extern e_vector *sun3x_prom_vbr; |
| 55 | |
| 56 | __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr)); |
| 57 | } |
| 58 | |
| 59 | /* setup the exception vector table */ |
| 60 | __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); |
| 61 | |
| 62 | if (CPU_IS_060) { |
| 63 | /* set up ISP entry points */ |
| 64 | asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); |
| 65 | |
| 66 | vectors[VEC_UNIMPII] = unimp_vec; |
| 67 | } |
| 68 | |
| 69 | vectors[VEC_BUSERR] = buserr; |
| 70 | vectors[VEC_ILLEGAL] = trap; |
| 71 | vectors[VEC_SYS] = system_call; |
| 72 | } |
| 73 | |
| 74 | void __init trap_init (void) |
| 75 | { |
| 76 | int i; |
| 77 | |
| 78 | for (i = VEC_SPUR; i <= VEC_INT7; i++) |
| 79 | vectors[i] = bad_inthandler; |
| 80 | |
| 81 | for (i = 0; i < VEC_USER; i++) |
| 82 | if (!vectors[i]) |
| 83 | vectors[i] = trap; |
| 84 | |
| 85 | for (i = VEC_USER; i < 256; i++) |
| 86 | vectors[i] = bad_inthandler; |
| 87 | |
| 88 | #ifdef CONFIG_M68KFPU_EMU |
| 89 | if (FPU_IS_EMU) |
| 90 | vectors[VEC_LINE11] = fpu_emu; |
| 91 | #endif |
| 92 | |
| 93 | if (CPU_IS_040 && !FPU_IS_EMU) { |
| 94 | /* set up FPSP entry points */ |
| 95 | asmlinkage void dz_vec(void) asm ("dz"); |
| 96 | asmlinkage void inex_vec(void) asm ("inex"); |
| 97 | asmlinkage void ovfl_vec(void) asm ("ovfl"); |
| 98 | asmlinkage void unfl_vec(void) asm ("unfl"); |
| 99 | asmlinkage void snan_vec(void) asm ("snan"); |
| 100 | asmlinkage void operr_vec(void) asm ("operr"); |
| 101 | asmlinkage void bsun_vec(void) asm ("bsun"); |
| 102 | asmlinkage void fline_vec(void) asm ("fline"); |
| 103 | asmlinkage void unsupp_vec(void) asm ("unsupp"); |
| 104 | |
| 105 | vectors[VEC_FPDIVZ] = dz_vec; |
| 106 | vectors[VEC_FPIR] = inex_vec; |
| 107 | vectors[VEC_FPOVER] = ovfl_vec; |
| 108 | vectors[VEC_FPUNDER] = unfl_vec; |
| 109 | vectors[VEC_FPNAN] = snan_vec; |
| 110 | vectors[VEC_FPOE] = operr_vec; |
| 111 | vectors[VEC_FPBRUC] = bsun_vec; |
| 112 | vectors[VEC_LINE11] = fline_vec; |
| 113 | vectors[VEC_FPUNSUP] = unsupp_vec; |
| 114 | } |
| 115 | |
| 116 | if (CPU_IS_060 && !FPU_IS_EMU) { |
| 117 | /* set up IFPSP entry points */ |
| 118 | asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan"); |
| 119 | asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr"); |
| 120 | asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl"); |
| 121 | asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl"); |
| 122 | asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz"); |
| 123 | asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex"); |
| 124 | asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline"); |
| 125 | asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp"); |
| 126 | asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd"); |
| 127 | |
| 128 | vectors[VEC_FPNAN] = snan_vec6; |
| 129 | vectors[VEC_FPOE] = operr_vec6; |
| 130 | vectors[VEC_FPOVER] = ovfl_vec6; |
| 131 | vectors[VEC_FPUNDER] = unfl_vec6; |
| 132 | vectors[VEC_FPDIVZ] = dz_vec6; |
| 133 | vectors[VEC_FPIR] = inex_vec6; |
| 134 | vectors[VEC_LINE11] = fline_vec6; |
| 135 | vectors[VEC_FPUNSUP] = unsupp_vec6; |
| 136 | vectors[VEC_UNIMPEA] = effadd_vec6; |
| 137 | } |
| 138 | |
| 139 | /* if running on an amiga, make the NMI interrupt do nothing */ |
| 140 | if (MACH_IS_AMIGA) { |
| 141 | vectors[VEC_INT7] = nmihandler; |
| 142 | } |
| 143 | } |
| 144 | |