summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-12-23 14:18:06 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-01-13 11:37:28 +0100
commit3e2647a7146d4b972c6a0290e6657bab0de18afa (patch)
tree027f8a7d676d3ae80950344b3891072e2ca0a736 /cpukit
parentbsps/powerpc: Use e500 exc categories for e6500 (diff)
downloadrtems-3e2647a7146d4b972c6a0290e6657bab0de18afa.tar.bz2
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.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/score/cpu/powerpc/cpu.c41
-rw-r--r--cpukit/score/cpu/powerpc/ppc-context-validate.S386
-rw-r--r--cpukit/score/cpu/powerpc/ppc-context-volatile-clobber.S93
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/cpu.h176
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/powerpc.h12
5 files changed, 700 insertions, 8 deletions
diff --git a/cpukit/score/cpu/powerpc/cpu.c b/cpukit/score/cpu/powerpc/cpu.c
index 53b4eaa247..5383a8ee24 100644
--- a/cpukit/score/cpu/powerpc/cpu.c
+++ b/cpukit/score/cpu/powerpc/cpu.c
@@ -57,6 +57,47 @@ PPC_ASSERT_OFFSET(gpr2, GPR2);
PPC_ASSERT_OFFSET(is_executing, IS_EXECUTING);
#endif
+#ifdef PPC_MULTILIB_ALTIVEC
+ RTEMS_STATIC_ASSERT(
+ PPC_CONTEXT_OFFSET_V20 % 16 == 0,
+ ppc_context_altivec
+ );
+ PPC_ASSERT_OFFSET(v20, V20);
+ PPC_ASSERT_OFFSET(v21, V21);
+ PPC_ASSERT_OFFSET(v22, V22);
+ PPC_ASSERT_OFFSET(v23, V23);
+ PPC_ASSERT_OFFSET(v24, V24);
+ PPC_ASSERT_OFFSET(v25, V25);
+ PPC_ASSERT_OFFSET(v26, V26);
+ PPC_ASSERT_OFFSET(v27, V27);
+ PPC_ASSERT_OFFSET(v28, V28);
+ PPC_ASSERT_OFFSET(v29, V29);
+ PPC_ASSERT_OFFSET(v30, V30);
+ PPC_ASSERT_OFFSET(v31, V31);
+ PPC_ASSERT_OFFSET(vrsave, VRSAVE);
+#endif
+
+#ifdef PPC_MULTILIB_FPU
+ PPC_ASSERT_OFFSET(f14, F14);
+ PPC_ASSERT_OFFSET(f15, F15);
+ PPC_ASSERT_OFFSET(f16, F16);
+ PPC_ASSERT_OFFSET(f17, F17);
+ PPC_ASSERT_OFFSET(f18, F18);
+ PPC_ASSERT_OFFSET(f19, F19);
+ PPC_ASSERT_OFFSET(f20, F20);
+ PPC_ASSERT_OFFSET(f21, F21);
+ PPC_ASSERT_OFFSET(f22, F22);
+ PPC_ASSERT_OFFSET(f23, F23);
+ PPC_ASSERT_OFFSET(f24, F24);
+ PPC_ASSERT_OFFSET(f25, F25);
+ PPC_ASSERT_OFFSET(f26, F26);
+ PPC_ASSERT_OFFSET(f27, F27);
+ PPC_ASSERT_OFFSET(f28, F28);
+ PPC_ASSERT_OFFSET(f29, F29);
+ PPC_ASSERT_OFFSET(f30, F30);
+ PPC_ASSERT_OFFSET(f31, F31);
+#endif
+
RTEMS_STATIC_ASSERT(
sizeof(Context_Control) % PPC_DEFAULT_CACHE_LINE_SIZE == 0,
ppc_context_size
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)
diff --git a/cpukit/score/cpu/powerpc/ppc-context-volatile-clobber.S b/cpukit/score/cpu/powerpc/ppc-context-volatile-clobber.S
index 14a6047837..17bcb92d7d 100644
--- a/cpukit/score/cpu/powerpc/ppc-context-volatile-clobber.S
+++ b/cpukit/score/cpu/powerpc/ppc-context-volatile-clobber.S
@@ -22,6 +22,99 @@
_CPU_Context_volatile_clobber:
+#ifdef PPC_MULTILIB_FPU
+.macro CLOBBER_F i
+ addi r4, r3, 0x100 + \i
+ stw r4, 16(r1)
+ addi r4, r3, 0x200 + \i
+ stw r4, 16 + 4(r1)
+ lfd \i, 16(r1)
+.endm
+
+ stwu r1, -32(r1)
+
+ /* Negate FPSCR[FPRF] bits */
+ mffs f0
+ stfd f0, 16(r1)
+ lwz r0, 20(r1)
+ nor r3, r0, r0
+ rlwinm r0, r0, 0, 20, 14
+ rlwinm r3, r3, 0, 15, 19
+ or r0, r3, r0
+ stw r0, 20(r1)
+ lfd f0, 16(r1)
+ mtfsf 0xff, f0
+
+ CLOBBER_F 0
+ CLOBBER_F 1
+ CLOBBER_F 2
+ CLOBBER_F 3
+ CLOBBER_F 4
+ CLOBBER_F 5
+ CLOBBER_F 6
+ CLOBBER_F 7
+ CLOBBER_F 8
+ CLOBBER_F 9
+ CLOBBER_F 10
+ CLOBBER_F 11
+ CLOBBER_F 12
+ CLOBBER_F 13
+ addi r1, r1, 32
+#endif
+
+#ifdef PPC_MULTILIB_ALTIVEC
+.macro CLOBBER_V i
+ addi r4, r3, 0x300 + \i
+ stw r4, 16(r1)
+ addi r4, r3, 0x400 + \i
+ stw r4, 16 + 4(r1)
+ addi r4, r3, 0x500 + \i
+ stw r4, 16 + 8(r1)
+ addi r4, r3, 0x600 + \i
+ stw r4, 16 + 12(r1)
+ li r4, 16
+ lvx \i, r1, r4
+.endm
+
+ stwu r1, -32(r1)
+
+ /* Negate VSCR[SAT] bit */
+ mfvscr v0
+ li r3, 16
+ stvewx v0, r1, r3
+ lwz r0, 16(r1)
+ nor r3, r0, r0
+ rlwinm r0, r0, 0, 0, 30
+ rlwinm r3, r3, 0, 31, 31
+ or r0, r3, r0
+ stw r0, 16(r1)
+ li r3, 16
+ lvewx v0, r1, r3
+ mtvscr v0
+
+ CLOBBER_V 0
+ CLOBBER_V 1
+ CLOBBER_V 2
+ CLOBBER_V 3
+ CLOBBER_V 4
+ CLOBBER_V 5
+ CLOBBER_V 6
+ CLOBBER_V 7
+ CLOBBER_V 8
+ CLOBBER_V 9
+ CLOBBER_V 10
+ CLOBBER_V 11
+ CLOBBER_V 12
+ CLOBBER_V 13
+ CLOBBER_V 14
+ CLOBBER_V 15
+ CLOBBER_V 16
+ CLOBBER_V 17
+ CLOBBER_V 18
+ CLOBBER_V 19
+ addi r1, r1, 32
+#endif
+
addi r4, r3, 10
rlwinm r4, r4, 0, 20, 7
mfcr r5
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
index 26255a637c..98aa4e4bf3 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -300,10 +300,22 @@ typedef struct {
PPC_GPR_TYPE gpr30;
PPC_GPR_TYPE gpr31;
uint32_t gpr2;
- #ifdef RTEMS_SMP
- volatile uint32_t is_executing;
- #endif
- #ifdef __ALTIVEC__
+ #if defined(PPC_MULTILIB_ALTIVEC)
+ uint32_t reserved_for_alignment;
+ uint8_t v20[16];
+ uint8_t v21[16];
+ uint8_t v22[16];
+ uint8_t v23[16];
+ uint8_t v24[16];
+ uint8_t v25[16];
+ uint8_t v26[16];
+ uint8_t v27[16];
+ uint8_t v28[16];
+ uint8_t v29[16];
+ uint8_t v30[16];
+ uint8_t v31[16];
+ uint32_t vrsave;
+ #elif defined(__ALTIVEC__)
/*
* 12 non-volatile vector registers, cache-aligned area for vscr/vrsave
* and padding to ensure cache-alignment. Unfortunately, we can't verify
@@ -315,6 +327,34 @@ typedef struct {
*/
uint8_t altivec[16*12 + 32 + PPC_DEFAULT_CACHE_LINE_SIZE];
#endif
+ #if defined(PPC_MULTILIB_FPU)
+ double f14;
+ double f15;
+ double f16;
+ double f17;
+ double f18;
+ double f19;
+ double f20;
+ double f21;
+ double f22;
+ double f23;
+ double f24;
+ double f25;
+ double f26;
+ double f27;
+ double f28;
+ double f29;
+ double f30;
+ double f31;
+ #endif
+ #if defined(RTEMS_SMP)
+ /*
+ * This item is at the structure end, so that we can use dcbz for the
+ * previous items to optimize the context switch. We must not set this
+ * item to zero via the dcbz.
+ */
+ volatile uint32_t is_executing;
+ #endif
} ppc_context;
typedef struct {
@@ -386,8 +426,60 @@ static inline ppc_context *ppc_get_context( const Context_Control *context )
#define PPC_CONTEXT_OFFSET_GPR31 PPC_CONTEXT_GPR_OFFSET( 31 )
#define PPC_CONTEXT_OFFSET_GPR2 PPC_CONTEXT_GPR_OFFSET( 32 )
+#ifdef PPC_MULTILIB_ALTIVEC
+ #define PPC_CONTEXT_OFFSET_V( v ) \
+ ( ( ( v ) - 20 ) * 16 + PPC_DEFAULT_CACHE_LINE_SIZE + 96 )
+ #define PPC_CONTEXT_OFFSET_V20 PPC_CONTEXT_OFFSET_V( 20 )
+ #define PPC_CONTEXT_OFFSET_V21 PPC_CONTEXT_OFFSET_V( 21 )
+ #define PPC_CONTEXT_OFFSET_V22 PPC_CONTEXT_OFFSET_V( 22 )
+ #define PPC_CONTEXT_OFFSET_V23 PPC_CONTEXT_OFFSET_V( 23 )
+ #define PPC_CONTEXT_OFFSET_V24 PPC_CONTEXT_OFFSET_V( 24 )
+ #define PPC_CONTEXT_OFFSET_V25 PPC_CONTEXT_OFFSET_V( 25 )
+ #define PPC_CONTEXT_OFFSET_V26 PPC_CONTEXT_OFFSET_V( 26 )
+ #define PPC_CONTEXT_OFFSET_V27 PPC_CONTEXT_OFFSET_V( 27 )
+ #define PPC_CONTEXT_OFFSET_V28 PPC_CONTEXT_OFFSET_V( 28 )
+ #define PPC_CONTEXT_OFFSET_V29 PPC_CONTEXT_OFFSET_V( 29 )
+ #define PPC_CONTEXT_OFFSET_V30 PPC_CONTEXT_OFFSET_V( 30 )
+ #define PPC_CONTEXT_OFFSET_V31 PPC_CONTEXT_OFFSET_V( 31 )
+ #define PPC_CONTEXT_OFFSET_VRSAVE PPC_CONTEXT_OFFSET_V( 32 )
+ #define PPC_CONTEXT_OFFSET_F( f ) \
+ ( ( ( f ) - 14 ) * 8 + PPC_DEFAULT_CACHE_LINE_SIZE + 296 )
+#else
+ #define PPC_CONTEXT_OFFSET_F( f ) \
+ ( ( ( f ) - 14 ) * 8 + PPC_DEFAULT_CACHE_LINE_SIZE + 96 )
+#endif
+
+#ifdef PPC_MULTILIB_FPU
+ #define PPC_CONTEXT_OFFSET_F14 PPC_CONTEXT_OFFSET_F( 14 )
+ #define PPC_CONTEXT_OFFSET_F15 PPC_CONTEXT_OFFSET_F( 15 )
+ #define PPC_CONTEXT_OFFSET_F16 PPC_CONTEXT_OFFSET_F( 16 )
+ #define PPC_CONTEXT_OFFSET_F17 PPC_CONTEXT_OFFSET_F( 17 )
+ #define PPC_CONTEXT_OFFSET_F18 PPC_CONTEXT_OFFSET_F( 18 )
+ #define PPC_CONTEXT_OFFSET_F19 PPC_CONTEXT_OFFSET_F( 19 )
+ #define PPC_CONTEXT_OFFSET_F20 PPC_CONTEXT_OFFSET_F( 20 )
+ #define PPC_CONTEXT_OFFSET_F21 PPC_CONTEXT_OFFSET_F( 21 )
+ #define PPC_CONTEXT_OFFSET_F22 PPC_CONTEXT_OFFSET_F( 22 )
+ #define PPC_CONTEXT_OFFSET_F23 PPC_CONTEXT_OFFSET_F( 23 )
+ #define PPC_CONTEXT_OFFSET_F24 PPC_CONTEXT_OFFSET_F( 24 )
+ #define PPC_CONTEXT_OFFSET_F25 PPC_CONTEXT_OFFSET_F( 25 )
+ #define PPC_CONTEXT_OFFSET_F26 PPC_CONTEXT_OFFSET_F( 26 )
+ #define PPC_CONTEXT_OFFSET_F27 PPC_CONTEXT_OFFSET_F( 27 )
+ #define PPC_CONTEXT_OFFSET_F28 PPC_CONTEXT_OFFSET_F( 28 )
+ #define PPC_CONTEXT_OFFSET_F29 PPC_CONTEXT_OFFSET_F( 29 )
+ #define PPC_CONTEXT_OFFSET_F30 PPC_CONTEXT_OFFSET_F( 30 )
+ #define PPC_CONTEXT_OFFSET_F31 PPC_CONTEXT_OFFSET_F( 31 )
+#endif
+
+#if defined(PPC_MULTILIB_FPU)
+ #define PPC_CONTEXT_VOLATILE_SIZE PPC_CONTEXT_OFFSET_F( 32 )
+#elif defined(PPC_MULTILIB_ALTIVEC)
+ #define PPC_CONTEXT_VOLATILE_SIZE (PPC_CONTEXT_OFFSET_VRSAVE + 4)
+#else
+ #define PPC_CONTEXT_VOLATILE_SIZE (PPC_CONTEXT_GPR_OFFSET( 32 ) + 4)
+#endif
+
#ifdef RTEMS_SMP
- #define PPC_CONTEXT_OFFSET_IS_EXECUTING (PPC_CONTEXT_GPR_OFFSET( 32 ) + 4)
+ #define PPC_CONTEXT_OFFSET_IS_EXECUTING PPC_CONTEXT_VOLATILE_SIZE
#endif
#ifndef ASM
@@ -1101,6 +1193,80 @@ typedef struct {
PPC_GPR_TYPE GPR29;
PPC_GPR_TYPE GPR30;
PPC_GPR_TYPE GPR31;
+ #if defined(PPC_MULTILIB_ALTIVEC) || defined(PPC_MULTILIB_FPU)
+ uint32_t reserved_for_alignment;
+ #endif
+ #ifdef PPC_MULTILIB_ALTIVEC
+ uint32_t VSCR;
+ uint32_t VRSAVE;
+ uint8_t V0[16];
+ uint8_t V1[16];
+ uint8_t V2[16];
+ uint8_t V3[16];
+ uint8_t V4[16];
+ uint8_t V5[16];
+ uint8_t V6[16];
+ uint8_t V7[16];
+ uint8_t V8[16];
+ uint8_t V9[16];
+ uint8_t V10[16];
+ uint8_t V11[16];
+ uint8_t V12[16];
+ uint8_t V13[16];
+ uint8_t V14[16];
+ uint8_t V15[16];
+ uint8_t V16[16];
+ uint8_t V17[16];
+ uint8_t V18[16];
+ uint8_t V19[16];
+ uint8_t V20[16];
+ uint8_t V21[16];
+ uint8_t V22[16];
+ uint8_t V23[16];
+ uint8_t V24[16];
+ uint8_t V25[16];
+ uint8_t V26[16];
+ uint8_t V27[16];
+ uint8_t V28[16];
+ uint8_t V29[16];
+ uint8_t V30[16];
+ uint8_t V31[16];
+ #endif
+ #ifdef PPC_MULTILIB_FPU
+ double F0;
+ double F1;
+ double F2;
+ double F3;
+ double F4;
+ double F5;
+ double F6;
+ double F7;
+ double F8;
+ double F9;
+ double F10;
+ double F11;
+ double F12;
+ double F13;
+ double F14;
+ double F15;
+ double F16;
+ double F17;
+ double F18;
+ double F19;
+ double F20;
+ double F21;
+ double F22;
+ double F23;
+ double F24;
+ double F25;
+ double F26;
+ double F27;
+ double F28;
+ double F29;
+ double F30;
+ double F31;
+ uint64_t FPSCR;
+ #endif
} CPU_Exception_frame;
void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
diff --git a/cpukit/score/cpu/powerpc/rtems/score/powerpc.h b/cpukit/score/cpu/powerpc/rtems/score/powerpc.h
index 7eaa237125..c640b2f783 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/powerpc.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/powerpc.h
@@ -120,12 +120,22 @@ extern "C" {
* Assume PPC_HAS_FPU to be a synonym for _SOFT_FLOAT.
*/
-#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__) /* e500 has unified integer/FP registers */
+#if defined(_SOFT_FLOAT) \
+ || defined(__NO_FPRS__) /* e500 has unified integer/FP registers */ \
+ || defined(__PPC_CPU_E6500__)
#define PPC_HAS_FPU 0
#else
#define PPC_HAS_FPU 1
#endif
+#if defined(__PPC_CPU_E6500__) && defined(__ALTIVEC__)
+#define PPC_MULTILIB_ALTIVEC
+#endif
+
+#if defined(__PPC_CPU_E6500__) && !defined(_SOFT_FLOAT)
+#define PPC_MULTILIB_FPU
+#endif
+
/*
* Unless specified above, If the model has FP support, it is assumed to
* support doubles (8-byte floating point numbers).