From 3e2647a7146d4b972c6a0290e6657bab0de18afa Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 23 Dec 2014 14:18:06 +0100 Subject: powerpc: AltiVec and FPU context support Add AltiVec and FPU support to the Context_Control in case we use the e6500 multilib. Add PPC_MULTILIB_ALTIVEC and PPC_MULTILIB_FPU multilib defines. Add non-volatile AltiVec and FPU context to Context_Control. Add save/restore of non-volatile AltiVec and FPU to _CPU_Context_switch(). Add save/restore of volatile AltiVec and FPU context to the exception code. Adjust data cache optimizations for the new context and cache line size. --- cpukit/score/cpu/powerpc/ppc-context-validate.S | 386 +++++++++++++++++++++++- 1 file changed, 384 insertions(+), 2 deletions(-) (limited to 'cpukit/score/cpu/powerpc/ppc-context-validate.S') diff --git a/cpukit/score/cpu/powerpc/ppc-context-validate.S b/cpukit/score/cpu/powerpc/ppc-context-validate.S index 58bc64c843..0e64cc58ee 100644 --- a/cpukit/score/cpu/powerpc/ppc-context-validate.S +++ b/cpukit/score/cpu/powerpc/ppc-context-validate.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013-2015 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -40,8 +40,60 @@ #define GPR29_OFFSET OFFSET(15) #define GPR30_OFFSET OFFSET(16) #define GPR31_OFFSET OFFSET(17) + +#ifdef PPC_MULTILIB_FPU + #define FOFFSET(i) ((i) * 8 + OFFSET(18)) + #define F14_OFFSET FOFFSET(0) + #define F15_OFFSET FOFFSET(1) + #define F16_OFFSET FOFFSET(2) + #define F17_OFFSET FOFFSET(3) + #define F18_OFFSET FOFFSET(4) + #define F19_OFFSET FOFFSET(5) + #define F20_OFFSET FOFFSET(6) + #define F21_OFFSET FOFFSET(7) + #define F22_OFFSET FOFFSET(8) + #define F23_OFFSET FOFFSET(9) + #define F24_OFFSET FOFFSET(10) + #define F25_OFFSET FOFFSET(11) + #define F26_OFFSET FOFFSET(12) + #define F27_OFFSET FOFFSET(13) + #define F28_OFFSET FOFFSET(14) + #define F29_OFFSET FOFFSET(15) + #define F30_OFFSET FOFFSET(16) + #define F31_OFFSET FOFFSET(17) + #define FPSCR_OFFSET FOFFSET(18) + #define FTMP_OFFSET FOFFSET(19) + #define FTMP2_OFFSET FOFFSET(20) + #define FPUEND FOFFSET(21) +#else + #define FPUEND OFFSET(18) +#endif + +#ifdef PPC_MULTILIB_ALTIVEC + #define VOFFSET(i) ((i) * 16 + ((FPUEND + 16 - 1) & ~(16 - 1))) + #define V20_OFFSET VOFFSET(0) + #define V21_OFFSET VOFFSET(1) + #define V22_OFFSET VOFFSET(2) + #define V23_OFFSET VOFFSET(3) + #define V24_OFFSET VOFFSET(4) + #define V25_OFFSET VOFFSET(5) + #define V26_OFFSET VOFFSET(6) + #define V27_OFFSET VOFFSET(7) + #define V28_OFFSET VOFFSET(8) + #define V29_OFFSET VOFFSET(9) + #define V30_OFFSET VOFFSET(10) + #define V31_OFFSET VOFFSET(11) + #define VTMP_OFFSET VOFFSET(12) + #define VTMP2_OFFSET VOFFSET(13) + #define VSCR_OFFSET VOFFSET(14) + #define VRSAVE_OFFSET (VSCR_OFFSET + 4) + #define ALTIVECEND (VRSAVE_OFFSET + 4) +#else + #define ALTIVECEND FPUEND +#endif + #define FRAME_SIZE \ - ((OFFSET(18) + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1)) + ((ALTIVECEND + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1)) .global _CPU_Context_validate @@ -72,6 +124,61 @@ _CPU_Context_validate: stw r30, GPR30_OFFSET(r1) stw r31, GPR31_OFFSET(r1) +#ifdef PPC_MULTILIB_FPU + stfd f14, F14_OFFSET(r1) + stfd f15, F15_OFFSET(r1) + stfd f16, F16_OFFSET(r1) + stfd f17, F17_OFFSET(r1) + stfd f18, F18_OFFSET(r1) + stfd f19, F19_OFFSET(r1) + stfd f20, F20_OFFSET(r1) + stfd f21, F21_OFFSET(r1) + stfd f22, F22_OFFSET(r1) + stfd f23, F23_OFFSET(r1) + stfd f24, F24_OFFSET(r1) + stfd f25, F25_OFFSET(r1) + stfd f26, F26_OFFSET(r1) + stfd f27, F27_OFFSET(r1) + stfd f28, F28_OFFSET(r1) + stfd f29, F29_OFFSET(r1) + stfd f30, F30_OFFSET(r1) + stfd f31, F31_OFFSET(r1) + mffs f0 + stfd f0, FPSCR_OFFSET(r1) +#endif + +#ifdef PPC_MULTILIB_ALTIVEC + li r0, V20_OFFSET + stvx v20, r1, r0 + li r0, V21_OFFSET + stvx v21, r1, r0 + li r0, V22_OFFSET + stvx v22, r1, r0 + li r0, V23_OFFSET + stvx v23, r1, r0 + li r0, V24_OFFSET + stvx v24, r1, r0 + li r0, V25_OFFSET + stvx v25, r1, r0 + li r0, V26_OFFSET + stvx v26, r1, r0 + li r0, V27_OFFSET + stvx v27, r1, r0 + li r0, V28_OFFSET + stvx v28, r1, r0 + li r0, V29_OFFSET + stvx v29, r1, r0 + li r0, V30_OFFSET + stvx v30, r1, r0 + li r0, V31_OFFSET + stvx v31, r1, r0 + mfvscr v0 + li r0, VSCR_OFFSET + stvewx v0, r1, r0 + mfvrsave r0 + stw r0, VRSAVE_OFFSET(r1) +#endif + /* Fill */ /* CR and GPR29 are equal most of the time */ @@ -124,6 +231,99 @@ _CPU_Context_validate: /* GPR31 contains the stack pointer */ mr r31, r1 +#ifdef PPC_MULTILIB_FPU +.macro FILL_F i + addi r4, r3, 0x100 + \i + stw r4, FTMP_OFFSET(r1) + addi r4, r3, 0x200 + \i + stw r4, FTMP_OFFSET + 4(r1) + lfd \i, FTMP_OFFSET(r1) +.endm + + FILL_F 0 + FILL_F 1 + FILL_F 2 + FILL_F 3 + FILL_F 4 + FILL_F 5 + FILL_F 6 + FILL_F 7 + FILL_F 8 + FILL_F 9 + FILL_F 10 + FILL_F 11 + FILL_F 12 + FILL_F 13 + FILL_F 14 + FILL_F 15 + FILL_F 16 + FILL_F 17 + FILL_F 18 + FILL_F 19 + FILL_F 20 + FILL_F 21 + FILL_F 22 + FILL_F 23 + FILL_F 24 + FILL_F 25 + FILL_F 26 + FILL_F 27 + FILL_F 28 + FILL_F 29 + FILL_F 30 + FILL_F 31 +#endif + +#ifdef PPC_MULTILIB_ALTIVEC +.macro FILL_V i + addi r4, r3, 0x300 + \i + stw r4, VTMP_OFFSET(r1) + addi r4, r3, 0x400 + \i + stw r4, VTMP_OFFSET + 4(r1) + addi r4, r3, 0x500 + \i + stw r4, VTMP_OFFSET + 8(r1) + addi r4, r3, 0x600 + \i + stw r4, VTMP_OFFSET + 12(r1) + li r4, VTMP_OFFSET + lvx \i, r1, r4 +.endm + + FILL_V 0 + FILL_V 1 + FILL_V 2 + FILL_V 3 + FILL_V 4 + FILL_V 5 + FILL_V 6 + FILL_V 7 + FILL_V 8 + FILL_V 9 + FILL_V 10 + FILL_V 11 + FILL_V 12 + FILL_V 13 + FILL_V 14 + FILL_V 15 + FILL_V 16 + FILL_V 17 + FILL_V 18 + FILL_V 19 + FILL_V 20 + FILL_V 21 + FILL_V 22 + FILL_V 23 + FILL_V 24 + FILL_V 25 + FILL_V 26 + FILL_V 27 + FILL_V 28 + FILL_V 29 + FILL_V 30 + FILL_V 31 + addi r4, r3, 0x700 + mtvrsave r4 +#endif + /* Check */ check: mfcr r4 @@ -226,12 +426,194 @@ check: bne restore cmpw r31, r1 bne restore + +#ifdef PPC_MULTILIB_FPU +.macro CHECK_F i + stfd \i, FTMP_OFFSET(r1) + lwz r5, FTMP_OFFSET(r1) + addi r4, r3, 0x100 + \i + cmpw r5, r4 + bne restore + lwz r5, FTMP_OFFSET + 4(r1) + addi r4, r3, 0x200 + \i + cmpw r5, r4 + bne restore +.endm + + /* Check FPSCR */ + stfd f0, FTMP_OFFSET(r1) + mffs f0 + stfd f0, FTMP2_OFFSET(r1) + lwz r4, FTMP2_OFFSET + 4(r1) + lwz r5, FPSCR_OFFSET + 4(r1) + cmpw r5, r4 + bne restore + lfd f0, FTMP_OFFSET(r1) + + CHECK_F 0 + CHECK_F 1 + CHECK_F 2 + CHECK_F 3 + CHECK_F 4 + CHECK_F 5 + CHECK_F 6 + CHECK_F 7 + CHECK_F 8 + CHECK_F 9 + CHECK_F 10 + CHECK_F 11 + CHECK_F 12 + CHECK_F 13 + CHECK_F 14 + CHECK_F 15 + CHECK_F 16 + CHECK_F 17 + CHECK_F 18 + CHECK_F 19 + CHECK_F 20 + CHECK_F 21 + CHECK_F 22 + CHECK_F 23 + CHECK_F 24 + CHECK_F 25 + CHECK_F 26 + CHECK_F 27 + CHECK_F 28 + CHECK_F 29 + CHECK_F 30 + CHECK_F 31 +#endif + +#ifdef PPC_MULTILIB_ALTIVEC +.macro CHECK_V i + li r4, VTMP_OFFSET + stvx \i, r1, r4 + lwz r5, VTMP_OFFSET(r1) + addi r4, r3, 0x300 + \i + cmpw r5, r4 + bne restore + lwz r5, VTMP_OFFSET + 4(r1) + addi r4, r3, 0x400 + \i + cmpw r5, r4 + bne restore + lwz r5, VTMP_OFFSET + 8(r1) + addi r4, r3, 0x500 + \i + cmpw r5, r4 + bne restore + lwz r5, VTMP_OFFSET + 12(r1) + addi r4, r3, 0x600 + \i + cmpw r5, r4 + bne restore +.endm + + /* Check VSCR */ + li r4, VTMP_OFFSET + stvx v0, r1, r4 + mfvscr v0 + li r4, VTMP2_OFFSET + stvewx v0, r1, r4 + lwz r4, VTMP2_OFFSET(r1) + lwz r5, VSCR_OFFSET(r1) + cmpw r5, r4 + bne restore + li r4, VTMP_OFFSET + lvx v0, r1, r4 + + CHECK_V 0 + CHECK_V 1 + CHECK_V 2 + CHECK_V 3 + CHECK_V 4 + CHECK_V 5 + CHECK_V 6 + CHECK_V 7 + CHECK_V 8 + CHECK_V 9 + CHECK_V 10 + CHECK_V 11 + CHECK_V 12 + CHECK_V 13 + CHECK_V 14 + CHECK_V 15 + CHECK_V 16 + CHECK_V 17 + CHECK_V 18 + CHECK_V 19 + CHECK_V 20 + CHECK_V 21 + CHECK_V 22 + CHECK_V 23 + CHECK_V 24 + CHECK_V 25 + CHECK_V 26 + CHECK_V 27 + CHECK_V 28 + CHECK_V 29 + CHECK_V 30 + CHECK_V 31 + mfvrsave r5 + addi r4, r3, 0x700 + cmpw r5, r4 + bne restore +#endif + mtcr r29 addi r5, r3, 1 b check /* Restore */ restore: + +#ifdef PPC_MULTILIB_ALTIVEC + lwz r0, VRSAVE_OFFSET(r1) + mtvrsave r0 + li r0, V31_OFFSET + lvx v31, r1, r0 + li r0, V30_OFFSET + lvx v30, r1, r0 + li r0, V29_OFFSET + lvx v29, r1, r0 + li r0, V28_OFFSET + lvx v28, r1, r0 + li r0, V27_OFFSET + lvx v27, r1, r0 + li r0, V26_OFFSET + lvx v26, r1, r0 + li r0, V25_OFFSET + lvx v25, r1, r0 + li r0, V24_OFFSET + lvx v24, r1, r0 + li r0, V23_OFFSET + lvx v23, r1, r0 + li r0, V22_OFFSET + lvx v22, r1, r0 + li r0, V21_OFFSET + lvx v21, r1, r0 + li r0, V20_OFFSET + lvx v20, r1, r0 +#endif + +#ifdef PPC_MULTILIB_FPU + lfd f31, F31_OFFSET(r1) + lfd f30, F30_OFFSET(r1) + lfd f29, F29_OFFSET(r1) + lfd f28, F28_OFFSET(r1) + lfd f27, F27_OFFSET(r1) + lfd f26, F26_OFFSET(r1) + lfd f25, F25_OFFSET(r1) + lfd f24, F24_OFFSET(r1) + lfd f23, F23_OFFSET(r1) + lfd f22, F22_OFFSET(r1) + lfd f21, F21_OFFSET(r1) + lfd f20, F20_OFFSET(r1) + lfd f19, F19_OFFSET(r1) + lfd f18, F18_OFFSET(r1) + lfd f17, F17_OFFSET(r1) + lfd f16, F16_OFFSET(r1) + lfd f15, F15_OFFSET(r1) + lfd f14, F14_OFFSET(r1) +#endif + lwz r31, GPR31_OFFSET(r1) lwz r30, GPR30_OFFSET(r1) lwz r29, GPR29_OFFSET(r1) -- cgit v1.2.3