mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-26 06:08:20 +00:00
powerpc: Add support for VRSAVE
The VRSAVE feature of the Altivec unit can be used to reduce the amount of Altivec registers which need to be saved/restored during interrupt processing and context switches. In order to use the VRSAVE optimization a corresponding multilib (-mvrsave) is required, see GCC configuration. The -mvrsave option must be added to the ABI_FLAGS of the BSP. Currently only the -mcpu=e6500 based QorIQ BSP support this optimization. Update #4712.
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
* COPYRIGHT (c) 1989-1997.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Copyright (c) 2011, 2017 embedded brains GmbH
|
||||
* Copyright (c) 2011, 2020 embedded brains GmbH
|
||||
*
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
@@ -267,6 +267,10 @@ PROC (_CPU_Context_switch_no_return):
|
||||
isync
|
||||
#endif
|
||||
|
||||
#if defined(PPC_MULTILIB_ALTIVEC) && defined(__PPC_VRSAVE__)
|
||||
mfvrsave r9
|
||||
#endif
|
||||
|
||||
/* Align to a cache line */
|
||||
CLEAR_RIGHT_IMMEDIATE r3, r3, PPC_DEFAULT_CACHE_LINE_POWER
|
||||
CLEAR_RIGHT_IMMEDIATE r5, r4, PPC_DEFAULT_CACHE_LINE_POWER
|
||||
@@ -284,6 +288,14 @@ PROC (_CPU_Context_switch_no_return):
|
||||
mfmsr r6
|
||||
#endif /* END PPC_DISABLE_MSR_ACCESS */
|
||||
mfcr r7
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
#ifdef __PPC_VRSAVE__
|
||||
/* Mark v0 as used since we need it to get the VSCR */
|
||||
oris r8, r9, 0x8000
|
||||
mtvrsave r8
|
||||
#endif
|
||||
mfvscr v0
|
||||
#endif
|
||||
mflr r8
|
||||
lwz r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
|
||||
|
||||
@@ -356,6 +368,16 @@ PROC (_CPU_Context_switch_no_return):
|
||||
stw r11, PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE(r3)
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
li r10, PPC_CONTEXT_OFFSET_VSCR
|
||||
stvewx v0, r3, r10
|
||||
|
||||
#ifdef __PPC_VRSAVE__
|
||||
stw r9, PPC_CONTEXT_OFFSET_VRSAVE(r3)
|
||||
andi. r9, r9, 0xfff
|
||||
bne .Laltivec_save
|
||||
|
||||
.Laltivec_save_continue:
|
||||
#else /* __PPC_VRSAVE__ */
|
||||
li r9, PPC_CONTEXT_OFFSET_V20
|
||||
stvx v20, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V21
|
||||
@@ -397,7 +419,8 @@ PROC (_CPU_Context_switch_no_return):
|
||||
stvx v31, r3, r9
|
||||
mfvrsave r9
|
||||
stw r9, PPC_CONTEXT_OFFSET_VRSAVE(r3)
|
||||
#endif
|
||||
#endif /* __PPC_VRSAVE__ */
|
||||
#endif /* PPC_MULTILIB_ALTIVEC */
|
||||
|
||||
#ifdef PPC_MULTILIB_FPU
|
||||
stfd f14, PPC_CONTEXT_OFFSET_F14(r3)
|
||||
@@ -461,6 +484,14 @@ restore_context:
|
||||
PPC_REG_LOAD r1, PPC_CONTEXT_OFFSET_GPR1(r5)
|
||||
PPC_REG_LOAD r8, PPC_CONTEXT_OFFSET_LR(r5)
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
li r10, PPC_CONTEXT_OFFSET_VSCR
|
||||
lvewx v0, r5, r10
|
||||
#ifdef __PPC_VRSAVE__
|
||||
lwz r9, PPC_CONTEXT_OFFSET_VRSAVE(r5)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
PPC_GPR_LOAD r14, PPC_CONTEXT_OFFSET_GPR14(r5)
|
||||
PPC_GPR_LOAD r15, PPC_CONTEXT_OFFSET_GPR15(r5)
|
||||
|
||||
@@ -494,6 +525,15 @@ restore_context:
|
||||
lwz r11, PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE(r5)
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
mtvscr v0
|
||||
|
||||
#ifdef __PPC_VRSAVE__
|
||||
mtvrsave r9
|
||||
andi. r9, r9, 0xfff
|
||||
bne .Laltivec_restore
|
||||
|
||||
.Laltivec_restore_continue:
|
||||
#else /* __PPC_VRSAVE__ */
|
||||
li r9, PPC_CONTEXT_OFFSET_V20
|
||||
lvx v20, r5, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V21
|
||||
@@ -520,7 +560,8 @@ restore_context:
|
||||
lvx v31, r5, r9
|
||||
lwz r9, PPC_CONTEXT_OFFSET_VRSAVE(r5)
|
||||
mtvrsave r9
|
||||
#endif
|
||||
#endif /* __PPC_VRSAVE__ */
|
||||
#endif /* PPC_MULTILIB_ALTIVEC */
|
||||
|
||||
#ifdef PPC_MULTILIB_FPU
|
||||
lfd f14, PPC_CONTEXT_OFFSET_F14(r5)
|
||||
@@ -567,6 +608,13 @@ PROC (_CPU_Context_restore):
|
||||
li r3, 0
|
||||
#endif
|
||||
|
||||
#if defined(PPC_MULTILIB_ALTIVEC) && defined(__PPC_VRSAVE__)
|
||||
/* Mark v0 as used since we need it to get the VSCR */
|
||||
mfvrsave r9
|
||||
oris r8, r9, 0x8000
|
||||
mtvrsave r8
|
||||
#endif
|
||||
|
||||
b restore_context
|
||||
|
||||
#ifdef RTEMS_SMP
|
||||
@@ -595,3 +643,105 @@ PROC (_CPU_Context_restore):
|
||||
|
||||
b .Lcheck_is_executing
|
||||
#endif
|
||||
|
||||
#if defined(PPC_MULTILIB_ALTIVEC) && defined(__PPC_VRSAVE__)
|
||||
.Laltivec_save:
|
||||
|
||||
/*
|
||||
* Let X be VRSAVE, calculate:
|
||||
*
|
||||
* Z = X & 0x777
|
||||
* Z = Z + 0x777
|
||||
* X = X | Z
|
||||
*
|
||||
* Afterwards, we have in X for each group of four non-volatile VR
|
||||
* registers:
|
||||
*
|
||||
* 0111b, if VRSAVE group of four registers == 0
|
||||
* 1XXXb, if VRSAVE group of four registers != 0
|
||||
*/
|
||||
andi. r10, r9, 0x777
|
||||
addi r10, r10, 0x777
|
||||
or r9, r9, r10
|
||||
mtcr r9
|
||||
|
||||
bf 20, .Laltivec_save_v24
|
||||
li r9, PPC_CONTEXT_OFFSET_V20
|
||||
stvx v20, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V21
|
||||
stvx v21, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V22
|
||||
stvx v22, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V23
|
||||
stvx v23, r3, r9
|
||||
|
||||
.Laltivec_save_v24:
|
||||
|
||||
bf 24, .Laltivec_save_v28
|
||||
li r9, PPC_CONTEXT_OFFSET_V24
|
||||
stvx v24, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V25
|
||||
stvx v25, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V26
|
||||
stvx v26, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V27
|
||||
stvx v27, r3, r9
|
||||
|
||||
.Laltivec_save_v28:
|
||||
|
||||
bf 28, .Laltivec_save_continue
|
||||
li r9, PPC_CONTEXT_OFFSET_V28
|
||||
stvx v28, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V29
|
||||
stvx v29, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V30
|
||||
stvx v30, r3, r9
|
||||
li r9, PPC_CONTEXT_OFFSET_V31
|
||||
stvx v31, r3, r9
|
||||
|
||||
b .Laltivec_save_continue
|
||||
|
||||
.Laltivec_restore:
|
||||
|
||||
/* See comment at .Laltivec_save */
|
||||
andi. r10, r9, 0x777
|
||||
addi r10, r10, 0x777
|
||||
or r9, r9, r10
|
||||
mtcr r9
|
||||
|
||||
bf 20, .Laltivec_restore_v24
|
||||
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
|
||||
|
||||
.Laltivec_restore_v24:
|
||||
|
||||
bf 24, .Laltivec_restore_v28
|
||||
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
|
||||
|
||||
.Laltivec_restore_v28:
|
||||
|
||||
bf 28, .Laltivec_restore_continue
|
||||
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
|
||||
|
||||
b .Laltivec_restore_continue
|
||||
#endif /* PPC_MULTILIB_ALTIVEC && __PPC_VRSAVE__ */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011, 2017 embedded brains GmbH. All rights reserved.
|
||||
* Copyright (c) 2011, 2020 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -173,8 +173,15 @@ ppc_exc_interrupt:
|
||||
evstdd SCRATCH_5_REGISTER, PPC_EXC_ACC_OFFSET(r1)
|
||||
#endif
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
/* Save volatile AltiVec context */
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
#ifdef __PPC_VRSAVE__
|
||||
mfvrsave SCRATCH_0_REGISTER
|
||||
cmpwi SCRATCH_0_REGISTER, 0
|
||||
bne .Laltivec_save
|
||||
|
||||
.Laltivec_save_continue:
|
||||
#else /* __PPC_VRSAVE__ */
|
||||
li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(0)
|
||||
stvx v0, r1, SCRATCH_0_REGISTER
|
||||
mfvscr v0
|
||||
@@ -218,7 +225,8 @@ ppc_exc_interrupt:
|
||||
stvx v19, r1, SCRATCH_0_REGISTER
|
||||
li SCRATCH_0_REGISTER, PPC_EXC_MIN_VSCR_OFFSET
|
||||
stvewx v0, r1, SCRATCH_0_REGISTER
|
||||
#endif
|
||||
#endif /* __PPC_VRSAVE__ */
|
||||
#endif /* PPC_MULTILIB_ALTIVEC */
|
||||
|
||||
#ifdef PPC_MULTILIB_FPU
|
||||
/* Save volatile FPU context */
|
||||
@@ -334,8 +342,15 @@ ppc_exc_interrupt:
|
||||
|
||||
.Lthread_dispatch_done:
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
/* Restore volatile AltiVec context */
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
#ifdef __PPC_VRSAVE__
|
||||
mfvrsave SCRATCH_0_REGISTER
|
||||
cmpwi SCRATCH_0_REGISTER, 0
|
||||
bne .Laltivec_restore
|
||||
|
||||
.Laltivec_restore_continue:
|
||||
#else /* __PPC_VRSAVE__ */
|
||||
li SCRATCH_0_REGISTER, PPC_EXC_MIN_VSCR_OFFSET
|
||||
lvewx v0, r1, SCRATCH_0_REGISTER
|
||||
mtvscr v0
|
||||
@@ -379,7 +394,8 @@ ppc_exc_interrupt:
|
||||
lvx v18, r1, SCRATCH_0_REGISTER
|
||||
li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(19)
|
||||
lvx v19, r1, SCRATCH_0_REGISTER
|
||||
#endif
|
||||
#endif /* __PPC_VRSAVE__ */
|
||||
#endif /* PPC_MULTILIB_ALTIVEC */
|
||||
|
||||
#ifdef PPC_MULTILIB_FPU
|
||||
/* Restore volatile FPU context */
|
||||
@@ -478,6 +494,169 @@ ppc_exc_interrupt:
|
||||
/* Return */
|
||||
rfi
|
||||
|
||||
#if defined(PPC_MULTILIB_ALTIVEC) && defined(__PPC_VRSAVE__)
|
||||
.Laltivec_save:
|
||||
|
||||
/*
|
||||
* Let X be VRSAVE, calculate:
|
||||
*
|
||||
* Y = 0x77777777
|
||||
* Z = X & Y
|
||||
* Z = Z + Y
|
||||
* X = X | Z
|
||||
*
|
||||
* Afterwards, we have in X for each group of four VR registers:
|
||||
*
|
||||
* 0111b, if VRSAVE group of four registers == 0
|
||||
* 1XXXb, if VRSAVE group of four registers != 0
|
||||
*/
|
||||
lis SCRATCH_5_REGISTER, 0x7777
|
||||
ori SCRATCH_5_REGISTER, SCRATCH_5_REGISTER, 0x7777
|
||||
and SCRATCH_6_REGISTER, SCRATCH_0_REGISTER, SCRATCH_5_REGISTER
|
||||
add SCRATCH_6_REGISTER, SCRATCH_5_REGISTER, SCRATCH_6_REGISTER
|
||||
or SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, SCRATCH_6_REGISTER
|
||||
mtcr SCRATCH_0_REGISTER
|
||||
|
||||
li SCRATCH_0_REGISTER, PPC_EXC_MIN_VR_OFFSET(0)
|
||||
stvx v0, r1, SCRATCH_0_REGISTER
|
||||
|
||||
/* Move VCSR to V0 */
|
||||
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
|
||||
|
||||
/* Save VCSR using V0 */
|
||||
li SCRATCH_0_REGISTER, PPC_EXC_MIN_VSCR_OFFSET
|
||||
stvewx v0, r1, SCRATCH_0_REGISTER
|
||||
|
||||
bf 4, .Laltivec_save_v8
|
||||
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
|
||||
|
||||
.Laltivec_save_v8:
|
||||
|
||||
bf 8, .Laltivec_save_v12
|
||||
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
|
||||
|
||||
.Laltivec_save_v12:
|
||||
|
||||
bf 12, .Laltivec_save_v16
|
||||
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
|
||||
|
||||
.Laltivec_save_v16:
|
||||
|
||||
bf 16, .Laltivec_save_continue
|
||||
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
|
||||
|
||||
b .Laltivec_save_continue
|
||||
|
||||
.Laltivec_restore:
|
||||
|
||||
/* Load VCSR using V0 */
|
||||
li SCRATCH_5_REGISTER, PPC_EXC_MIN_VSCR_OFFSET
|
||||
lvewx v0, r1, SCRATCH_5_REGISTER
|
||||
|
||||
/* See comment at .Laltivec_save */
|
||||
lis SCRATCH_5_REGISTER, 0x7777
|
||||
ori SCRATCH_5_REGISTER, SCRATCH_5_REGISTER, 0x7777
|
||||
and SCRATCH_6_REGISTER, SCRATCH_0_REGISTER, SCRATCH_5_REGISTER
|
||||
add SCRATCH_6_REGISTER, SCRATCH_5_REGISTER, SCRATCH_6_REGISTER
|
||||
or SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, SCRATCH_6_REGISTER
|
||||
mtcr SCRATCH_0_REGISTER
|
||||
|
||||
/* Restore VCR using V0 */
|
||||
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
|
||||
|
||||
bf 4, .Laltivec_restore_v8
|
||||
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
|
||||
|
||||
.Laltivec_restore_v8:
|
||||
|
||||
bf 8, .Laltivec_restore_v12
|
||||
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
|
||||
|
||||
.Laltivec_restore_v12:
|
||||
|
||||
bf 12, .Laltivec_restore_v16
|
||||
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
|
||||
|
||||
.Laltivec_restore_v16:
|
||||
|
||||
bf 16, .Laltivec_restore_continue
|
||||
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
|
||||
|
||||
b .Laltivec_restore_continue
|
||||
#endif /* PPC_MULTILIB_ALTIVEC && __PPC_VRSAVE__ */
|
||||
|
||||
/* Symbol provided for debugging and tracing */
|
||||
ppc_exc_interrupt_end:
|
||||
|
||||
|
||||
@@ -79,8 +79,10 @@ PPC_ASSERT_OFFSET(isr_dispatch_disable, ISR_DISPATCH_DISABLE);
|
||||
#endif
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
PPC_ASSERT_OFFSET(vrsave, VRSAVE);
|
||||
PPC_ASSERT_OFFSET(vscr, VSCR);
|
||||
RTEMS_STATIC_ASSERT(
|
||||
PPC_CONTEXT_OFFSET_V20 % 16 == 0,
|
||||
PPC_CONTEXT_OFFSET_V20 % PPC_DEFAULT_CACHE_LINE_SIZE == 0,
|
||||
ppc_context_altivec
|
||||
);
|
||||
PPC_ASSERT_OFFSET(v20, V20);
|
||||
@@ -95,7 +97,6 @@ PPC_ASSERT_OFFSET(isr_dispatch_disable, ISR_DISPATCH_DISABLE);
|
||||
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
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*
|
||||
* Copyright (c) 2001 Surrey Satellite Technology Limited (SSTL).
|
||||
*
|
||||
* Copyright (c) 2010, 2017 embedded brains GmbH.
|
||||
* Copyright (c) 2010, 2020 embedded brains GmbH.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -246,6 +246,13 @@ typedef struct {
|
||||
uint32_t isr_dispatch_disable;
|
||||
uint32_t reserved_for_alignment;
|
||||
#if defined(PPC_MULTILIB_ALTIVEC)
|
||||
#if !defined(__powerpc64__)
|
||||
uint32_t reserved_for_alignment_2[4];
|
||||
#endif
|
||||
uint32_t vrsave;
|
||||
uint32_t reserved_for_alignment_3[2];
|
||||
/* This field must take stvewx/lvewx requirements into account */
|
||||
uint32_t vscr;
|
||||
uint8_t v20[16];
|
||||
uint8_t v21[16];
|
||||
uint8_t v22[16];
|
||||
@@ -258,7 +265,6 @@ typedef struct {
|
||||
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
|
||||
@@ -373,8 +379,16 @@ static inline ppc_context *ppc_get_context( const Context_Control *context )
|
||||
#define PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE PPC_CONTEXT_GPR_OFFSET( 32 )
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
#ifdef __powerpc64__
|
||||
#define PPC_CONTEXT_OFFSET_VRSAVE \
|
||||
( PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE + 8 )
|
||||
#else
|
||||
#define PPC_CONTEXT_OFFSET_VRSAVE \
|
||||
( PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE + 24 )
|
||||
#endif
|
||||
#define PPC_CONTEXT_OFFSET_VSCR ( PPC_CONTEXT_OFFSET_VRSAVE + 12 )
|
||||
#define PPC_CONTEXT_OFFSET_V( v ) \
|
||||
( ( ( v ) - 20 ) * 16 + PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE + 8)
|
||||
( ( ( v ) - 20 ) * 16 + PPC_CONTEXT_OFFSET_VRSAVE + 16)
|
||||
#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 )
|
||||
@@ -387,9 +401,8 @@ static inline ppc_context *ppc_get_context( const Context_Control *context )
|
||||
#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_CONTEXT_OFFSET_VRSAVE + 8 )
|
||||
( ( ( f ) - 14 ) * 8 + PPC_CONTEXT_OFFSET_V( 32 ) )
|
||||
#else
|
||||
#define PPC_CONTEXT_OFFSET_F( f ) \
|
||||
( ( ( f ) - 14 ) * 8 + PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE + 8 )
|
||||
@@ -419,7 +432,7 @@ static inline ppc_context *ppc_get_context( const Context_Control *context )
|
||||
#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)
|
||||
#define PPC_CONTEXT_VOLATILE_SIZE PPC_CONTEXT_OFFSET_V( 33 )
|
||||
#elif defined(__ALTIVEC__)
|
||||
#define PPC_CONTEXT_VOLATILE_SIZE \
|
||||
(PPC_CONTEXT_GPR_OFFSET( 32 ) + 8 \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
|
||||
* Copyright (c) 2013, 2020 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -99,6 +99,7 @@
|
||||
#define VTMP_OFFSET VOFFSET(12)
|
||||
#define VTMP2_OFFSET VOFFSET(13)
|
||||
#define VRSAVE_OFFSET VOFFSET(14)
|
||||
#define VRSAVE2_OFFSET (VOFFSET(14) + 4)
|
||||
#define VSCR_OFFSET (VOFFSET(14) + 12)
|
||||
#define ALTIVECEND VOFFSET(15)
|
||||
#else
|
||||
@@ -161,6 +162,13 @@ _CPU_Context_validate:
|
||||
#endif
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
mfvrsave r0
|
||||
stw r0, VRSAVE_OFFSET(r1)
|
||||
li r0, 0xffffffff
|
||||
mtvrsave r0
|
||||
mfvscr v0
|
||||
li r0, VSCR_OFFSET
|
||||
stvewx v0, r1, r0
|
||||
li r0, V20_OFFSET
|
||||
stvx v20, r1, r0
|
||||
li r0, V21_OFFSET
|
||||
@@ -185,11 +193,6 @@ _CPU_Context_validate:
|
||||
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 */
|
||||
@@ -337,8 +340,10 @@ _CPU_Context_validate:
|
||||
FILL_V 29
|
||||
FILL_V 30
|
||||
FILL_V 31
|
||||
#ifndef __PPC_VRSAVE__
|
||||
addi r4, r3, 0x700
|
||||
mtvrsave r4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Check */
|
||||
@@ -516,6 +521,15 @@ check:
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
.macro CHECK_V i
|
||||
#ifdef __PPC_VRSAVE__
|
||||
mfvrsave r4
|
||||
.if (31 - \i) > 15
|
||||
andis. r5, r4, 1 << (31 - \i - 16)
|
||||
.else
|
||||
andi. r5, r4, 1 << (31 - \i)
|
||||
.endif
|
||||
beq 1f
|
||||
#endif
|
||||
li r4, VTMP_OFFSET
|
||||
stvx \i, r1, r4
|
||||
lwz r5, VTMP_OFFSET(r1)
|
||||
@@ -534,9 +548,43 @@ check:
|
||||
addi r4, r3, 0x600 + \i
|
||||
cmpw r5, r4
|
||||
bne restore
|
||||
#ifdef __PPC_VRSAVE__
|
||||
mfvrsave r4
|
||||
.if (31 - \i) > 15
|
||||
xoris r4, r4, 1 << (31 - \i - 16)
|
||||
.else
|
||||
xori r4, r4, 1 << (31 - \i)
|
||||
.endif
|
||||
mtvrsave r4
|
||||
b 2f
|
||||
1:
|
||||
.if (31 - \i) > 15
|
||||
oris r4, r4, 1 << (31 - \i - 16)
|
||||
.else
|
||||
ori r4, r4, 1 << (31 - \i)
|
||||
.endif
|
||||
mtvrsave r4
|
||||
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
|
||||
2:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* Check VSCR */
|
||||
#ifdef __PPC_VRSAVE__
|
||||
mfvrsave r4
|
||||
stw r4, VRSAVE2_OFFSET(r1)
|
||||
oris r4, r4, 0x8000
|
||||
mtvrsave r4
|
||||
#endif
|
||||
li r4, VTMP_OFFSET
|
||||
stvx v0, r1, r4
|
||||
mfvscr v0
|
||||
@@ -548,6 +596,10 @@ check:
|
||||
bne restore
|
||||
li r4, VTMP_OFFSET
|
||||
lvx v0, r1, r4
|
||||
#ifdef __PPC_VRSAVE__
|
||||
lwz r4, VRSAVE2_OFFSET(r1)
|
||||
mtvrsave r4
|
||||
#endif
|
||||
|
||||
CHECK_V 0
|
||||
CHECK_V 1
|
||||
@@ -582,9 +634,15 @@ check:
|
||||
CHECK_V 30
|
||||
CHECK_V 31
|
||||
mfvrsave r5
|
||||
#ifdef __PPC_VRSAVE__
|
||||
addi r5, r5, 1
|
||||
cmplwi r0, r5, 1
|
||||
bgt restore
|
||||
#else
|
||||
addi r4, r3, 0x700
|
||||
cmpw r5, r4
|
||||
bne restore
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mtcr r29
|
||||
@@ -595,7 +653,7 @@ check:
|
||||
restore:
|
||||
|
||||
#ifdef PPC_MULTILIB_ALTIVEC
|
||||
lwz r0, VRSAVE_OFFSET(r1)
|
||||
li r0, 0xffffffff
|
||||
mtvrsave r0
|
||||
li r0, V31_OFFSET
|
||||
lvx v31, r1, r0
|
||||
@@ -621,6 +679,11 @@ restore:
|
||||
lvx v21, r1, r0
|
||||
li r0, V20_OFFSET
|
||||
lvx v20, r1, r0
|
||||
li r0, VSCR_OFFSET
|
||||
lvewx v0, r1, r0
|
||||
mtvscr v0
|
||||
lwz r0, VRSAVE_OFFSET(r1)
|
||||
mtvrsave r0
|
||||
#endif
|
||||
|
||||
#ifdef PPC_MULTILIB_FPU
|
||||
|
||||
Reference in New Issue
Block a user