259 lines
5.1 KiB
ArmAsm
259 lines
5.1 KiB
ArmAsm
|
/* 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
|