1/* MN10300 Low level FPU management operations 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11#include <linux/linkage.h> 12#include <asm/cpu-regs.h> 13#include <asm/smp.h> 14#include <asm/thread_info.h> 15#include <asm/asm-offsets.h> 16#include <asm/frame.inc> 17 18.macro FPU_INIT_STATE_ALL 19 fmov 0,fs0 20 fmov fs0,fs1 21 fmov fs0,fs2 22 fmov fs0,fs3 23 fmov fs0,fs4 24 fmov fs0,fs5 25 fmov fs0,fs6 26 fmov fs0,fs7 27 fmov fs0,fs8 28 fmov fs0,fs9 29 fmov fs0,fs10 30 fmov fs0,fs11 31 fmov fs0,fs12 32 fmov fs0,fs13 33 fmov fs0,fs14 34 fmov fs0,fs15 35 fmov fs0,fs16 36 fmov fs0,fs17 37 fmov fs0,fs18 38 fmov fs0,fs19 39 fmov fs0,fs20 40 fmov fs0,fs21 41 fmov fs0,fs22 42 fmov fs0,fs23 43 fmov fs0,fs24 44 fmov fs0,fs25 45 fmov fs0,fs26 46 fmov fs0,fs27 47 fmov fs0,fs28 48 fmov fs0,fs29 49 fmov fs0,fs30 50 fmov fs0,fs31 51 fmov FPCR_INIT,fpcr 52.endm 53 54.macro FPU_SAVE_ALL areg,dreg 55 fmov fs0,(\areg+) 56 fmov fs1,(\areg+) 57 fmov fs2,(\areg+) 58 fmov fs3,(\areg+) 59 fmov fs4,(\areg+) 60 fmov fs5,(\areg+) 61 fmov fs6,(\areg+) 62 fmov fs7,(\areg+) 63 fmov fs8,(\areg+) 64 fmov fs9,(\areg+) 65 fmov fs10,(\areg+) 66 fmov fs11,(\areg+) 67 fmov fs12,(\areg+) 68 fmov fs13,(\areg+) 69 fmov fs14,(\areg+) 70 fmov fs15,(\areg+) 71 fmov fs16,(\areg+) 72 fmov fs17,(\areg+) 73 fmov fs18,(\areg+) 74 fmov fs19,(\areg+) 75 fmov fs20,(\areg+) 76 fmov fs21,(\areg+) 77 fmov fs22,(\areg+) 78 fmov fs23,(\areg+) 79 fmov fs24,(\areg+) 80 fmov fs25,(\areg+) 81 fmov fs26,(\areg+) 82 fmov fs27,(\areg+) 83 fmov fs28,(\areg+) 84 fmov fs29,(\areg+) 85 fmov fs30,(\areg+) 86 fmov fs31,(\areg+) 87 fmov fpcr,\dreg 88 mov \dreg,(\areg) 89.endm 90 91.macro FPU_RESTORE_ALL areg,dreg 92 fmov (\areg+),fs0 93 fmov (\areg+),fs1 94 fmov (\areg+),fs2 95 fmov (\areg+),fs3 96 fmov (\areg+),fs4 97 fmov (\areg+),fs5 98 fmov (\areg+),fs6 99 fmov (\areg+),fs7 100 fmov (\areg+),fs8 101 fmov (\areg+),fs9 102 fmov (\areg+),fs10 103 fmov (\areg+),fs11 104 fmov (\areg+),fs12 105 fmov (\areg+),fs13 106 fmov (\areg+),fs14 107 fmov (\areg+),fs15 108 fmov (\areg+),fs16 109 fmov (\areg+),fs17 110 fmov (\areg+),fs18 111 fmov (\areg+),fs19 112 fmov (\areg+),fs20 113 fmov (\areg+),fs21 114 fmov (\areg+),fs22 115 fmov (\areg+),fs23 116 fmov (\areg+),fs24 117 fmov (\areg+),fs25 118 fmov (\areg+),fs26 119 fmov (\areg+),fs27 120 fmov (\areg+),fs28 121 fmov (\areg+),fs29 122 fmov (\areg+),fs30 123 fmov (\areg+),fs31 124 mov (\areg),\dreg 125 fmov \dreg,fpcr 126.endm 127 128############################################################################### 129# 130# void fpu_init_state(void) 131# - initialise the FPU 132# 133############################################################################### 134 .globl fpu_init_state 135 .type fpu_init_state,@function 136fpu_init_state: 137 mov epsw,d0 138 or EPSW_FE,epsw 139 140#ifdef CONFIG_MN10300_PROC_MN103E010 141 nop 142 nop 143 nop 144#endif 145 FPU_INIT_STATE_ALL 146#ifdef CONFIG_MN10300_PROC_MN103E010 147 nop 148 nop 149 nop 150#endif 151 mov d0,epsw 152 ret [],0 153 154 .size fpu_init_state,.-fpu_init_state 155 156############################################################################### 157# 158# void fpu_save(struct fpu_state_struct *) 159# - save the fpu state 160# - note that an FPU Operational exception might occur during this process 161# 162############################################################################### 163 .globl fpu_save 164 .type fpu_save,@function 165fpu_save: 166 mov epsw,d1 167 or EPSW_FE,epsw /* enable the FPU so we can access it */ 168 169#ifdef CONFIG_MN10300_PROC_MN103E010 170 nop 171 nop 172#endif 173 mov d0,a0 174 FPU_SAVE_ALL a0,d0 175#ifdef CONFIG_MN10300_PROC_MN103E010 176 nop 177 nop 178#endif 179 180 mov d1,epsw 181 ret [],0 182 183 .size fpu_save,.-fpu_save 184 185############################################################################### 186# 187# void fpu_disabled(void) 188# - handle an exception due to the FPU being disabled 189# when CONFIG_FPU is enabled 190# 191############################################################################### 192 .type fpu_disabled,@function 193 .globl fpu_disabled 194fpu_disabled: 195 or EPSW_nAR|EPSW_FE,epsw 196 nop 197 nop 198 nop 199 200 mov sp,a1 201 mov (a1),d1 /* get epsw of user context */ 202 and ~(THREAD_SIZE-1),a1 /* a1: (thread_info *ti) */ 203 mov (TI_task,a1),a2 /* a2: (task_struct *tsk) */ 204 btst EPSW_nSL,d1 205 beq fpu_used_in_kernel 206 207 or EPSW_FE,d1 208 mov d1,(sp) 209 mov (TASK_THREAD+THREAD_FPU_FLAGS,a2),d1 210#ifndef CONFIG_LAZY_SAVE_FPU 211 or __THREAD_HAS_FPU,d1 212 mov d1,(TASK_THREAD+THREAD_FPU_FLAGS,a2) 213#else /* !CONFIG_LAZY_SAVE_FPU */ 214 mov (fpu_state_owner),a0 215 cmp 0,a0 216 beq fpu_regs_save_end 217 218 mov (TASK_THREAD+THREAD_UREGS,a0),a1 219 add TASK_THREAD+THREAD_FPU_STATE,a0 220 FPU_SAVE_ALL a0,d0 221 222 mov (REG_EPSW,a1),d0 223 and ~EPSW_FE,d0 224 mov d0,(REG_EPSW,a1) 225 226fpu_regs_save_end: 227 mov a2,(fpu_state_owner) 228#endif /* !CONFIG_LAZY_SAVE_FPU */ 229 230 btst __THREAD_USING_FPU,d1 231 beq fpu_regs_init 232 add TASK_THREAD+THREAD_FPU_STATE,a2 233 FPU_RESTORE_ALL a2,d0 234 rti 235 236fpu_regs_init: 237 FPU_INIT_STATE_ALL 238 add TASK_THREAD+THREAD_FPU_FLAGS,a2 239 bset __THREAD_USING_FPU,(0,a2) 240 rti 241 242fpu_used_in_kernel: 243 and ~(EPSW_nAR|EPSW_FE),epsw 244 nop 245 nop 246 247 add -4,sp 248 SAVE_ALL 249 mov -1,d0 250 mov d0,(REG_ORIG_D0,fp) 251 252 and ~EPSW_NMID,epsw 253 254 mov fp,d0 255 call fpu_disabled_in_kernel[],0 256 jmp ret_from_exception 257 258 .size fpu_disabled,.-fpu_disabled 259