powerpc: Move VMX and VSX asm code to vector.S
Currently, load_up_altivec and give_up_altivec are duplicated in 32-bit and 64-bit. This creates a common implementation that is moved away from head_32.S, head_64.S and misc_64.S and into vector.S, using the same macros we already use for our common implementation of load_up_fpu. I also moved the VSX code over to vector.S though in that case I didn't make it build on 32-bit (yet). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
@ -743,101 +743,6 @@ PerformanceMonitor:
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
EXC_XFER_STD(0xf00, performance_monitor_exception)
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
/* Note that the AltiVec support is closely modeled after the FP
|
||||
* support. Changes to one are likely to be applicable to the
|
||||
* other! */
|
||||
load_up_altivec:
|
||||
/*
|
||||
* Disable AltiVec for the task which had AltiVec previously,
|
||||
* and save its AltiVec registers in its thread_struct.
|
||||
* Enables AltiVec for use in the kernel on return.
|
||||
* On SMP we know the AltiVec units are free, since we give it up every
|
||||
* switch. -- Kumar
|
||||
*/
|
||||
mfmsr r5
|
||||
oris r5,r5,MSR_VEC@h
|
||||
MTMSRD(r5) /* enable use of AltiVec now */
|
||||
isync
|
||||
/*
|
||||
* For SMP, we don't do lazy AltiVec switching because it just gets too
|
||||
* horrendously complex, especially when a task switches from one CPU
|
||||
* to another. Instead we call giveup_altivec in switch_to.
|
||||
*/
|
||||
#ifndef CONFIG_SMP
|
||||
tophys(r6,0)
|
||||
addis r3,r6,last_task_used_altivec@ha
|
||||
lwz r4,last_task_used_altivec@l(r3)
|
||||
cmpwi 0,r4,0
|
||||
beq 1f
|
||||
add r4,r4,r6
|
||||
addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */
|
||||
SAVE_32VRS(0,r10,r4)
|
||||
mfvscr vr0
|
||||
li r10,THREAD_VSCR
|
||||
stvx vr0,r10,r4
|
||||
lwz r5,PT_REGS(r4)
|
||||
add r5,r5,r6
|
||||
lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
lis r10,MSR_VEC@h
|
||||
andc r4,r4,r10 /* disable altivec for previous task */
|
||||
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
1:
|
||||
#endif /* CONFIG_SMP */
|
||||
/* enable use of AltiVec after return */
|
||||
oris r9,r9,MSR_VEC@h
|
||||
mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
|
||||
li r4,1
|
||||
li r10,THREAD_VSCR
|
||||
stw r4,THREAD_USED_VR(r5)
|
||||
lvx vr0,r10,r5
|
||||
mtvscr vr0
|
||||
REST_32VRS(0,r10,r5)
|
||||
#ifndef CONFIG_SMP
|
||||
subi r4,r5,THREAD
|
||||
sub r4,r4,r6
|
||||
stw r4,last_task_used_altivec@l(r3)
|
||||
#endif /* CONFIG_SMP */
|
||||
/* restore registers and return */
|
||||
/* we haven't used ctr or xer or lr */
|
||||
b fast_exception_return
|
||||
|
||||
/*
|
||||
* giveup_altivec(tsk)
|
||||
* Disable AltiVec for the task given as the argument,
|
||||
* and save the AltiVec registers in its thread_struct.
|
||||
* Enables AltiVec for use in the kernel on return.
|
||||
*/
|
||||
|
||||
.globl giveup_altivec
|
||||
giveup_altivec:
|
||||
mfmsr r5
|
||||
oris r5,r5,MSR_VEC@h
|
||||
SYNC
|
||||
MTMSRD(r5) /* enable use of AltiVec now */
|
||||
isync
|
||||
cmpwi 0,r3,0
|
||||
beqlr- /* if no previous owner, done */
|
||||
addi r3,r3,THREAD /* want THREAD of task */
|
||||
lwz r5,PT_REGS(r3)
|
||||
cmpwi 0,r5,0
|
||||
SAVE_32VRS(0, r4, r3)
|
||||
mfvscr vr0
|
||||
li r4,THREAD_VSCR
|
||||
stvx vr0,r4,r3
|
||||
beq 1f
|
||||
lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
lis r3,MSR_VEC@h
|
||||
andc r4,r4,r3 /* disable AltiVec for previous task */
|
||||
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
1:
|
||||
#ifndef CONFIG_SMP
|
||||
li r5,0
|
||||
lis r4,last_task_used_altivec@ha
|
||||
stw r5,last_task_used_altivec@l(r4)
|
||||
#endif /* CONFIG_SMP */
|
||||
blr
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
|
||||
/*
|
||||
* This code is jumped to from the startup code to copy
|
||||
|
Reference in New Issue
Block a user