mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-21 20:14:29 +00:00
feat(fpmr): disable FPMR trap
This patch enables support of FEAT_FPMR by enabling access to FPMR register. It achieves it by setting the EnFPM bit of SCR_EL3. This feature is currently enabled for NS world only. Reference: https://developer.arm.com/documentation/109697/2024_09/ Feature-descriptions/The-Armv9-5-architecture-extension?lang=en Change-Id: I580c409b9b22f8ead0737502280fb9093a3d5dd2 Signed-off-by: Arvind Ram Prakash <arvind.ramprakash@arm.com>
This commit is contained in:
parent
e372c29153
commit
a57e18e433
12 changed files with 110 additions and 0 deletions
15
Makefile
15
Makefile
|
@ -951,8 +951,21 @@ ifeq (${ARCH},aarch32)
|
||||||
ifeq (${ENABLE_FEAT_RNG_TRAP},1)
|
ifeq (${ENABLE_FEAT_RNG_TRAP},1)
|
||||||
$(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
|
$(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (${ENABLE_FEAT_FPMR},0)
|
||||||
|
$(error "ENABLE_FEAT_FPMR cannot be used with ARCH=aarch32")
|
||||||
|
endif
|
||||||
endif #(ARCH=aarch32)
|
endif #(ARCH=aarch32)
|
||||||
|
|
||||||
|
ifneq (${ENABLE_FEAT_FPMR},0)
|
||||||
|
ifeq (${ENABLE_FEAT_FGT},0)
|
||||||
|
$(error "ENABLE_FEAT_FPMR requires ENABLE_FEAT_FGT")
|
||||||
|
endif
|
||||||
|
ifeq (${ENABLE_FEAT_HCX},0)
|
||||||
|
$(error "ENABLE_FEAT_FPMR requires ENABLE_FEAT_HCX")
|
||||||
|
endif
|
||||||
|
endif #(ENABLE_FEAT_FPMR)
|
||||||
|
|
||||||
ifneq (${ENABLE_SME_FOR_NS},0)
|
ifneq (${ENABLE_SME_FOR_NS},0)
|
||||||
ifeq (${ENABLE_SVE_FOR_NS},0)
|
ifeq (${ENABLE_SVE_FOR_NS},0)
|
||||||
$(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
|
$(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
|
||||||
|
@ -1264,6 +1277,7 @@ $(eval $(call assert_numerics,\
|
||||||
ENABLE_FEAT_ECV \
|
ENABLE_FEAT_ECV \
|
||||||
ENABLE_FEAT_FGT \
|
ENABLE_FEAT_FGT \
|
||||||
ENABLE_FEAT_FGT2 \
|
ENABLE_FEAT_FGT2 \
|
||||||
|
ENABLE_FEAT_FPMR \
|
||||||
ENABLE_FEAT_HCX \
|
ENABLE_FEAT_HCX \
|
||||||
ENABLE_FEAT_LS64_ACCDATA \
|
ENABLE_FEAT_LS64_ACCDATA \
|
||||||
ENABLE_FEAT_MTE2 \
|
ENABLE_FEAT_MTE2 \
|
||||||
|
@ -1425,6 +1439,7 @@ $(eval $(call add_defines,\
|
||||||
ENABLE_MPMM_FCONF \
|
ENABLE_MPMM_FCONF \
|
||||||
ENABLE_FEAT_FGT \
|
ENABLE_FEAT_FGT \
|
||||||
ENABLE_FEAT_FGT2 \
|
ENABLE_FEAT_FGT2 \
|
||||||
|
ENABLE_FEAT_FPMR \
|
||||||
ENABLE_FEAT_ECV \
|
ENABLE_FEAT_ECV \
|
||||||
ENABLE_FEAT_AMUv1p1 \
|
ENABLE_FEAT_AMUv1p1 \
|
||||||
ENABLE_FEAT_SEL2 \
|
ENABLE_FEAT_SEL2 \
|
||||||
|
|
|
@ -150,6 +150,10 @@ ifneq (${ENABLE_TRF_FOR_NS},0)
|
||||||
BL31_SOURCES += lib/extensions/trf/aarch64/trf.c
|
BL31_SOURCES += lib/extensions/trf/aarch64/trf.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (${ENABLE_FEAT_FPMR},0)
|
||||||
|
BL31_SOURCES += lib/extensions/fpmr/fpmr.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq (${WORKAROUND_CVE_2017_5715},1)
|
ifeq (${WORKAROUND_CVE_2017_5715},1)
|
||||||
BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \
|
BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \
|
||||||
lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
|
lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
|
||||||
|
|
|
@ -280,6 +280,12 @@ static unsigned int read_feat_d128_id_field(void)
|
||||||
ID_AA64MMFR3_EL1_D128_MASK);
|
ID_AA64MMFR3_EL1_D128_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int read_feat_fpmr_id_field(void)
|
||||||
|
{
|
||||||
|
return ISOLATE_FIELD(read_id_aa64pfr2_el1(), ID_AA64PFR2_EL1_FPMR_SHIFT,
|
||||||
|
ID_AA64PFR2_EL1_FPMR_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************
|
/***********************************************************************************
|
||||||
* TF-A supports many Arm architectural features starting from arch version
|
* TF-A supports many Arm architectural features starting from arch version
|
||||||
* (8.0 till 8.7+). These features are mostly enabled through build flags. This
|
* (8.0 till 8.7+). These features are mostly enabled through build flags. This
|
||||||
|
@ -405,6 +411,8 @@ void detect_arch_features(void)
|
||||||
"SME", 1, 2);
|
"SME", 1, 2);
|
||||||
check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
|
check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
|
||||||
"SME2", 2, 2);
|
"SME2", 2, 2);
|
||||||
|
check_feature(ENABLE_FEAT_FPMR, read_feat_fpmr_id_field(),
|
||||||
|
"FPMR", 1, 1);
|
||||||
|
|
||||||
/* v9.3 features */
|
/* v9.3 features */
|
||||||
check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),
|
check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),
|
||||||
|
|
|
@ -351,6 +351,12 @@ Common build options
|
||||||
This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
|
This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
|
||||||
mechanism. Default value is ``0``.
|
mechanism. Default value is ``0``.
|
||||||
|
|
||||||
|
- ``ENABLE_FEAT_FPMR``: Numerical value to enable support for Floating Point
|
||||||
|
Mode Register feature, allowing access to the FPMR register. FPMR register
|
||||||
|
controls the behaviors of FP8 instructions. It is an optional architectural
|
||||||
|
feature from v9.2 and upwards. This flag can take value of 0 to 2, to align
|
||||||
|
with the ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
|
||||||
|
|
||||||
- ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
|
- ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
|
||||||
feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
|
feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
|
||||||
Read Trap Register) during EL2 to EL3 context save/restore operations.
|
Read Trap Register) during EL2 to EL3 context save/restore operations.
|
||||||
|
|
|
@ -465,6 +465,11 @@
|
||||||
#define ID_AA64PFR2_EL1_MTEFAR_SHIFT U(8)
|
#define ID_AA64PFR2_EL1_MTEFAR_SHIFT U(8)
|
||||||
#define ID_AA64PFR2_EL1_MTEFAR_MASK ULL(0xf)
|
#define ID_AA64PFR2_EL1_MTEFAR_MASK ULL(0xf)
|
||||||
|
|
||||||
|
#define ID_AA64PFR2_EL1_FPMR_SHIFT U(32)
|
||||||
|
#define ID_AA64PFR2_EL1_FPMR_MASK ULL(0xf)
|
||||||
|
|
||||||
|
#define FPMR_IMPLEMENTED ULL(0x1)
|
||||||
|
|
||||||
#define VDISR_EL2 S3_4_C12_C1_1
|
#define VDISR_EL2 S3_4_C12_C1_1
|
||||||
#define VSESR_EL2 S3_4_C5_C2_3
|
#define VSESR_EL2 S3_4_C5_C2_3
|
||||||
|
|
||||||
|
@ -605,6 +610,7 @@
|
||||||
#define SCR_NSE_SHIFT U(62)
|
#define SCR_NSE_SHIFT U(62)
|
||||||
#define SCR_FGTEN2_BIT (UL(1) << 59)
|
#define SCR_FGTEN2_BIT (UL(1) << 59)
|
||||||
#define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT)
|
#define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT)
|
||||||
|
#define SCR_EnFPM_BIT (ULL(1) << 50)
|
||||||
#define SCR_GPF_BIT (UL(1) << 48)
|
#define SCR_GPF_BIT (UL(1) << 48)
|
||||||
#define SCR_D128En_BIT (UL(1) << 47)
|
#define SCR_D128En_BIT (UL(1) << 47)
|
||||||
#define SCR_TWEDEL_SHIFT U(30)
|
#define SCR_TWEDEL_SHIFT U(30)
|
||||||
|
@ -1522,6 +1528,11 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6
|
#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* FEAT_FPMR - Floating point Mode Register
|
||||||
|
******************************************************************************/
|
||||||
|
#define FPMR S3_3_C4_C4_2
|
||||||
|
|
||||||
/* CLUSTERPWRDN_EL1 register definitions */
|
/* CLUSTERPWRDN_EL1 register definitions */
|
||||||
#define DSU_CLUSTER_PWR_OFF 0
|
#define DSU_CLUSTER_PWR_OFF 0
|
||||||
#define DSU_CLUSTER_PWR_ON 1
|
#define DSU_CLUSTER_PWR_ON 1
|
||||||
|
|
|
@ -142,6 +142,8 @@ CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
|
||||||
* +----------------------------+
|
* +----------------------------+
|
||||||
* | FEAT_LS64_ACCDATA |
|
* | FEAT_LS64_ACCDATA |
|
||||||
* +----------------------------+
|
* +----------------------------+
|
||||||
|
* | FEAT_FPMR |
|
||||||
|
* +----------------------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
|
@ -284,6 +286,12 @@ CREATE_FEATURE_FUNCS(feat_d128, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_D128_SHIFT,
|
||||||
ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
|
ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
|
||||||
ENABLE_FEAT_D128)
|
ENABLE_FEAT_D128)
|
||||||
|
|
||||||
|
/* FEAT_FPMR */
|
||||||
|
CREATE_FEATURE_FUNCS(feat_fpmr, id_aa64pfr2_el1, ID_AA64PFR2_EL1_FPMR_SHIFT,
|
||||||
|
ID_AA64PFR2_EL1_FPMR_MASK, FPMR_IMPLEMENTED,
|
||||||
|
ENABLE_FEAT_FPMR)
|
||||||
|
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
static inline bool is_feat_sxpie_supported(void)
|
static inline bool is_feat_sxpie_supported(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -718,6 +718,8 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(cpumpmmcr_el3, CPUMPMMCR_EL3)
|
||||||
DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3)
|
DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3)
|
||||||
DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
|
DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
|
||||||
|
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(fpmr, FPMR)
|
||||||
|
|
||||||
#define IS_IN_EL(x) \
|
#define IS_IN_EL(x) \
|
||||||
(GET_EL(read_CurrentEl()) == MODE_EL##x)
|
(GET_EL(read_CurrentEl()) == MODE_EL##x)
|
||||||
|
|
||||||
|
|
20
include/lib/extensions/fpmr.h
Normal file
20
include/lib/extensions/fpmr.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FPMR_H
|
||||||
|
#define FPMR_H
|
||||||
|
|
||||||
|
#include <context.h>
|
||||||
|
|
||||||
|
#if ENABLE_FEAT_FPMR
|
||||||
|
void fpmr_enable_per_world(per_world_context_t *per_world_ctx);
|
||||||
|
#else
|
||||||
|
static inline void fpmr_enable_per_world(per_world_context_t *per_world_ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_FEAT_FPMR */
|
||||||
|
|
||||||
|
#endif /* FPMR_H */
|
|
@ -28,6 +28,7 @@
|
||||||
#include <lib/extensions/brbe.h>
|
#include <lib/extensions/brbe.h>
|
||||||
#include <lib/extensions/debug_v8p9.h>
|
#include <lib/extensions/debug_v8p9.h>
|
||||||
#include <lib/extensions/fgt2.h>
|
#include <lib/extensions/fgt2.h>
|
||||||
|
#include <lib/extensions/fpmr.h>
|
||||||
#include <lib/extensions/mpam.h>
|
#include <lib/extensions/mpam.h>
|
||||||
#include <lib/extensions/pmuv3.h>
|
#include <lib/extensions/pmuv3.h>
|
||||||
#include <lib/extensions/sme.h>
|
#include <lib/extensions/sme.h>
|
||||||
|
@ -291,6 +292,13 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
|
||||||
scr_el3 |= SCR_D128En_BIT;
|
scr_el3 |= SCR_D128En_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_feat_fpmr_supported()) {
|
||||||
|
/* Set the EnFPM bit in SCR_EL3 to enable access to FPMR
|
||||||
|
* register.
|
||||||
|
*/
|
||||||
|
scr_el3 |= SCR_EnFPM_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
|
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
|
||||||
|
|
||||||
/* Initialize EL2 context registers */
|
/* Initialize EL2 context registers */
|
||||||
|
@ -714,6 +722,10 @@ void manage_extensions_nonsecure_per_world(void)
|
||||||
if (is_feat_mpam_supported()) {
|
if (is_feat_mpam_supported()) {
|
||||||
mpam_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
|
mpam_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_feat_fpmr_supported()) {
|
||||||
|
fpmr_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* IMAGE_BL31 */
|
#endif /* IMAGE_BL31 */
|
||||||
|
|
||||||
|
|
20
lib/extensions/fpmr/fpmr.c
Normal file
20
lib/extensions/fpmr/fpmr.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Arm Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <arch_features.h>
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <lib/extensions/fpmr.h>
|
||||||
|
|
||||||
|
void fpmr_enable_per_world(per_world_context_t *per_world_ctx)
|
||||||
|
{
|
||||||
|
u_register_t reg;
|
||||||
|
|
||||||
|
/* Disable Floating point Trap in CPTR_EL3. */
|
||||||
|
reg = per_world_ctx->ctx_cptr_el3;
|
||||||
|
reg &= ~TFP_BIT;
|
||||||
|
per_world_ctx->ctx_cptr_el3 = reg;
|
||||||
|
}
|
|
@ -408,6 +408,9 @@ ENABLE_SME_FOR_SWD ?= 0
|
||||||
# if FEAT_BRBE is implemented.
|
# if FEAT_BRBE is implemented.
|
||||||
ENABLE_BRBE_FOR_NS ?= 0
|
ENABLE_BRBE_FOR_NS ?= 0
|
||||||
|
|
||||||
|
# Flag to enable Floating point exception Mode Register Feature (FEAT_FPMR)
|
||||||
|
ENABLE_FEAT_FPMR ?= 0
|
||||||
|
|
||||||
#----
|
#----
|
||||||
# 9.3
|
# 9.3
|
||||||
#----
|
#----
|
||||||
|
|
|
@ -57,6 +57,7 @@ endif
|
||||||
ENABLE_BRBE_FOR_NS := 2
|
ENABLE_BRBE_FOR_NS := 2
|
||||||
ENABLE_TRBE_FOR_NS := 2
|
ENABLE_TRBE_FOR_NS := 2
|
||||||
ENABLE_FEAT_D128 := 2
|
ENABLE_FEAT_D128 := 2
|
||||||
|
ENABLE_FEAT_FPMR := 2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ENABLE_SYS_REG_TRACE_FOR_NS := 2
|
ENABLE_SYS_REG_TRACE_FOR_NS := 2
|
||||||
|
|
Loading…
Add table
Reference in a new issue