This source file includes following definitions.
- nwfpe_notify
- fpe_init
- fpe_exit
- float_raise
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 #include "fpa11.h"
  13 
  14 #include <linux/module.h>
  15 #include <linux/moduleparam.h>
  16 
  17 
  18 #include <linux/errno.h>
  19 #include <linux/types.h>
  20 #include <linux/kernel.h>
  21 #include <linux/signal.h>
  22 #include <linux/sched/signal.h>
  23 #include <linux/init.h>
  24 
  25 #include <asm/thread_notify.h>
  26 
  27 #include "softfloat.h"
  28 #include "fpopcode.h"
  29 #include "fpmodule.h"
  30 #include "fpa11.inl"
  31 
  32 
  33 #ifdef CONFIG_FPE_NWFPE_XP
  34 #define NWFPE_BITS "extended"
  35 #else
  36 #define NWFPE_BITS "double"
  37 #endif
  38 
  39 #ifdef MODULE
  40 void fp_send_sig(unsigned long sig, struct task_struct *p, int priv);
  41 #else
  42 #define fp_send_sig     send_sig
  43 #define kern_fp_enter   fp_enter
  44 
  45 extern char fpe_type[];
  46 #endif
  47 
  48 static int nwfpe_notify(struct notifier_block *self, unsigned long cmd, void *v)
  49 {
  50         struct thread_info *thread = v;
  51 
  52         if (cmd == THREAD_NOTIFY_FLUSH)
  53                 nwfpe_init_fpa(&thread->fpstate);
  54 
  55         return NOTIFY_DONE;
  56 }
  57 
  58 static struct notifier_block nwfpe_notifier_block = {
  59         .notifier_call = nwfpe_notify,
  60 };
  61 
  62 
  63 void fp_setup(void);
  64 
  65 
  66 extern void (*kern_fp_enter)(void);
  67 
  68 
  69 static void (*orig_fp_enter)(void);
  70 
  71 
  72 extern void nwfpe_enter(void);
  73 
  74 static int __init fpe_init(void)
  75 {
  76         if (sizeof(FPA11) > sizeof(union fp_state)) {
  77                 pr_err("nwfpe: bad structure size\n");
  78                 return -EINVAL;
  79         }
  80 
  81         if (sizeof(FPREG) != 12) {
  82                 pr_err("nwfpe: bad register size\n");
  83                 return -EINVAL;
  84         }
  85         if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
  86                 return 0;
  87 
  88         
  89         pr_info("NetWinder Floating Point Emulator V0.97 ("
  90                 NWFPE_BITS " precision)\n");
  91 
  92         thread_register_notifier(&nwfpe_notifier_block);
  93 
  94         
  95         orig_fp_enter = kern_fp_enter;
  96         kern_fp_enter = nwfpe_enter;
  97 
  98         return 0;
  99 }
 100 
 101 static void __exit fpe_exit(void)
 102 {
 103         thread_unregister_notifier(&nwfpe_notifier_block);
 104         
 105         kern_fp_enter = orig_fp_enter;
 106 }
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 
 116 
 117 
 118 
 119 
 120 
 121 
 122 
 123 
 124 
 125 
 126 #ifdef CONFIG_DEBUG_USER
 127 
 128 static int debug = ~BIT_IXC;
 129 #endif
 130 
 131 void float_raise(signed char flags)
 132 {
 133         register unsigned int fpsr, cumulativeTraps;
 134 
 135 #ifdef CONFIG_DEBUG_USER
 136         if (flags & debug)
 137                 printk(KERN_DEBUG
 138                        "NWFPE: %s[%d] takes exception %08x at %ps from %08lx\n",
 139                        current->comm, current->pid, flags,
 140                        __builtin_return_address(0), GET_USERREG()->ARM_pc);
 141 #endif
 142 
 143         
 144         fpsr = readFPSR();
 145         cumulativeTraps = 0;
 146 
 147         
 148 
 149         if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
 150                 cumulativeTraps |= BIT_IXC;
 151         if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
 152                 cumulativeTraps |= BIT_UFC;
 153         if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
 154                 cumulativeTraps |= BIT_OFC;
 155         if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
 156                 cumulativeTraps |= BIT_DZC;
 157         if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
 158                 cumulativeTraps |= BIT_IOC;
 159 
 160         
 161         if (cumulativeTraps)
 162                 writeFPSR(fpsr | cumulativeTraps);
 163 
 164         
 165         if (fpsr & (flags << 16))
 166                 fp_send_sig(SIGFPE, current, 1);
 167 }
 168 
 169 module_init(fpe_init);
 170 module_exit(fpe_exit);
 171 
 172 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
 173 MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)");
 174 MODULE_LICENSE("GPL");
 175 
 176 #ifdef CONFIG_DEBUG_USER
 177 module_param(debug, int, 0644);
 178 #endif