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. --- .../new-exceptions/bspsupport/ppc_exc_asm_macros.h | 247 ++++++++++++- .../bspsupport/ppc_exc_async_normal.S | 149 +++++++- .../new-exceptions/bspsupport/ppc_exc_initialize.c | 148 ++++++++ .../new-exceptions/bspsupport/ppc_exc_print.c | 36 ++ .../powerpc/new-exceptions/bspsupport/vectors.h | 106 +++++- c/src/lib/libcpu/powerpc/new-exceptions/cpu.c | 17 +- c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S | 130 ++++++- cpukit/score/cpu/powerpc/cpu.c | 41 +++ cpukit/score/cpu/powerpc/ppc-context-validate.S | 386 ++++++++++++++++++++- .../cpu/powerpc/ppc-context-volatile-clobber.S | 93 +++++ cpukit/score/cpu/powerpc/rtems/score/cpu.h | 176 +++++++++- cpukit/score/cpu/powerpc/rtems/score/powerpc.h | 12 +- 12 files changed, 1521 insertions(+), 20 deletions(-) diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h index 0e3bc96895..c89046619b 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h @@ -426,6 +426,19 @@ wrap_no_save_frame_register_\_FLVR: /* Check exception type and remember it in non-volatile CR_TYPE */ cmpwi CR_TYPE, VECTOR_REGISTER, 0 +#if defined(PPC_MULTILIB_FPU) || defined(PPC_MULTILIB_ALTIVEC) + /* Enable FPU and/or AltiVec */ + mfmsr SCRATCH_REGISTER_0 +#ifdef PPC_MULTILIB_FPU + ori SCRATCH_REGISTER_0, SCRATCH_REGISTER_0, MSR_FP +#endif +#ifdef PPC_MULTILIB_ALTIVEC + oris SCRATCH_REGISTER_0, SCRATCH_REGISTER_0, MSR_VE >> 16 +#endif + mtmsr SCRATCH_REGISTER_0 + isync +#endif + /* * Depending on the exception type we do now save the non-volatile * registers or disable thread dispatching and switch to the ISR stack. @@ -545,7 +558,7 @@ wrap_change_msr_done_\_FLVR: #endif /* PPC_EXC_CONFIG_BOOKE_ONLY */ -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC) LA SCRATCH_REGISTER_0, _CPU_save_altivec_volatile mtctr SCRATCH_REGISTER_0 addi r3, FRAME_REGISTER, EXC_VEC_OFFSET @@ -566,6 +579,71 @@ wrap_change_msr_done_\_FLVR: lwz VECTOR_REGISTER, EXCEPTION_NUMBER_OFFSET(FRAME_REGISTER) #endif +#ifdef PPC_MULTILIB_ALTIVEC + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(0) + stvx v0, FRAME_REGISTER, SCRATCH_REGISTER_0 + mfvscr v0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(1) + stvx v1, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(2) + stvx v2, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(3) + stvx v3, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(4) + stvx v4, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(5) + stvx v5, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(6) + stvx v6, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(7) + stvx v7, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(8) + stvx v8, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(9) + stvx v9, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(0) + stvx v10, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(11) + stvx v11, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(12) + stvx v12, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(13) + stvx v13, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(14) + stvx v14, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(15) + stvx v15, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(16) + stvx v16, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(17) + stvx v17, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(18) + stvx v18, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(19) + stvx v19, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VSCR_OFFSET + stvewx v0, r1, SCRATCH_REGISTER_0 +#endif + +#ifdef PPC_MULTILIB_FPU + stfd f0, PPC_EXC_FR_OFFSET(0)(FRAME_REGISTER) + mffs f0 + stfd f1, PPC_EXC_FR_OFFSET(1)(FRAME_REGISTER) + stfd f2, PPC_EXC_FR_OFFSET(2)(FRAME_REGISTER) + stfd f3, PPC_EXC_FR_OFFSET(3)(FRAME_REGISTER) + stfd f4, PPC_EXC_FR_OFFSET(4)(FRAME_REGISTER) + stfd f5, PPC_EXC_FR_OFFSET(5)(FRAME_REGISTER) + stfd f6, PPC_EXC_FR_OFFSET(6)(FRAME_REGISTER) + stfd f7, PPC_EXC_FR_OFFSET(7)(FRAME_REGISTER) + stfd f8, PPC_EXC_FR_OFFSET(8)(FRAME_REGISTER) + stfd f9, PPC_EXC_FR_OFFSET(9)(FRAME_REGISTER) + stfd f10, PPC_EXC_FR_OFFSET(10)(FRAME_REGISTER) + stfd f11, PPC_EXC_FR_OFFSET(11)(FRAME_REGISTER) + stfd f12, PPC_EXC_FR_OFFSET(12)(FRAME_REGISTER) + stfd f13, PPC_EXC_FR_OFFSET(13)(FRAME_REGISTER) + stfd f0, PPC_EXC_FPSCR_OFFSET(FRAME_REGISTER) +#endif + /* * Call high level exception handler */ @@ -666,13 +744,78 @@ wrap_handler_done_\_FLVR: wrap_thread_dispatching_done_\_FLVR: -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC) LA SCRATCH_REGISTER_0, _CPU_load_altivec_volatile mtctr SCRATCH_REGISTER_0 addi r3, FRAME_REGISTER, EXC_VEC_OFFSET bctrl #endif +#ifdef PPC_MULTILIB_ALTIVEC + li SCRATCH_REGISTER_0, PPC_EXC_MIN_VSCR_OFFSET + lvewx v0, r1, SCRATCH_REGISTER_0 + mtvscr v0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(0) + lvx v0, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(1) + lvx v1, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(2) + lvx v2, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(3) + lvx v3, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(4) + lvx v4, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(5) + lvx v5, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(6) + lvx v6, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(7) + lvx v7, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(8) + lvx v8, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(9) + lvx v9, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(0) + lvx v10, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(11) + lvx v11, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(12) + lvx v12, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(13) + lvx v13, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(14) + lvx v14, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(15) + lvx v15, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(16) + lvx v16, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(17) + lvx v17, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(18) + lvx v18, FRAME_REGISTER, SCRATCH_REGISTER_0 + li SCRATCH_REGISTER_0, PPC_EXC_VR_OFFSET(19) + lvx v19, FRAME_REGISTER, SCRATCH_REGISTER_0 +#endif + +#ifdef PPC_MULTILIB_FPU + lfd f0, PPC_EXC_FPSCR_OFFSET(FRAME_REGISTER) + mtfsf 0xff, f0 + lfd f0, PPC_EXC_FR_OFFSET(0)(FRAME_REGISTER) + lfd f1, PPC_EXC_FR_OFFSET(1)(FRAME_REGISTER) + lfd f2, PPC_EXC_FR_OFFSET(2)(FRAME_REGISTER) + lfd f3, PPC_EXC_FR_OFFSET(3)(FRAME_REGISTER) + lfd f4, PPC_EXC_FR_OFFSET(4)(FRAME_REGISTER) + lfd f5, PPC_EXC_FR_OFFSET(5)(FRAME_REGISTER) + lfd f6, PPC_EXC_FR_OFFSET(6)(FRAME_REGISTER) + lfd f7, PPC_EXC_FR_OFFSET(7)(FRAME_REGISTER) + lfd f8, PPC_EXC_FR_OFFSET(8)(FRAME_REGISTER) + lfd f9, PPC_EXC_FR_OFFSET(9)(FRAME_REGISTER) + lfd f10, PPC_EXC_FR_OFFSET(10)(FRAME_REGISTER) + lfd f11, PPC_EXC_FR_OFFSET(11)(FRAME_REGISTER) + lfd f12, PPC_EXC_FR_OFFSET(12)(FRAME_REGISTER) + lfd f13, PPC_EXC_FR_OFFSET(13)(FRAME_REGISTER) +#endif + #ifndef PPC_EXC_CONFIG_BOOKE_ONLY /* Restore MSR? */ @@ -801,6 +944,56 @@ wrap_save_non_volatile_regs_\_FLVR: stw r31, GPR31_OFFSET(FRAME_REGISTER) #endif +#ifdef PPC_MULTILIB_ALTIVEC + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(20) + stvx v20, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(21) + stvx v21, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(22) + stvx v22, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(23) + stvx v23, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(24) + stvx v24, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(25) + stvx v25, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(26) + stvx v26, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(27) + stvx v27, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(28) + stvx v28, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(29) + stvx v29, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(30) + stvx v30, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(31) + stvx v31, FRAME_REGISTER, SCRATCH_REGISTER_1 + mfvrsave SCRATCH_REGISTER_1 + stw SCRATCH_REGISTER_1, PPC_EXC_VRSAVE_OFFSET(FRAME_REGISTER) +#endif + +#ifdef PPC_MULTILIB_FPU + stfd f14, PPC_EXC_FR_OFFSET(14)(FRAME_REGISTER) + stfd f15, PPC_EXC_FR_OFFSET(15)(FRAME_REGISTER) + stfd f16, PPC_EXC_FR_OFFSET(16)(FRAME_REGISTER) + stfd f17, PPC_EXC_FR_OFFSET(17)(FRAME_REGISTER) + stfd f18, PPC_EXC_FR_OFFSET(18)(FRAME_REGISTER) + stfd f19, PPC_EXC_FR_OFFSET(19)(FRAME_REGISTER) + stfd f20, PPC_EXC_FR_OFFSET(20)(FRAME_REGISTER) + stfd f21, PPC_EXC_FR_OFFSET(21)(FRAME_REGISTER) + stfd f22, PPC_EXC_FR_OFFSET(22)(FRAME_REGISTER) + stfd f23, PPC_EXC_FR_OFFSET(23)(FRAME_REGISTER) + stfd f24, PPC_EXC_FR_OFFSET(24)(FRAME_REGISTER) + stfd f25, PPC_EXC_FR_OFFSET(25)(FRAME_REGISTER) + stfd f26, PPC_EXC_FR_OFFSET(26)(FRAME_REGISTER) + stfd f27, PPC_EXC_FR_OFFSET(27)(FRAME_REGISTER) + stfd f28, PPC_EXC_FR_OFFSET(28)(FRAME_REGISTER) + stfd f29, PPC_EXC_FR_OFFSET(29)(FRAME_REGISTER) + stfd f30, PPC_EXC_FR_OFFSET(30)(FRAME_REGISTER) + stfd f31, PPC_EXC_FR_OFFSET(31)(FRAME_REGISTER) +#endif + b wrap_disable_thread_dispatching_done_\_FLVR wrap_restore_non_volatile_regs_\_FLVR: @@ -839,6 +1032,56 @@ wrap_restore_non_volatile_regs_\_FLVR: /* Restore stack pointer */ stw SCRATCH_REGISTER_0, 0(r1) +#ifdef PPC_MULTILIB_ALTIVEC + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(20) + lvx v20, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(21) + lvx v21, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(22) + lvx v22, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(23) + lvx v23, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(24) + lvx v24, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(25) + lvx v25, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(26) + lvx v26, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(27) + lvx v27, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(28) + lvx v28, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(29) + lvx v29, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(30) + lvx v30, FRAME_REGISTER, SCRATCH_REGISTER_1 + li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(31) + lvx v31, FRAME_REGISTER, SCRATCH_REGISTER_1 + lwz SCRATCH_REGISTER_1, PPC_EXC_VRSAVE_OFFSET(FRAME_REGISTER) + mtvrsave SCRATCH_REGISTER_1 +#endif + +#ifdef PPC_MULTILIB_FPU + lfd f14, PPC_EXC_FR_OFFSET(14)(FRAME_REGISTER) + lfd f15, PPC_EXC_FR_OFFSET(15)(FRAME_REGISTER) + lfd f16, PPC_EXC_FR_OFFSET(16)(FRAME_REGISTER) + lfd f17, PPC_EXC_FR_OFFSET(17)(FRAME_REGISTER) + lfd f18, PPC_EXC_FR_OFFSET(18)(FRAME_REGISTER) + lfd f19, PPC_EXC_FR_OFFSET(19)(FRAME_REGISTER) + lfd f20, PPC_EXC_FR_OFFSET(20)(FRAME_REGISTER) + lfd f21, PPC_EXC_FR_OFFSET(21)(FRAME_REGISTER) + lfd f22, PPC_EXC_FR_OFFSET(22)(FRAME_REGISTER) + lfd f23, PPC_EXC_FR_OFFSET(23)(FRAME_REGISTER) + lfd f24, PPC_EXC_FR_OFFSET(24)(FRAME_REGISTER) + lfd f25, PPC_EXC_FR_OFFSET(25)(FRAME_REGISTER) + lfd f26, PPC_EXC_FR_OFFSET(26)(FRAME_REGISTER) + lfd f27, PPC_EXC_FR_OFFSET(27)(FRAME_REGISTER) + lfd f28, PPC_EXC_FR_OFFSET(28)(FRAME_REGISTER) + lfd f29, PPC_EXC_FR_OFFSET(29)(FRAME_REGISTER) + lfd f30, PPC_EXC_FR_OFFSET(30)(FRAME_REGISTER) + lfd f31, PPC_EXC_FR_OFFSET(31)(FRAME_REGISTER) +#endif + b wrap_thread_dispatching_done_\_FLVR wrap_call_global_handler_\_FLVR: diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S index a1ae8931d7..ae575c5825 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2011-2015 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -105,6 +105,19 @@ ppc_exc_wrap_async_normal: isync #endif +#if defined(PPC_MULTILIB_FPU) || defined(PPC_MULTILIB_ALTIVEC) + /* Enable FPU and/or AltiVec */ + mfmsr FRAME_REGISTER +#ifdef PPC_MULTILIB_FPU + ori FRAME_REGISTER, FRAME_REGISTER, MSR_FP +#endif +#ifdef PPC_MULTILIB_ALTIVEC + oris FRAME_REGISTER, FRAME_REGISTER, MSR_VE >> 16 +#endif + mtmsr FRAME_REGISTER + isync +#endif + /* Move frame pointer to non-volatile FRAME_REGISTER */ mr FRAME_REGISTER, r1 @@ -176,6 +189,73 @@ ppc_exc_wrap_async_normal: evstdd SCRATCH_1_REGISTER, PPC_EXC_ACC_OFFSET(r1) #endif +#ifdef PPC_MULTILIB_ALTIVEC + /* Save volatile AltiVec context */ + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(0) + stvx v0, r1, SCRATCH_0_REGISTER + mfvscr v0 + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(1) + stvx v1, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(2) + stvx v2, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(3) + stvx v3, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(4) + stvx v4, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(5) + stvx v5, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(6) + stvx v6, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(7) + stvx v7, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(8) + stvx v8, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(9) + stvx v9, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(10) + stvx v10, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(11) + stvx v11, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(12) + stvx v12, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(13) + stvx v13, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(14) + stvx v14, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(15) + stvx v15, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(16) + stvx v16, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(17) + stvx v17, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(18) + stvx v18, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(19) + stvx v19, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VSCR_OFFSET + stvewx v0, r1, SCRATCH_0_REGISTER +#endif + +#ifdef PPC_MULTILIB_FPU + /* Save volatile FPU context */ + stfd f0, PPC_EXC_MIN_FR_OFFSET(0)(r1) + mffs f0 + stfd f1, PPC_EXC_MIN_FR_OFFSET(1)(r1) + stfd f2, PPC_EXC_MIN_FR_OFFSET(2)(r1) + stfd f3, PPC_EXC_MIN_FR_OFFSET(3)(r1) + stfd f4, PPC_EXC_MIN_FR_OFFSET(4)(r1) + stfd f5, PPC_EXC_MIN_FR_OFFSET(5)(r1) + stfd f6, PPC_EXC_MIN_FR_OFFSET(6)(r1) + stfd f7, PPC_EXC_MIN_FR_OFFSET(7)(r1) + stfd f8, PPC_EXC_MIN_FR_OFFSET(8)(r1) + stfd f9, PPC_EXC_MIN_FR_OFFSET(9)(r1) + stfd f10, PPC_EXC_MIN_FR_OFFSET(10)(r1) + stfd f11, PPC_EXC_MIN_FR_OFFSET(11)(r1) + stfd f12, PPC_EXC_MIN_FR_OFFSET(12)(r1) + stfd f13, PPC_EXC_MIN_FR_OFFSET(13)(r1) + stfd f0, PPC_EXC_MIN_FPSCR_OFFSET(r1) +#endif + /* Increment ISR nest level and thread dispatch disable level */ cmpwi ISR_NEST_REGISTER, 0 addi ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1 @@ -246,6 +326,73 @@ profiling_done: bl _Thread_Dispatch thread_dispatching_done: +#ifdef PPC_MULTILIB_ALTIVEC + /* Restore volatile AltiVec context */ + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VSCR_OFFSET + lvewx v0, r1, SCRATCH_0_REGISTER + mtvscr v0 + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(0) + lvx v0, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(1) + lvx v1, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(2) + lvx v2, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(3) + lvx v3, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(4) + lvx v4, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(5) + lvx v5, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(6) + lvx v6, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(7) + lvx v7, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(8) + lvx v8, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(9) + lvx v9, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(10) + lvx v10, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(11) + lvx v11, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(12) + lvx v12, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(13) + lvx v13, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(14) + lvx v14, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(15) + lvx v15, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(16) + lvx v16, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(17) + lvx v17, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(18) + lvx v18, r1, SCRATCH_0_REGISTER + li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(19) + lvx v19, r1, SCRATCH_0_REGISTER +#endif + +#ifdef PPC_MULTILIB_FPU + /* Restore volatile FPU context */ + lfd f0, PPC_EXC_MIN_FPSCR_OFFSET(r1) + mtfsf 0xff, f0 + lfd f0, PPC_EXC_MIN_FR_OFFSET(0)(r1) + lfd f1, PPC_EXC_MIN_FR_OFFSET(1)(r1) + lfd f2, PPC_EXC_MIN_FR_OFFSET(2)(r1) + lfd f3, PPC_EXC_MIN_FR_OFFSET(3)(r1) + lfd f4, PPC_EXC_MIN_FR_OFFSET(4)(r1) + lfd f5, PPC_EXC_MIN_FR_OFFSET(5)(r1) + lfd f6, PPC_EXC_MIN_FR_OFFSET(6)(r1) + lfd f7, PPC_EXC_MIN_FR_OFFSET(7)(r1) + lfd f8, PPC_EXC_MIN_FR_OFFSET(8)(r1) + lfd f9, PPC_EXC_MIN_FR_OFFSET(9)(r1) + lfd f10, PPC_EXC_MIN_FR_OFFSET(10)(r1) + lfd f11, PPC_EXC_MIN_FR_OFFSET(11)(r1) + lfd f12, PPC_EXC_MIN_FR_OFFSET(12)(r1) + lfd f13, PPC_EXC_MIN_FR_OFFSET(13)(r1) +#endif + #ifdef __SPE__ /* Load SPEFSCR and ACC */ lwz DISPATCH_LEVEL_REGISTER, PPC_EXC_SPEFSCR_OFFSET(r1) diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_initialize.c b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_initialize.c index ef978f8d57..54451afe03 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_initialize.c +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_initialize.c @@ -36,6 +36,15 @@ #define PPC_EXC_ASSERT_CANONIC_OFFSET(field) \ PPC_EXC_ASSERT_OFFSET(field, field ## _OFFSET) +#define PPC_EXC_MIN_ASSERT_OFFSET(field, off) \ + RTEMS_STATIC_ASSERT( \ + offsetof(ppc_exc_min_frame, field) + FRAME_LINK_SPACE == off, \ + ppc_exc_min_frame_offset_ ## field \ + ) + +#define PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(field) \ + PPC_EXC_MIN_ASSERT_OFFSET(field, field ## _OFFSET) + PPC_EXC_ASSERT_OFFSET(EXC_SRR0, SRR0_FRAME_OFFSET); PPC_EXC_ASSERT_OFFSET(EXC_SRR1, SRR1_FRAME_OFFSET); PPC_EXC_ASSERT_OFFSET(_EXC_number, EXCEPTION_NUMBER_OFFSET); @@ -80,6 +89,145 @@ PPC_EXC_ASSERT_CANONIC_OFFSET(GPR29); PPC_EXC_ASSERT_CANONIC_OFFSET(GPR30); PPC_EXC_ASSERT_CANONIC_OFFSET(GPR31); +PPC_EXC_MIN_ASSERT_OFFSET(EXC_SRR0, SRR0_FRAME_OFFSET); +PPC_EXC_MIN_ASSERT_OFFSET(EXC_SRR1, SRR1_FRAME_OFFSET); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(EXC_CR); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(EXC_CTR); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(EXC_XER); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(EXC_LR); +#ifdef __SPE__ + PPC_EXC_MIN_ASSERT_OFFSET(EXC_SPEFSCR, PPC_EXC_SPEFSCR_OFFSET); + PPC_EXC_MIN_ASSERT_OFFSET(EXC_ACC, PPC_EXC_ACC_OFFSET); +#endif +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR0); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR1); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR2); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR3); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR4); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR5); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR6); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR7); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR8); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR9); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR10); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR11); +PPC_EXC_MIN_ASSERT_CANONIC_OFFSET(GPR12); + +#ifdef PPC_MULTILIB_ALTIVEC +PPC_EXC_ASSERT_OFFSET(VSCR, PPC_EXC_VSCR_OFFSET); +PPC_EXC_ASSERT_OFFSET(VRSAVE, PPC_EXC_VRSAVE_OFFSET); +RTEMS_STATIC_ASSERT(PPC_EXC_VR_OFFSET(0) % 16 == 0, PPC_EXC_VR_OFFSET); +PPC_EXC_ASSERT_OFFSET(V0, PPC_EXC_VR_OFFSET(0)); +PPC_EXC_ASSERT_OFFSET(V1, PPC_EXC_VR_OFFSET(1)); +PPC_EXC_ASSERT_OFFSET(V2, PPC_EXC_VR_OFFSET(2)); +PPC_EXC_ASSERT_OFFSET(V3, PPC_EXC_VR_OFFSET(3)); +PPC_EXC_ASSERT_OFFSET(V4, PPC_EXC_VR_OFFSET(4)); +PPC_EXC_ASSERT_OFFSET(V5, PPC_EXC_VR_OFFSET(5)); +PPC_EXC_ASSERT_OFFSET(V6, PPC_EXC_VR_OFFSET(6)); +PPC_EXC_ASSERT_OFFSET(V7, PPC_EXC_VR_OFFSET(7)); +PPC_EXC_ASSERT_OFFSET(V8, PPC_EXC_VR_OFFSET(8)); +PPC_EXC_ASSERT_OFFSET(V9, PPC_EXC_VR_OFFSET(9)); +PPC_EXC_ASSERT_OFFSET(V10, PPC_EXC_VR_OFFSET(10)); +PPC_EXC_ASSERT_OFFSET(V11, PPC_EXC_VR_OFFSET(11)); +PPC_EXC_ASSERT_OFFSET(V12, PPC_EXC_VR_OFFSET(12)); +PPC_EXC_ASSERT_OFFSET(V13, PPC_EXC_VR_OFFSET(13)); +PPC_EXC_ASSERT_OFFSET(V14, PPC_EXC_VR_OFFSET(14)); +PPC_EXC_ASSERT_OFFSET(V15, PPC_EXC_VR_OFFSET(15)); +PPC_EXC_ASSERT_OFFSET(V16, PPC_EXC_VR_OFFSET(16)); +PPC_EXC_ASSERT_OFFSET(V17, PPC_EXC_VR_OFFSET(17)); +PPC_EXC_ASSERT_OFFSET(V18, PPC_EXC_VR_OFFSET(18)); +PPC_EXC_ASSERT_OFFSET(V19, PPC_EXC_VR_OFFSET(19)); +PPC_EXC_ASSERT_OFFSET(V20, PPC_EXC_VR_OFFSET(20)); +PPC_EXC_ASSERT_OFFSET(V21, PPC_EXC_VR_OFFSET(21)); +PPC_EXC_ASSERT_OFFSET(V22, PPC_EXC_VR_OFFSET(22)); +PPC_EXC_ASSERT_OFFSET(V23, PPC_EXC_VR_OFFSET(23)); +PPC_EXC_ASSERT_OFFSET(V24, PPC_EXC_VR_OFFSET(24)); +PPC_EXC_ASSERT_OFFSET(V25, PPC_EXC_VR_OFFSET(25)); +PPC_EXC_ASSERT_OFFSET(V26, PPC_EXC_VR_OFFSET(26)); +PPC_EXC_ASSERT_OFFSET(V27, PPC_EXC_VR_OFFSET(27)); +PPC_EXC_ASSERT_OFFSET(V28, PPC_EXC_VR_OFFSET(28)); +PPC_EXC_ASSERT_OFFSET(V29, PPC_EXC_VR_OFFSET(29)); +PPC_EXC_ASSERT_OFFSET(V30, PPC_EXC_VR_OFFSET(30)); +PPC_EXC_ASSERT_OFFSET(V31, PPC_EXC_VR_OFFSET(31)); + +PPC_EXC_MIN_ASSERT_OFFSET(VSCR, PPC_EXC_MIN_VSCR_OFFSET); +RTEMS_STATIC_ASSERT(PPC_EXC_MIN_VR_OFFSET(0) % 16 == 0, PPC_EXC_MIN_VR_OFFSET); +PPC_EXC_MIN_ASSERT_OFFSET(V0, PPC_EXC_MIN_VR_OFFSET(0)); +PPC_EXC_MIN_ASSERT_OFFSET(V1, PPC_EXC_MIN_VR_OFFSET(1)); +PPC_EXC_MIN_ASSERT_OFFSET(V2, PPC_EXC_MIN_VR_OFFSET(2)); +PPC_EXC_MIN_ASSERT_OFFSET(V3, PPC_EXC_MIN_VR_OFFSET(3)); +PPC_EXC_MIN_ASSERT_OFFSET(V4, PPC_EXC_MIN_VR_OFFSET(4)); +PPC_EXC_MIN_ASSERT_OFFSET(V5, PPC_EXC_MIN_VR_OFFSET(5)); +PPC_EXC_MIN_ASSERT_OFFSET(V6, PPC_EXC_MIN_VR_OFFSET(6)); +PPC_EXC_MIN_ASSERT_OFFSET(V7, PPC_EXC_MIN_VR_OFFSET(7)); +PPC_EXC_MIN_ASSERT_OFFSET(V8, PPC_EXC_MIN_VR_OFFSET(8)); +PPC_EXC_MIN_ASSERT_OFFSET(V9, PPC_EXC_MIN_VR_OFFSET(9)); +PPC_EXC_MIN_ASSERT_OFFSET(V10, PPC_EXC_MIN_VR_OFFSET(10)); +PPC_EXC_MIN_ASSERT_OFFSET(V11, PPC_EXC_MIN_VR_OFFSET(11)); +PPC_EXC_MIN_ASSERT_OFFSET(V12, PPC_EXC_MIN_VR_OFFSET(12)); +PPC_EXC_MIN_ASSERT_OFFSET(V13, PPC_EXC_MIN_VR_OFFSET(13)); +PPC_EXC_MIN_ASSERT_OFFSET(V14, PPC_EXC_MIN_VR_OFFSET(14)); +PPC_EXC_MIN_ASSERT_OFFSET(V15, PPC_EXC_MIN_VR_OFFSET(15)); +PPC_EXC_MIN_ASSERT_OFFSET(V16, PPC_EXC_MIN_VR_OFFSET(16)); +PPC_EXC_MIN_ASSERT_OFFSET(V17, PPC_EXC_MIN_VR_OFFSET(17)); +PPC_EXC_MIN_ASSERT_OFFSET(V18, PPC_EXC_MIN_VR_OFFSET(18)); +PPC_EXC_MIN_ASSERT_OFFSET(V19, PPC_EXC_MIN_VR_OFFSET(19)); +#endif + +#ifdef PPC_MULTILIB_FPU +RTEMS_STATIC_ASSERT(PPC_EXC_FR_OFFSET(0) % 8 == 0, PPC_EXC_FR_OFFSET); +PPC_EXC_ASSERT_OFFSET(F0, PPC_EXC_FR_OFFSET(0)); +PPC_EXC_ASSERT_OFFSET(F1, PPC_EXC_FR_OFFSET(1)); +PPC_EXC_ASSERT_OFFSET(F2, PPC_EXC_FR_OFFSET(2)); +PPC_EXC_ASSERT_OFFSET(F3, PPC_EXC_FR_OFFSET(3)); +PPC_EXC_ASSERT_OFFSET(F4, PPC_EXC_FR_OFFSET(4)); +PPC_EXC_ASSERT_OFFSET(F5, PPC_EXC_FR_OFFSET(5)); +PPC_EXC_ASSERT_OFFSET(F6, PPC_EXC_FR_OFFSET(6)); +PPC_EXC_ASSERT_OFFSET(F7, PPC_EXC_FR_OFFSET(7)); +PPC_EXC_ASSERT_OFFSET(F8, PPC_EXC_FR_OFFSET(8)); +PPC_EXC_ASSERT_OFFSET(F9, PPC_EXC_FR_OFFSET(9)); +PPC_EXC_ASSERT_OFFSET(F10, PPC_EXC_FR_OFFSET(10)); +PPC_EXC_ASSERT_OFFSET(F11, PPC_EXC_FR_OFFSET(11)); +PPC_EXC_ASSERT_OFFSET(F12, PPC_EXC_FR_OFFSET(12)); +PPC_EXC_ASSERT_OFFSET(F13, PPC_EXC_FR_OFFSET(13)); +PPC_EXC_ASSERT_OFFSET(F14, PPC_EXC_FR_OFFSET(14)); +PPC_EXC_ASSERT_OFFSET(F15, PPC_EXC_FR_OFFSET(15)); +PPC_EXC_ASSERT_OFFSET(F16, PPC_EXC_FR_OFFSET(16)); +PPC_EXC_ASSERT_OFFSET(F17, PPC_EXC_FR_OFFSET(17)); +PPC_EXC_ASSERT_OFFSET(F18, PPC_EXC_FR_OFFSET(18)); +PPC_EXC_ASSERT_OFFSET(F19, PPC_EXC_FR_OFFSET(19)); +PPC_EXC_ASSERT_OFFSET(F20, PPC_EXC_FR_OFFSET(20)); +PPC_EXC_ASSERT_OFFSET(F21, PPC_EXC_FR_OFFSET(21)); +PPC_EXC_ASSERT_OFFSET(F22, PPC_EXC_FR_OFFSET(22)); +PPC_EXC_ASSERT_OFFSET(F23, PPC_EXC_FR_OFFSET(23)); +PPC_EXC_ASSERT_OFFSET(F24, PPC_EXC_FR_OFFSET(24)); +PPC_EXC_ASSERT_OFFSET(F25, PPC_EXC_FR_OFFSET(25)); +PPC_EXC_ASSERT_OFFSET(F26, PPC_EXC_FR_OFFSET(26)); +PPC_EXC_ASSERT_OFFSET(F27, PPC_EXC_FR_OFFSET(27)); +PPC_EXC_ASSERT_OFFSET(F28, PPC_EXC_FR_OFFSET(28)); +PPC_EXC_ASSERT_OFFSET(F29, PPC_EXC_FR_OFFSET(29)); +PPC_EXC_ASSERT_OFFSET(F30, PPC_EXC_FR_OFFSET(30)); +PPC_EXC_ASSERT_OFFSET(F31, PPC_EXC_FR_OFFSET(31)); +PPC_EXC_ASSERT_OFFSET(FPSCR, PPC_EXC_FPSCR_OFFSET); + +RTEMS_STATIC_ASSERT(PPC_EXC_MIN_FR_OFFSET(0) % 8 == 0, PPC_EXC_MIN_FR_OFFSET); +PPC_EXC_MIN_ASSERT_OFFSET(F0, PPC_EXC_MIN_FR_OFFSET(0)); +PPC_EXC_MIN_ASSERT_OFFSET(F1, PPC_EXC_MIN_FR_OFFSET(1)); +PPC_EXC_MIN_ASSERT_OFFSET(F2, PPC_EXC_MIN_FR_OFFSET(2)); +PPC_EXC_MIN_ASSERT_OFFSET(F3, PPC_EXC_MIN_FR_OFFSET(3)); +PPC_EXC_MIN_ASSERT_OFFSET(F4, PPC_EXC_MIN_FR_OFFSET(4)); +PPC_EXC_MIN_ASSERT_OFFSET(F5, PPC_EXC_MIN_FR_OFFSET(5)); +PPC_EXC_MIN_ASSERT_OFFSET(F6, PPC_EXC_MIN_FR_OFFSET(6)); +PPC_EXC_MIN_ASSERT_OFFSET(F7, PPC_EXC_MIN_FR_OFFSET(7)); +PPC_EXC_MIN_ASSERT_OFFSET(F8, PPC_EXC_MIN_FR_OFFSET(8)); +PPC_EXC_MIN_ASSERT_OFFSET(F9, PPC_EXC_MIN_FR_OFFSET(9)); +PPC_EXC_MIN_ASSERT_OFFSET(F10, PPC_EXC_MIN_FR_OFFSET(10)); +PPC_EXC_MIN_ASSERT_OFFSET(F11, PPC_EXC_MIN_FR_OFFSET(11)); +PPC_EXC_MIN_ASSERT_OFFSET(F12, PPC_EXC_MIN_FR_OFFSET(12)); +PPC_EXC_MIN_ASSERT_OFFSET(F13, PPC_EXC_MIN_FR_OFFSET(13)); +PPC_EXC_MIN_ASSERT_OFFSET(FPSCR, PPC_EXC_MIN_FPSCR_OFFSET); +#endif + RTEMS_STATIC_ASSERT( PPC_EXC_MINIMAL_FRAME_SIZE % CPU_STACK_ALIGNMENT == 0, PPC_EXC_MINIMAL_FRAME_SIZE diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_print.c b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_print.c index cb95aba006..27b76a1934 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_print.c +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_print.c @@ -179,6 +179,42 @@ void _CPU_Exception_frame_print(const CPU_Exception_frame *excPtr) printk(" MCSR = 0x%08x\n", mcsr); } +#ifdef PPC_MULTILIB_ALTIVEC + { + unsigned char *v = (unsigned char *) &excPtr->V0; + int i; + int j; + + printk(" VSCR = 0x%08x\n", excPtr->VSCR); + printk("VRSAVE = 0x%08x\n", excPtr->VRSAVE); + + for (i = 0; i < 32; ++i) { + printk(" V%02i = 0x", i); + + for (j = 0; j < 16; ++j) { + printk("%02x", v[j]); + } + + printk("\n"); + + v += 16; + } + } +#endif + +#ifdef PPC_MULTILIB_FPU + { + unsigned long long *f = (unsigned long long *) &excPtr->F0; + int i; + + printk("FPSCR = 0x%08llx\n", excPtr->FPSCR); + + for (i = 0; i < 32; ++i) { + printk(" F%02i = 0x%016llx\n", i, f[i]); + } + } +#endif + if (executing != NULL) { const char *name = (const char *) &executing->Object.name; diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h index bf13c757f1..86bd0f11f2 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h @@ -146,8 +146,37 @@ extern "C" { #ifndef __SPE__ #define PPC_EXC_GPR_OFFSET(gpr) ((gpr) * PPC_GPR_SIZE + 36) #define PPC_EXC_VECTOR_PROLOGUE_OFFSET PPC_EXC_GPR_OFFSET(4) - #define PPC_EXC_MINIMAL_FRAME_SIZE 96 - #define PPC_EXC_FRAME_SIZE 176 + #if defined(PPC_MULTILIB_ALTIVEC) && defined(PPC_MULTILIB_FPU) + #define PPC_EXC_VSCR_OFFSET 168 + #define PPC_EXC_VRSAVE_OFFSET 172 + #define PPC_EXC_VR_OFFSET(v) ((v) * 16 + 176) + #define PPC_EXC_FR_OFFSET(f) ((f) * 8 + 688) + #define PPC_EXC_FPSCR_OFFSET 944 + #define PPC_EXC_FRAME_SIZE 960 + #define PPC_EXC_MIN_VSCR_OFFSET 92 + #define PPC_EXC_MIN_VR_OFFSET(v) ((v) * 16 + 96) + #define PPC_EXC_MIN_FR_OFFSET(f) ((f) * 8 + 416) + #define PPC_EXC_MIN_FPSCR_OFFSET 528 + #define PPC_EXC_MINIMAL_FRAME_SIZE 544 + #elif defined(PPC_MULTILIB_ALTIVEC) + #define PPC_EXC_VSCR_OFFSET 168 + #define PPC_EXC_VRSAVE_OFFSET 172 + #define PPC_EXC_VR_OFFSET(v) ((v) * 16 + 176) + #define PPC_EXC_FRAME_SIZE 688 + #define PPC_EXC_MIN_VSCR_OFFSET 92 + #define PPC_EXC_MIN_VR_OFFSET(v) ((v) * 16 + 96) + #define PPC_EXC_MINIMAL_FRAME_SIZE 416 + #elif defined(PPC_MULTILIB_FPU) + #define PPC_EXC_FR_OFFSET(f) ((f) * 8 + 168) + #define PPC_EXC_FPSCR_OFFSET 424 + #define PPC_EXC_FRAME_SIZE 448 + #define PPC_EXC_MIN_FR_OFFSET(f) ((f) * 8 + 96) + #define PPC_EXC_MIN_FPSCR_OFFSET 92 + #define PPC_EXC_MINIMAL_FRAME_SIZE 224 + #else + #define PPC_EXC_FRAME_SIZE 176 + #define PPC_EXC_MINIMAL_FRAME_SIZE 96 + #endif #else #define PPC_EXC_SPEFSCR_OFFSET 36 #define PPC_EXC_ACC_OFFSET 40 @@ -214,7 +243,7 @@ extern "C" { #define EXC_GENERIC_SIZE PPC_EXC_FRAME_SIZE -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC) #define EXC_VEC_OFFSET EXC_GENERIC_SIZE #ifndef PPC_CACHE_ALIGNMENT #error "Missing include file!" @@ -248,6 +277,77 @@ extern "C" { * @{ */ +typedef struct { + uint32_t EXC_SRR0; + uint32_t EXC_SRR1; + uint32_t unused; + uint32_t EXC_CR; + uint32_t EXC_CTR; + uint32_t EXC_XER; + uint32_t EXC_LR; + #ifdef __SPE__ + uint32_t EXC_SPEFSCR; + uint64_t EXC_ACC; + #endif + PPC_GPR_TYPE GPR0; + PPC_GPR_TYPE GPR1; + PPC_GPR_TYPE GPR2; + PPC_GPR_TYPE GPR3; + PPC_GPR_TYPE GPR4; + PPC_GPR_TYPE GPR5; + PPC_GPR_TYPE GPR6; + PPC_GPR_TYPE GPR7; + PPC_GPR_TYPE GPR8; + PPC_GPR_TYPE GPR9; + PPC_GPR_TYPE GPR10; + PPC_GPR_TYPE GPR11; + PPC_GPR_TYPE GPR12; + uint32_t EARLY_INSTANT; + #ifdef PPC_MULTILIB_ALTIVEC + uint32_t VSCR; + 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]; + #endif + #ifdef PPC_MULTILIB_FPU + #ifndef PPC_MULTILIB_ALTIVEC + uint32_t reserved_for_alignment; + #endif + 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; + uint64_t FPSCR; + #endif +} ppc_exc_min_frame; + typedef CPU_Exception_frame BSP_Exception_frame; /** @} */ diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c b/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c index 6aa1301baf..0b0527ec4d 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c +++ b/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c @@ -45,7 +45,7 @@ */ void _CPU_Initialize(void) { -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC) _CPU_Initialize_altivec(); #endif } @@ -75,6 +75,8 @@ void _CPU_Context_Initialize( _CPU_MSR_GET( msr_value ); + the_ppc_context = ppc_get_context( the_context ); + /* * Setting the interrupt mask here is not strictly necessary * since the IRQ level will be established from _Thread_Handler() @@ -95,6 +97,9 @@ void _CPU_Context_Initialize( msr_value &= ~ppc_interrupt_get_disable_mask(); } +#ifdef PPC_MULTILIB_FPU + msr_value |= MSR_FP; +#else /* * The FP bit of the MSR should only be enabled if this is a floating * point task. Unfortunately, the vfprintf_r routine in newlib @@ -118,13 +123,19 @@ void _CPU_Context_Initialize( msr_value |= PPC_MSR_FP; else msr_value &= ~PPC_MSR_FP; +#endif + +#ifdef PPC_MULTILIB_ALTIVEC + msr_value |= MSR_VE; + + the_ppc_context->vrsave = 0; +#endif - the_ppc_context = ppc_get_context( the_context ); the_ppc_context->gpr1 = sp; the_ppc_context->msr = msr_value; the_ppc_context->lr = (uint32_t) entry_point; -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC) _CPU_Context_initialize_altivec( the_ppc_context ); #endif diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S index 26ef58d7b9..5d8c70d290 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S +++ b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S @@ -23,7 +23,7 @@ * COPYRIGHT (c) 1989-1997. * On-Line Applications Research Corporation (OAR). * - * Copyright (c) 2011-2014 embedded brains GmbH + * Copyright (c) 2011-2015 embedded brains GmbH * * The license and distribution terms for this file may in * the file LICENSE in this distribution or at @@ -55,6 +55,7 @@ #define PPC_CONTEXT_CACHE_LINE_2 (3 * PPC_DEFAULT_CACHE_LINE_SIZE) #define PPC_CONTEXT_CACHE_LINE_3 (4 * PPC_DEFAULT_CACHE_LINE_SIZE) #define PPC_CONTEXT_CACHE_LINE_4 (5 * PPC_DEFAULT_CACHE_LINE_SIZE) +#define PPC_CONTEXT_CACHE_LINE_5 (6 * PPC_DEFAULT_CACHE_LINE_SIZE) BEGIN_CODE @@ -257,7 +258,10 @@ PROC (_CPU_Context_switch): clrrwi r5, r4, PPC_DEFAULT_CACHE_LINE_POWER DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_0) + +#if PPC_CONTEXT_CACHE_LINE_2 <= PPC_CONTEXT_VOLATILE_SIZE DATA_CACHE_ZERO_AND_TOUCH(r11, PPC_CONTEXT_CACHE_LINE_1) +#endif /* Save context to r3 */ @@ -317,6 +321,11 @@ PROC (_CPU_Context_switch): PPC_GPR_STORE r24, PPC_CONTEXT_OFFSET_GPR24(r3) PPC_GPR_STORE r25, PPC_CONTEXT_OFFSET_GPR25(r3) + +#if PPC_CONTEXT_OFFSET_V22 == PPC_CONTEXT_CACHE_LINE_2 + DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_2) +#endif + PPC_GPR_STORE r26, PPC_CONTEXT_OFFSET_GPR26(r3) PPC_GPR_STORE r27, PPC_CONTEXT_OFFSET_GPR27(r3) @@ -327,6 +336,71 @@ PROC (_CPU_Context_switch): stw r2, PPC_CONTEXT_OFFSET_GPR2(r3) +#ifdef PPC_MULTILIB_ALTIVEC + li r9, PPC_CONTEXT_OFFSET_V20 + stvx v20, r3, r9 + li r9, PPC_CONTEXT_OFFSET_V21 + stvx v21, r3, r9 + +#if PPC_CONTEXT_OFFSET_V26 == PPC_CONTEXT_CACHE_LINE_3 + DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_3) +#endif + + li r9, PPC_CONTEXT_OFFSET_V22 + stvx v22, r3, r9 + li r9, PPC_CONTEXT_OFFSET_V23 + stvx v23, r3, r9 + li r9, PPC_CONTEXT_OFFSET_V24 + stvx v24, r3, r9 + li r9, PPC_CONTEXT_OFFSET_V25 + stvx v25, r3, r9 + +#if PPC_CONTEXT_OFFSET_V30 == PPC_CONTEXT_CACHE_LINE_4 + DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_4) +#endif + + li r9, PPC_CONTEXT_OFFSET_V26 + stvx v26, r3, r9 + li r9, PPC_CONTEXT_OFFSET_V27 + stvx v27, r3, r9 + li r9, PPC_CONTEXT_OFFSET_V28 + stvx v28, r3, r9 + li r9, PPC_CONTEXT_OFFSET_V29 + stvx v29, r3, r9 + +#if PPC_CONTEXT_OFFSET_F17 == PPC_CONTEXT_CACHE_LINE_5 + DATA_CACHE_ZERO_AND_TOUCH(r10, PPC_CONTEXT_CACHE_LINE_5) +#endif + + li r9, PPC_CONTEXT_OFFSET_V30 + stvx v30, r3, r9 + li r9, PPC_CONTEXT_OFFSET_V31 + stvx v31, r3, r9 + mfvrsave r9 + stw r9, PPC_CONTEXT_OFFSET_VRSAVE(r3) +#endif + +#ifdef PPC_MULTILIB_FPU + stfd f14, PPC_CONTEXT_OFFSET_F14(r3) + stfd f15, PPC_CONTEXT_OFFSET_F15(r3) + stfd f16, PPC_CONTEXT_OFFSET_F16(r3) + stfd f17, PPC_CONTEXT_OFFSET_F17(r3) + stfd f18, PPC_CONTEXT_OFFSET_F18(r3) + stfd f19, PPC_CONTEXT_OFFSET_F19(r3) + stfd f20, PPC_CONTEXT_OFFSET_F20(r3) + stfd f21, PPC_CONTEXT_OFFSET_F21(r3) + stfd f22, PPC_CONTEXT_OFFSET_F22(r3) + stfd f23, PPC_CONTEXT_OFFSET_F23(r3) + stfd f24, PPC_CONTEXT_OFFSET_F24(r3) + stfd f25, PPC_CONTEXT_OFFSET_F25(r3) + stfd f26, PPC_CONTEXT_OFFSET_F26(r3) + stfd f27, PPC_CONTEXT_OFFSET_F27(r3) + stfd f28, PPC_CONTEXT_OFFSET_F28(r3) + stfd f29, PPC_CONTEXT_OFFSET_F29(r3) + stfd f30, PPC_CONTEXT_OFFSET_F30(r3) + stfd f31, PPC_CONTEXT_OFFSET_F31(r3) +#endif + #ifdef RTEMS_SMP /* The executing context no longer executes on this processor */ msync @@ -351,7 +425,7 @@ check_is_executing: /* Restore context from r5 */ restore_context: -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC) mr r14, r5 .extern _CPU_Context_switch_altivec bl _CPU_Context_switch_altivec @@ -390,6 +464,56 @@ restore_context: lwz r2, PPC_CONTEXT_OFFSET_GPR2(r5) +#ifdef PPC_MULTILIB_ALTIVEC + li r9, PPC_CONTEXT_OFFSET_V20 + lvx v20, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V21 + lvx v21, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V22 + lvx v22, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V23 + lvx v23, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V24 + lvx v24, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V25 + lvx v25, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V26 + lvx v26, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V27 + lvx v27, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V28 + lvx v28, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V29 + lvx v29, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V30 + lvx v30, r5, r9 + li r9, PPC_CONTEXT_OFFSET_V31 + lvx v31, r5, r9 + lwz r9, PPC_CONTEXT_OFFSET_VRSAVE(r5) + mtvrsave r9 +#endif + +#ifdef PPC_MULTILIB_FPU + lfd f14, PPC_CONTEXT_OFFSET_F14(r5) + lfd f15, PPC_CONTEXT_OFFSET_F15(r5) + lfd f16, PPC_CONTEXT_OFFSET_F16(r5) + lfd f17, PPC_CONTEXT_OFFSET_F17(r5) + lfd f18, PPC_CONTEXT_OFFSET_F18(r5) + lfd f19, PPC_CONTEXT_OFFSET_F19(r5) + lfd f20, PPC_CONTEXT_OFFSET_F20(r5) + lfd f21, PPC_CONTEXT_OFFSET_F21(r5) + lfd f22, PPC_CONTEXT_OFFSET_F22(r5) + lfd f23, PPC_CONTEXT_OFFSET_F23(r5) + lfd f24, PPC_CONTEXT_OFFSET_F24(r5) + lfd f25, PPC_CONTEXT_OFFSET_F25(r5) + lfd f26, PPC_CONTEXT_OFFSET_F26(r5) + lfd f27, PPC_CONTEXT_OFFSET_F27(r5) + lfd f28, PPC_CONTEXT_OFFSET_F28(r5) + lfd f29, PPC_CONTEXT_OFFSET_F29(r5) + lfd f30, PPC_CONTEXT_OFFSET_F30(r5) + lfd f31, PPC_CONTEXT_OFFSET_F31(r5) +#endif + mtcr r8 mtlr r7 mtmsr r6 @@ -405,7 +529,7 @@ PROC (_CPU_Context_restore): /* Align to a cache line */ clrrwi r5, r3, PPC_DEFAULT_CACHE_LINE_POWER -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC) li r3, 0 #endif 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). -- cgit v1.2.3