123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /* MN10300 Low level FPU management operations
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
- #include <linux/linkage.h>
- #include <asm/cpu-regs.h>
- #include <asm/smp.h>
- #include <asm/thread_info.h>
- #include <asm/asm-offsets.h>
- #include <asm/frame.inc>
- .macro FPU_INIT_STATE_ALL
- fmov 0,fs0
- fmov fs0,fs1
- fmov fs0,fs2
- fmov fs0,fs3
- fmov fs0,fs4
- fmov fs0,fs5
- fmov fs0,fs6
- fmov fs0,fs7
- fmov fs0,fs8
- fmov fs0,fs9
- fmov fs0,fs10
- fmov fs0,fs11
- fmov fs0,fs12
- fmov fs0,fs13
- fmov fs0,fs14
- fmov fs0,fs15
- fmov fs0,fs16
- fmov fs0,fs17
- fmov fs0,fs18
- fmov fs0,fs19
- fmov fs0,fs20
- fmov fs0,fs21
- fmov fs0,fs22
- fmov fs0,fs23
- fmov fs0,fs24
- fmov fs0,fs25
- fmov fs0,fs26
- fmov fs0,fs27
- fmov fs0,fs28
- fmov fs0,fs29
- fmov fs0,fs30
- fmov fs0,fs31
- fmov FPCR_INIT,fpcr
- .endm
- .macro FPU_SAVE_ALL areg,dreg
- fmov fs0,(\areg+)
- fmov fs1,(\areg+)
- fmov fs2,(\areg+)
- fmov fs3,(\areg+)
- fmov fs4,(\areg+)
- fmov fs5,(\areg+)
- fmov fs6,(\areg+)
- fmov fs7,(\areg+)
- fmov fs8,(\areg+)
- fmov fs9,(\areg+)
- fmov fs10,(\areg+)
- fmov fs11,(\areg+)
- fmov fs12,(\areg+)
- fmov fs13,(\areg+)
- fmov fs14,(\areg+)
- fmov fs15,(\areg+)
- fmov fs16,(\areg+)
- fmov fs17,(\areg+)
- fmov fs18,(\areg+)
- fmov fs19,(\areg+)
- fmov fs20,(\areg+)
- fmov fs21,(\areg+)
- fmov fs22,(\areg+)
- fmov fs23,(\areg+)
- fmov fs24,(\areg+)
- fmov fs25,(\areg+)
- fmov fs26,(\areg+)
- fmov fs27,(\areg+)
- fmov fs28,(\areg+)
- fmov fs29,(\areg+)
- fmov fs30,(\areg+)
- fmov fs31,(\areg+)
- fmov fpcr,\dreg
- mov \dreg,(\areg)
- .endm
- .macro FPU_RESTORE_ALL areg,dreg
- fmov (\areg+),fs0
- fmov (\areg+),fs1
- fmov (\areg+),fs2
- fmov (\areg+),fs3
- fmov (\areg+),fs4
- fmov (\areg+),fs5
- fmov (\areg+),fs6
- fmov (\areg+),fs7
- fmov (\areg+),fs8
- fmov (\areg+),fs9
- fmov (\areg+),fs10
- fmov (\areg+),fs11
- fmov (\areg+),fs12
- fmov (\areg+),fs13
- fmov (\areg+),fs14
- fmov (\areg+),fs15
- fmov (\areg+),fs16
- fmov (\areg+),fs17
- fmov (\areg+),fs18
- fmov (\areg+),fs19
- fmov (\areg+),fs20
- fmov (\areg+),fs21
- fmov (\areg+),fs22
- fmov (\areg+),fs23
- fmov (\areg+),fs24
- fmov (\areg+),fs25
- fmov (\areg+),fs26
- fmov (\areg+),fs27
- fmov (\areg+),fs28
- fmov (\areg+),fs29
- fmov (\areg+),fs30
- fmov (\areg+),fs31
- mov (\areg),\dreg
- fmov \dreg,fpcr
- .endm
- ###############################################################################
- #
- # void fpu_init_state(void)
- # - initialise the FPU
- #
- ###############################################################################
- .globl fpu_init_state
- .type fpu_init_state,@function
- fpu_init_state:
- mov epsw,d0
- or EPSW_FE,epsw
- #ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
- nop
- #endif
- FPU_INIT_STATE_ALL
- #ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
- nop
- #endif
- mov d0,epsw
- ret [],0
- .size fpu_init_state,.-fpu_init_state
- ###############################################################################
- #
- # void fpu_save(struct fpu_state_struct *)
- # - save the fpu state
- # - note that an FPU Operational exception might occur during this process
- #
- ###############################################################################
- .globl fpu_save
- .type fpu_save,@function
- fpu_save:
- mov epsw,d1
- or EPSW_FE,epsw /* enable the FPU so we can access it */
- #ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
- #endif
- mov d0,a0
- FPU_SAVE_ALL a0,d0
- #ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
- #endif
- mov d1,epsw
- ret [],0
- .size fpu_save,.-fpu_save
- ###############################################################################
- #
- # void fpu_disabled(void)
- # - handle an exception due to the FPU being disabled
- # when CONFIG_FPU is enabled
- #
- ###############################################################################
- .type fpu_disabled,@function
- .globl fpu_disabled
- fpu_disabled:
- or EPSW_nAR|EPSW_FE,epsw
- nop
- nop
- nop
- mov sp,a1
- mov (a1),d1 /* get epsw of user context */
- and ~(THREAD_SIZE-1),a1 /* a1: (thread_info *ti) */
- mov (TI_task,a1),a2 /* a2: (task_struct *tsk) */
- btst EPSW_nSL,d1
- beq fpu_used_in_kernel
- or EPSW_FE,d1
- mov d1,(sp)
- mov (TASK_THREAD+THREAD_FPU_FLAGS,a2),d1
- #ifndef CONFIG_LAZY_SAVE_FPU
- or __THREAD_HAS_FPU,d1
- mov d1,(TASK_THREAD+THREAD_FPU_FLAGS,a2)
- #else /* !CONFIG_LAZY_SAVE_FPU */
- mov (fpu_state_owner),a0
- cmp 0,a0
- beq fpu_regs_save_end
- mov (TASK_THREAD+THREAD_UREGS,a0),a1
- add TASK_THREAD+THREAD_FPU_STATE,a0
- FPU_SAVE_ALL a0,d0
- mov (REG_EPSW,a1),d0
- and ~EPSW_FE,d0
- mov d0,(REG_EPSW,a1)
- fpu_regs_save_end:
- mov a2,(fpu_state_owner)
- #endif /* !CONFIG_LAZY_SAVE_FPU */
- btst __THREAD_USING_FPU,d1
- beq fpu_regs_init
- add TASK_THREAD+THREAD_FPU_STATE,a2
- FPU_RESTORE_ALL a2,d0
- rti
- fpu_regs_init:
- FPU_INIT_STATE_ALL
- add TASK_THREAD+THREAD_FPU_FLAGS,a2
- bset __THREAD_USING_FPU,(0,a2)
- rti
- fpu_used_in_kernel:
- and ~(EPSW_nAR|EPSW_FE),epsw
- nop
- nop
- add -4,sp
- SAVE_ALL
- mov -1,d0
- mov d0,(REG_ORIG_D0,fp)
- and ~EPSW_NMID,epsw
- mov fp,d0
- call fpu_disabled_in_kernel[],0
- jmp ret_from_exception
- .size fpu_disabled,.-fpu_disabled
|