Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

unicore32 additional architecture files: float point handling

This patch implements support for float point unit, which using UniCore-F64 FPU hardware
in UniCore32 ISA.

Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Acked-by: Arnd Bergmann <arnd@arndb.de>

+205
+26
arch/unicore32/include/asm/fpstate.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/fpstate.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #ifndef __UNICORE_FPSTATE_H__ 14 + #define __UNICORE_FPSTATE_H__ 15 + 16 + #ifndef __ASSEMBLY__ 17 + 18 + #define FP_REGS_NUMBER 33 19 + 20 + struct fp_state { 21 + unsigned int regs[FP_REGS_NUMBER]; 22 + } __attribute__((aligned(8))); 23 + 24 + #endif 25 + 26 + #endif
+53
arch/unicore32/include/asm/fpu-ucf64.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/fpu-ucf64.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> 7 + * Copyright (C) 2001-2010 Guan Xuetao 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + */ 13 + #define FPSCR s31 14 + 15 + /* FPSCR bits */ 16 + #define FPSCR_DEFAULT_NAN (1<<25) 17 + 18 + #define FPSCR_CMPINSTR_BIT (1<<31) 19 + 20 + #define FPSCR_CON (1<<29) 21 + #define FPSCR_TRAP (1<<27) 22 + 23 + /* RND mode */ 24 + #define FPSCR_ROUND_NEAREST (0<<0) 25 + #define FPSCR_ROUND_PLUSINF (2<<0) 26 + #define FPSCR_ROUND_MINUSINF (3<<0) 27 + #define FPSCR_ROUND_TOZERO (1<<0) 28 + #define FPSCR_RMODE_BIT (0) 29 + #define FPSCR_RMODE_MASK (7 << FPSCR_RMODE_BIT) 30 + 31 + /* trap enable */ 32 + #define FPSCR_IOE (1<<16) 33 + #define FPSCR_OFE (1<<14) 34 + #define FPSCR_UFE (1<<13) 35 + #define FPSCR_IXE (1<<12) 36 + #define FPSCR_HIE (1<<11) 37 + #define FPSCR_NDE (1<<10) /* non denomal */ 38 + 39 + /* flags */ 40 + #define FPSCR_IDC (1<<24) 41 + #define FPSCR_HIC (1<<23) 42 + #define FPSCR_IXC (1<<22) 43 + #define FPSCR_OFC (1<<21) 44 + #define FPSCR_UFC (1<<20) 45 + #define FPSCR_IOC (1<<19) 46 + 47 + /* stick bits */ 48 + #define FPSCR_IOS (1<<9) 49 + #define FPSCR_OFS (1<<7) 50 + #define FPSCR_UFS (1<<6) 51 + #define FPSCR_IXS (1<<5) 52 + #define FPSCR_HIS (1<<4) 53 + #define FPSCR_NDS (1<<3) /*non denomal */
+126
arch/unicore32/kernel/fpu-ucf64.c
··· 1 + /* 2 + * linux/arch/unicore32/kernel/fpu-ucf64.c 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + #include <linux/module.h> 13 + #include <linux/types.h> 14 + #include <linux/kernel.h> 15 + #include <linux/signal.h> 16 + #include <linux/sched.h> 17 + #include <linux/init.h> 18 + 19 + #include <asm/fpu-ucf64.h> 20 + 21 + /* 22 + * A special flag to tell the normalisation code not to normalise. 23 + */ 24 + #define F64_NAN_FLAG 0x100 25 + 26 + /* 27 + * A bit pattern used to indicate the initial (unset) value of the 28 + * exception mask, in case nothing handles an instruction. This 29 + * doesn't include the NAN flag, which get masked out before 30 + * we check for an error. 31 + */ 32 + #define F64_EXCEPTION_ERROR ((u32)-1 & ~F64_NAN_FLAG) 33 + 34 + /* 35 + * Since we aren't building with -mfpu=f64, we need to code 36 + * these instructions using their MRC/MCR equivalents. 37 + */ 38 + #define f64reg(_f64_) #_f64_ 39 + 40 + #define cff(_f64_) ({ \ 41 + u32 __v; \ 42 + asm("cff %0, " f64reg(_f64_) "@ fmrx %0, " #_f64_ \ 43 + : "=r" (__v) : : "cc"); \ 44 + __v; \ 45 + }) 46 + 47 + #define ctf(_f64_, _var_) \ 48 + asm("ctf %0, " f64reg(_f64_) "@ fmxr " #_f64_ ", %0" \ 49 + : : "r" (_var_) : "cc") 50 + 51 + /* 52 + * Raise a SIGFPE for the current process. 53 + * sicode describes the signal being raised. 54 + */ 55 + void ucf64_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) 56 + { 57 + siginfo_t info; 58 + 59 + memset(&info, 0, sizeof(info)); 60 + 61 + info.si_signo = SIGFPE; 62 + info.si_code = sicode; 63 + info.si_addr = (void __user *)(instruction_pointer(regs) - 4); 64 + 65 + /* 66 + * This is the same as NWFPE, because it's not clear what 67 + * this is used for 68 + */ 69 + current->thread.error_code = 0; 70 + current->thread.trap_no = 6; 71 + 72 + send_sig_info(SIGFPE, &info, current); 73 + } 74 + 75 + /* 76 + * Handle exceptions of UniCore-F64. 77 + */ 78 + void ucf64_exchandler(u32 inst, u32 fpexc, struct pt_regs *regs) 79 + { 80 + u32 tmp = fpexc; 81 + u32 exc = F64_EXCEPTION_ERROR & fpexc; 82 + 83 + pr_debug("UniCore-F64: instruction %08x fpscr %08x\n", 84 + inst, fpexc); 85 + 86 + if (exc & FPSCR_CMPINSTR_BIT) { 87 + if (exc & FPSCR_CON) 88 + tmp |= FPSCR_CON; 89 + else 90 + tmp &= ~(FPSCR_CON); 91 + exc &= ~(FPSCR_CMPINSTR_BIT | FPSCR_CON); 92 + } else { 93 + pr_debug(KERN_ERR "UniCore-F64 Error: unhandled exceptions\n"); 94 + pr_debug(KERN_ERR "UniCore-F64 FPSCR 0x%08x INST 0x%08x\n", 95 + cff(FPSCR), inst); 96 + 97 + ucf64_raise_sigfpe(0, regs); 98 + return; 99 + } 100 + 101 + /* 102 + * Update the FPSCR with the additional exception flags. 103 + * Comparison instructions always return at least one of 104 + * these flags set. 105 + */ 106 + tmp &= ~(FPSCR_TRAP | FPSCR_IOS | FPSCR_OFS | FPSCR_UFS | 107 + FPSCR_IXS | FPSCR_HIS | FPSCR_IOC | FPSCR_OFC | 108 + FPSCR_UFC | FPSCR_IXC | FPSCR_HIC); 109 + 110 + tmp |= exc; 111 + ctf(FPSCR, tmp); 112 + } 113 + 114 + /* 115 + * F64 support code initialisation. 116 + */ 117 + static int __init ucf64_init(void) 118 + { 119 + ctf(FPSCR, 0x0); /* FPSCR_UFE | FPSCR_NDE perhaps better */ 120 + 121 + printk(KERN_INFO "Enable UniCore-F64 support.\n"); 122 + 123 + return 0; 124 + } 125 + 126 + late_initcall(ucf64_init);