xref: /optee_os/core/arch/arm/include/kernel/vfp.h (revision d50fee0321fe6853ac6352cf0fd548666457b407)
11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */
2bc46c1c6SJerome Forissier /*
3bc46c1c6SJerome Forissier  * Copyright (c) 2015, Linaro Limited
4bc46c1c6SJerome Forissier  */
5bc46c1c6SJerome Forissier 
6*d50fee03SEtienne Carriere #ifndef __KERNEL_VFP_H
7*d50fee03SEtienne Carriere #define __KERNEL_VFP_H
8abe38974SJens Wiklander 
9abe38974SJens Wiklander #include <types_ext.h>
10bc46c1c6SJerome Forissier #include <compiler.h>
11bc46c1c6SJerome Forissier 
12bc46c1c6SJerome Forissier #ifdef ARM32
13bc46c1c6SJerome Forissier /*
14bc46c1c6SJerome Forissier  * Advanced SIMD/floating point state on ARMv7-A or ARMv8-A AArch32 has:
15bc46c1c6SJerome Forissier  * - 32 64-bit data registers
16bc46c1c6SJerome Forissier  * - FPSCR (32 bits)
17bc46c1c6SJerome Forissier  * - FPEXC (32 bits)
18bc46c1c6SJerome Forissier  */
19abe38974SJens Wiklander 
204a6784caSJens Wiklander #define VFP_NUM_REGS	U(32)
21abe38974SJens Wiklander 
22bc46c1c6SJerome Forissier struct vfp_reg {
23bc46c1c6SJerome Forissier 	uint64_t v;
24bc46c1c6SJerome Forissier };
25bc46c1c6SJerome Forissier 
26abe38974SJens Wiklander struct vfp_state {
27abe38974SJens Wiklander 	uint32_t fpexc;
28abe38974SJens Wiklander 	uint32_t fpscr;
29bc46c1c6SJerome Forissier 	struct vfp_reg reg[VFP_NUM_REGS];
30abe38974SJens Wiklander };
31bc46c1c6SJerome Forissier #endif
32bc46c1c6SJerome Forissier 
33bc46c1c6SJerome Forissier #ifdef ARM64
34bc46c1c6SJerome Forissier /*
35bc46c1c6SJerome Forissier  * Advanced SIMD/floating point state on ARMv8-A AArch64 has:
36bc46c1c6SJerome Forissier  * - 32 128-bit data registers
37bc46c1c6SJerome Forissier  * - FPSR (32 bits)
38bc46c1c6SJerome Forissier  * - FPCR (32 bits)
39bc46c1c6SJerome Forissier  * - CPACR_EL1.FPEN (2 bits)
40bc46c1c6SJerome Forissier  */
41bc46c1c6SJerome Forissier 
424a6784caSJens Wiklander #define VFP_NUM_REGS	U(32)
43bc46c1c6SJerome Forissier 
44bc46c1c6SJerome Forissier struct vfp_reg {
45bc46c1c6SJerome Forissier 	uint8_t v[16];
46bc46c1c6SJerome Forissier } __aligned(16);
47bc46c1c6SJerome Forissier 
48bc46c1c6SJerome Forissier struct vfp_state {
49bc46c1c6SJerome Forissier 	struct vfp_reg reg[VFP_NUM_REGS];
50bc46c1c6SJerome Forissier 	uint32_t fpsr;
51bc46c1c6SJerome Forissier 	uint32_t fpcr;
52bc46c1c6SJerome Forissier 	uint32_t cpacr_el1;
53bc46c1c6SJerome Forissier };
54bc46c1c6SJerome Forissier #endif
55abe38974SJens Wiklander 
560de9a5fbSJens Wiklander #ifdef CFG_WITH_VFP
570de9a5fbSJens Wiklander /* vfp_is_enabled() - Returns true if VFP is enabled */
58abe38974SJens Wiklander bool vfp_is_enabled(void);
590de9a5fbSJens Wiklander 
600de9a5fbSJens Wiklander /* vfp_enable() - Enables vfp */
61abe38974SJens Wiklander void vfp_enable(void);
620de9a5fbSJens Wiklander 
630de9a5fbSJens Wiklander /* vfp_disable() - Disables vfp */
64abe38974SJens Wiklander void vfp_disable(void);
650de9a5fbSJens Wiklander #else
vfp_is_enabled(void)660de9a5fbSJens Wiklander static inline bool vfp_is_enabled(void)
670de9a5fbSJens Wiklander {
680de9a5fbSJens Wiklander 	return false;
690de9a5fbSJens Wiklander }
700de9a5fbSJens Wiklander 
vfp_enable(void)710de9a5fbSJens Wiklander static inline void vfp_enable(void)
720de9a5fbSJens Wiklander {
730de9a5fbSJens Wiklander }
740de9a5fbSJens Wiklander 
vfp_disable(void)750de9a5fbSJens Wiklander static inline void vfp_disable(void)
760de9a5fbSJens Wiklander {
770de9a5fbSJens Wiklander }
780de9a5fbSJens Wiklander #endif
79abe38974SJens Wiklander 
80abe38974SJens Wiklander /*
81bc46c1c6SJerome Forissier  * vfp_lazy_save_state_init() - Saves VFP enable status and disables VFP
82abe38974SJens Wiklander  * @state:	VFP state structure to initialize
83abe38974SJens Wiklander  */
84abe38974SJens Wiklander void vfp_lazy_save_state_init(struct vfp_state *state);
85abe38974SJens Wiklander 
86abe38974SJens Wiklander /*
87abe38974SJens Wiklander  * vfp_lazy_save_state_final() - Saves rest of VFP state
88bc46c1c6SJerome Forissier  * @state:	VFP state to save to
898e01b4b9SJens Wiklander  * @force_save:	Forces saving of state regardless of previous state if true.
90abe38974SJens Wiklander  *
918e01b4b9SJens Wiklander  * If VFP was enabled when vfp_lazy_save_state_init() was called or
928e01b4b9SJens Wiklander  * @force_save is true: save rest of state and disable VFP. Otherwise, do
938e01b4b9SJens Wiklander  * nothing.
94abe38974SJens Wiklander  */
958e01b4b9SJens Wiklander void vfp_lazy_save_state_final(struct vfp_state *state, bool force_save);
96abe38974SJens Wiklander 
97abe38974SJens Wiklander /*
98abe38974SJens Wiklander  * vfp_lazy_restore_state() - Lazy restore VFP state
99abe38974SJens Wiklander  * @state:		VFP state to restore
100abe38974SJens Wiklander  *
101bc46c1c6SJerome Forissier  * Restores VFP enable status and also restores rest of VFP state if
102abe38974SJens Wiklander  * vfp_lazy_save_state_final() was called on this state.
103abe38974SJens Wiklander  */
104abe38974SJens Wiklander void vfp_lazy_restore_state(struct vfp_state *state, bool full_state);
105abe38974SJens Wiklander 
106*d50fee03SEtienne Carriere #endif /*__KERNEL_VFP_H*/
107