summaryrefslogtreecommitdiff
path: root/core/arch/arm/include/kernel/vfp.h
blob: dc65c37252b7d5133300c81a878f900b57f01cc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* SPDX-License-Identifier: BSD-2-Clause */
/*
 * Copyright (c) 2015, Linaro Limited
 */

#ifndef KERNEL_VFP_H
#define KERNEL_VFP_H

#include <types_ext.h>
#include <compiler.h>

#ifdef ARM32
/*
 * Advanced SIMD/floating point state on ARMv7-A or ARMv8-A AArch32 has:
 * - 32 64-bit data registers
 * - FPSCR (32 bits)
 * - FPEXC (32 bits)
 */

#define VFP_NUM_REGS	32

struct vfp_reg {
	uint64_t v;
};

struct vfp_state {
	uint32_t fpexc;
	uint32_t fpscr;
	struct vfp_reg reg[VFP_NUM_REGS];
};
#endif

#ifdef ARM64
/*
 * Advanced SIMD/floating point state on ARMv8-A AArch64 has:
 * - 32 128-bit data registers
 * - FPSR (32 bits)
 * - FPCR (32 bits)
 * - CPACR_EL1.FPEN (2 bits)
 */

#define VFP_NUM_REGS	32

struct vfp_reg {
	uint8_t v[16];
} __aligned(16);

struct vfp_state {
	struct vfp_reg reg[VFP_NUM_REGS];
	uint32_t fpsr;
	uint32_t fpcr;
	uint32_t cpacr_el1;
	bool force_save; /* Save to reg even if VFP was not enabled */
};
#endif

#ifdef CFG_WITH_VFP
/* vfp_is_enabled() - Returns true if VFP is enabled */
bool vfp_is_enabled(void);

/* vfp_enable() - Enables vfp */
void vfp_enable(void);

/* vfp_disable() - Disables vfp */
void vfp_disable(void);
#else
static inline bool vfp_is_enabled(void)
{
	return false;
}

static inline void vfp_enable(void)
{
}

static inline void vfp_disable(void)
{
}
#endif

/*
 * vfp_lazy_save_state_init() - Saves VFP enable status and disables VFP
 * @state:	VFP state structure to initialize
 */
void vfp_lazy_save_state_init(struct vfp_state *state);

/*
 * vfp_lazy_save_state_final() - Saves rest of VFP state
 * @state:	VFP state to save to
 *
 * If VFP was enabled when vfp_lazy_save_state_init() was called: save rest
 * of state and disable VFP. Otherwise, do nothing.
 */
void vfp_lazy_save_state_final(struct vfp_state *state);

/*
 * vfp_lazy_restore_state() - Lazy restore VFP state
 * @state:		VFP state to restore
 *
 * Restores VFP enable status and also restores rest of VFP state if
 * vfp_lazy_save_state_final() was called on this state.
 */
void vfp_lazy_restore_state(struct vfp_state *state, bool full_state);

#endif /*KERNEL_VFP_H*/