mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-07 21:33:54 +00:00
feat(d128): add support for FEAT_D128
This patch disables trapping to EL3 when the FEAT_D128 specific registers are accessed by setting the SCR_EL3.D128En bit. If FEAT_D128 is implemented, then FEAT_SYSREG128 is implemented. With FEAT_SYSREG128 certain system registers are treated as 128-bit, so we should be context saving and restoring 128-bits instead of 64-bit when FEAT_D128 is enabled. FEAT_SYSREG128 adds support for MRRS and MSRR instruction which helps us to read write to 128-bit system register. Refer to Arm Architecture Manual for further details. Change the FVP platform to default to handling this as a dynamic option so the right decision can be made by the code at runtime. Change-Id: I1a53db5eac29e56c8fbdcd4961ede3abfcb2411a Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com> Signed-off-by: Govindraj Raja <govindraj.raja@arm.com>
This commit is contained in:
parent
57c20e2427
commit
306551362c
20 changed files with 324 additions and 25 deletions
9
Makefile
9
Makefile
|
@ -645,6 +645,13 @@ ifeq (${CTX_INCLUDE_EL2_REGS}, 1)
|
|||
endif
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Make 128-Bit sysreg read/writes availabe when FEAT_D128 is enabled.
|
||||
################################################################################
|
||||
ifneq (${ENABLE_FEAT_D128}, 0)
|
||||
BL_COMMON_SOURCES += lib/extensions/sysreg128/sysreg128.S
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Platform specific Makefile might provide us ARCH_MAJOR/MINOR use that to come
|
||||
# up with appropriate march values for compiler.
|
||||
|
@ -1263,6 +1270,7 @@ $(eval $(call assert_numerics,\
|
|||
ENABLE_FEAT_S2POE \
|
||||
ENABLE_FEAT_S1POE \
|
||||
ENABLE_FEAT_SCTLR2 \
|
||||
ENABLE_FEAT_D128 \
|
||||
ENABLE_FEAT_GCS \
|
||||
ENABLE_FEAT_VHE \
|
||||
ENABLE_FEAT_MPAM \
|
||||
|
@ -1421,6 +1429,7 @@ $(eval $(call add_defines,\
|
|||
ENABLE_FEAT_S2POE \
|
||||
ENABLE_FEAT_S1POE \
|
||||
ENABLE_FEAT_SCTLR2 \
|
||||
ENABLE_FEAT_D128 \
|
||||
ENABLE_FEAT_GCS \
|
||||
ENABLE_FEAT_MTE2 \
|
||||
FEATURE_DETECTION \
|
||||
|
|
|
@ -269,6 +269,12 @@ static unsigned int read_feat_sctlr2_id_field(void)
|
|||
ID_AA64MMFR3_EL1_SCTLR2_MASK);
|
||||
}
|
||||
|
||||
static unsigned int read_feat_d128_id_field(void)
|
||||
{
|
||||
return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_D128_SHIFT,
|
||||
ID_AA64MMFR3_EL1_D128_MASK);
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* 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
|
||||
|
@ -394,6 +400,10 @@ void detect_arch_features(void)
|
|||
check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
|
||||
"SME2", 2, 2);
|
||||
|
||||
/* v9.3 features */
|
||||
check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),
|
||||
"D128", 1, 1);
|
||||
|
||||
/* v9.4 features */
|
||||
check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
|
||||
check_feature(ENABLE_RME, read_feat_rme_id_field(), "RME", 1, 1);
|
||||
|
|
|
@ -471,6 +471,15 @@ Common build options
|
|||
This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
|
||||
mechanism. Default value is ``0``.
|
||||
|
||||
- ``ENABLE_FEAT_D128``: Numeric value to enable support for FEAT_D128
|
||||
at EL2 and below, setting the bit SCT_EL3.D128En in EL3 to allow access to
|
||||
128 bit version of system registers like PAR_EL1, TTBR0_EL1, TTBR1_EL1,
|
||||
TTBR0_EL2, TTBR1_EL2, TTBR0_EL12, TTBR1_EL12 , VTTBR_EL2, RCWMASK_EL1, and
|
||||
RCWSMASK_EL1. Its an optional architectural feature and is available from
|
||||
9.3 and upwards.
|
||||
This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
|
||||
mechanism. Default value is ``0``.
|
||||
|
||||
- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
|
||||
support in GCC for TF-A. This option is currently only supported for
|
||||
AArch64. Default is 0.
|
||||
|
|
|
@ -697,8 +697,7 @@
|
|||
/* PAR fields */
|
||||
#define PAR_F_SHIFT U(0)
|
||||
#define PAR_F_MASK ULL(0x1)
|
||||
#define PAR_ADDR_SHIFT U(12)
|
||||
#define PAR_ADDR_MASK (BIT_64(40) - ULL(1)) /* 40-bits-wide page address */
|
||||
#define PAR_ADDR_MASK GENMASK_64(39, 12) /* 28-bits-wide page address */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions for system register interface to AMU for FEAT_AMUv1
|
||||
|
|
|
@ -194,5 +194,7 @@ __attribute__((always_inline))
|
|||
static inline bool is_feat_ebep_present(void) { return false; }
|
||||
__attribute__((always_inline))
|
||||
static inline bool is_feat_sebep_present(void) { return false; }
|
||||
__attribute__((always_inline))
|
||||
static inline bool is_feat_d128_present(void) { return false; }
|
||||
|
||||
#endif /* ARCH_FEATURES_H */
|
||||
|
|
|
@ -331,6 +331,7 @@
|
|||
#define PARANGE_0100 U(44)
|
||||
#define PARANGE_0101 U(48)
|
||||
#define PARANGE_0110 U(52)
|
||||
#define PARANGE_0111 U(56)
|
||||
|
||||
#define ID_AA64MMFR0_EL1_ECV_SHIFT U(60)
|
||||
#define ID_AA64MMFR0_EL1_ECV_MASK ULL(0xf)
|
||||
|
@ -394,6 +395,10 @@
|
|||
/* ID_AA64MMFR3_EL1 definitions */
|
||||
#define ID_AA64MMFR3_EL1 S3_0_C0_C7_3
|
||||
|
||||
#define ID_AA64MMFR3_EL1_D128_SHIFT U(32)
|
||||
#define ID_AA64MMFR3_EL1_D128_MASK ULL(0xf)
|
||||
#define D128_IMPLEMENTED ULL(0x1)
|
||||
|
||||
#define ID_AA64MMFR3_EL1_S2POE_SHIFT U(20)
|
||||
#define ID_AA64MMFR3_EL1_S2POE_MASK ULL(0xf)
|
||||
|
||||
|
@ -594,6 +599,7 @@
|
|||
#define SCR_FGTEN2_BIT (UL(1) << 59)
|
||||
#define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT)
|
||||
#define SCR_GPF_BIT (UL(1) << 48)
|
||||
#define SCR_D128En_BIT (UL(1) << 47)
|
||||
#define SCR_TWEDEL_SHIFT U(30)
|
||||
#define SCR_TWEDEL_MASK ULL(0xf)
|
||||
#define SCR_PIEN_BIT (UL(1) << 45)
|
||||
|
@ -1179,8 +1185,9 @@
|
|||
/* PAR_EL1 fields */
|
||||
#define PAR_F_SHIFT U(0)
|
||||
#define PAR_F_MASK ULL(0x1)
|
||||
#define PAR_ADDR_SHIFT U(12)
|
||||
#define PAR_ADDR_MASK (BIT(40) - ULL(1)) /* 40-bits-wide page address */
|
||||
|
||||
#define PAR_D128_ADDR_MASK GENMASK(55, 12) /* 44-bits-wide page address */
|
||||
#define PAR_ADDR_MASK GENMASK(51, 12) /* 40-bits-wide page address */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions for system register interface to SPE
|
||||
|
|
|
@ -138,6 +138,8 @@ CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
|
|||
* +----------------------------+
|
||||
* | FEAT_SCTLR2 |
|
||||
* +----------------------------+
|
||||
* | FEAT_D128 |
|
||||
* +----------------------------+
|
||||
*/
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@ -275,6 +277,11 @@ CREATE_FEATURE_FUNCS(feat_sctlr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_SCTLR2_SHIF
|
|||
ID_AA64MMFR3_EL1_SCTLR2_MASK, SCTLR2_IMPLEMENTED,
|
||||
ENABLE_FEAT_SCTLR2)
|
||||
|
||||
/* FEAT_D128 */
|
||||
CREATE_FEATURE_FUNCS(feat_d128, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_D128_SHIFT,
|
||||
ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
|
||||
ENABLE_FEAT_D128)
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline bool is_feat_sxpie_supported(void)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <lib/extensions/sysreg128.h>
|
||||
|
||||
/**********************************************************************
|
||||
* Macros which create inline functions to read or write CPU system
|
||||
|
@ -263,7 +264,12 @@ void disable_mpu_icache_el2(void);
|
|||
#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
|
||||
#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
|
||||
|
||||
#if ENABLE_FEAT_D128
|
||||
DECLARE_SYSREG128_RW_FUNCS(par_el1)
|
||||
#else
|
||||
DEFINE_SYSREG_RW_FUNCS(par_el1)
|
||||
#endif
|
||||
|
||||
DEFINE_IDREG_READ_FUNC(id_pfr1_el1)
|
||||
DEFINE_IDREG_READ_FUNC(id_aa64isar0_el1)
|
||||
DEFINE_IDREG_READ_FUNC(id_aa64isar1_el1)
|
||||
|
@ -443,13 +449,21 @@ DEFINE_SYSREG_RW_FUNCS(tcr_el1)
|
|||
DEFINE_SYSREG_RW_FUNCS(tcr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(tcr_el3)
|
||||
|
||||
#if ENABLE_FEAT_D128
|
||||
DECLARE_SYSREG128_RW_FUNCS(ttbr0_el1)
|
||||
DECLARE_SYSREG128_RW_FUNCS(ttbr1_el1)
|
||||
DECLARE_SYSREG128_RW_FUNCS(ttbr0_el2)
|
||||
DECLARE_SYSREG128_RW_FUNCS(ttbr1_el2)
|
||||
DECLARE_SYSREG128_RW_FUNCS(vttbr_el2)
|
||||
#else
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr0_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr1_el1)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
|
||||
DEFINE_SYSREG_RW_FUNCS(vttbr_el2)
|
||||
#endif
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(cptr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(cptr_el3)
|
||||
|
@ -574,7 +588,6 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el0, SCXTNUM_EL0)
|
|||
|
||||
/* Armv8.1 VHE Registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
|
||||
|
||||
/* Armv8.2 ID Registers */
|
||||
DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
|
||||
|
@ -671,8 +684,13 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
|
|||
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
|
||||
|
||||
/* FEAT_THE Registers */
|
||||
#if ENABLE_FEAT_D128
|
||||
DECLARE_SYSREG128_RW_FUNCS(rcwmask_el1)
|
||||
DECLARE_SYSREG128_RW_FUNCS(rcwsmask_el1)
|
||||
#else
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1)
|
||||
#endif
|
||||
|
||||
/* FEAT_SCTLR2 Registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
|
||||
|
|
30
include/common/par.h
Normal file
30
include/common/par.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PAR_H
|
||||
#define PAR_H
|
||||
|
||||
#include<arch_features.h>
|
||||
#include<lib/extensions/sysreg128.h>
|
||||
|
||||
static inline uint64_t get_par_el1_pa(sysreg_t par)
|
||||
{
|
||||
uint64_t pa = par & UINT64_MAX;
|
||||
/* PA, bits [51:12] is Output address */
|
||||
uint64_t mask = PAR_ADDR_MASK;
|
||||
|
||||
#if ENABLE_FEAT_D128
|
||||
/* If D128 is in use, the PA is in the upper 64-bit word of PAR_EL1 */
|
||||
if (is_feat_d128_supported() && (par & PAR_EL1_D128)) {
|
||||
pa = (par >> 64) & UINT64_MAX;
|
||||
/* PA, bits [55:12] is Output address */
|
||||
mask = PAR_D128_ADDR_MASK;
|
||||
}
|
||||
#endif
|
||||
return pa & mask;
|
||||
}
|
||||
|
||||
#endif /* PAR_H */
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef CONTEXT_EL1_H
|
||||
#define CONTEXT_EL1_H
|
||||
|
||||
#include <lib/extensions/sysreg128.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -28,15 +30,12 @@ typedef struct el1_common_regs {
|
|||
uint64_t csselr_el1;
|
||||
uint64_t sp_el1;
|
||||
uint64_t esr_el1;
|
||||
uint64_t ttbr0_el1;
|
||||
uint64_t ttbr1_el1;
|
||||
uint64_t mair_el1;
|
||||
uint64_t amair_el1;
|
||||
uint64_t actlr_el1;
|
||||
uint64_t tpidr_el1;
|
||||
uint64_t tpidr_el0;
|
||||
uint64_t tpidrro_el0;
|
||||
uint64_t par_el1;
|
||||
uint64_t far_el1;
|
||||
uint64_t afsr0_el1;
|
||||
uint64_t afsr1_el1;
|
||||
|
@ -44,6 +43,9 @@ typedef struct el1_common_regs {
|
|||
uint64_t vbar_el1;
|
||||
uint64_t mdccint_el1;
|
||||
uint64_t mdscr_el1;
|
||||
sysreg_t par_el1;
|
||||
sysreg_t ttbr0_el1;
|
||||
sysreg_t ttbr1_el1;
|
||||
} el1_common_regs_t;
|
||||
|
||||
typedef struct el1_aarch32_regs {
|
||||
|
@ -108,8 +110,8 @@ typedef struct el1_gcs_regs {
|
|||
} el1_gcs_regs_t;
|
||||
|
||||
typedef struct el1_the_regs {
|
||||
uint64_t rcwmask_el1;
|
||||
uint64_t rcwsmask_el1;
|
||||
sysreg_t rcwmask_el1;
|
||||
sysreg_t rcwsmask_el1;
|
||||
} el1_the_regs_t;
|
||||
|
||||
typedef struct el1_sctlr2_regs {
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
#ifndef CONTEXT_EL2_H
|
||||
#define CONTEXT_EL2_H
|
||||
|
||||
#include <lib/extensions/sysreg128.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/*******************************************************************************
|
||||
* EL2 Registers:
|
||||
* AArch64 EL2 system register context structure for preserving the
|
||||
|
@ -40,12 +43,12 @@ typedef struct el2_common_regs {
|
|||
uint64_t sp_el2;
|
||||
uint64_t tcr_el2;
|
||||
uint64_t tpidr_el2;
|
||||
uint64_t ttbr0_el2;
|
||||
uint64_t vbar_el2;
|
||||
uint64_t vmpidr_el2;
|
||||
uint64_t vpidr_el2;
|
||||
uint64_t vtcr_el2;
|
||||
uint64_t vttbr_el2;
|
||||
sysreg_t vttbr_el2;
|
||||
sysreg_t ttbr0_el2;
|
||||
} el2_common_regs_t;
|
||||
|
||||
typedef struct el2_mte2_regs {
|
||||
|
@ -75,7 +78,7 @@ typedef struct el2_ecv_regs {
|
|||
|
||||
typedef struct el2_vhe_regs {
|
||||
uint64_t contextidr_el2;
|
||||
uint64_t ttbr1_el2;
|
||||
sysreg_t ttbr1_el2;
|
||||
} el2_vhe_regs_t;
|
||||
|
||||
typedef struct el2_ras_regs {
|
||||
|
@ -222,6 +225,9 @@ typedef struct el2_sysregs {
|
|||
#define write_el2_ctx_common(ctx, reg, val) ((((ctx)->common).reg) \
|
||||
= (uint64_t) (val))
|
||||
|
||||
#define write_el2_ctx_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \
|
||||
= (sysreg_t) (val))
|
||||
|
||||
#if ENABLE_FEAT_MTE2
|
||||
#define read_el2_ctx_mte2(ctx, reg) (((ctx)->mte2).reg)
|
||||
#define write_el2_ctx_mte2(ctx, reg, val) ((((ctx)->mte2).reg) \
|
||||
|
@ -262,6 +268,9 @@ typedef struct el2_sysregs {
|
|||
#define read_el2_ctx_vhe(ctx, reg) (((ctx)->vhe).reg)
|
||||
#define write_el2_ctx_vhe(ctx, reg, val) ((((ctx)->vhe).reg) \
|
||||
= (uint64_t) (val))
|
||||
|
||||
#define write_el2_ctx_vhe_sysreg128(ctx, reg, val) ((((ctx)->vhe).reg) \
|
||||
= (sysreg_t) (val))
|
||||
#else
|
||||
#define read_el2_ctx_vhe(ctx, reg) ULL(0)
|
||||
#define write_el2_ctx_vhe(ctx, reg, val)
|
||||
|
|
36
include/lib/extensions/sysreg128.h
Normal file
36
include/lib/extensions/sysreg128.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SYSREG128_H
|
||||
#define SYSREG128_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#if ENABLE_FEAT_D128
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint128_t sysreg_t;
|
||||
|
||||
#define PAR_EL1_D128 (((sysreg_t)(1ULL)) << (64))
|
||||
|
||||
#define _DECLARE_SYSREG128_READ_FUNC(_name) \
|
||||
uint128_t read_ ## _name(void);
|
||||
|
||||
#define _DECLARE_SYSREG128_WRITE_FUNC(_name) \
|
||||
void write_ ## _name(uint128_t v);
|
||||
|
||||
#define DECLARE_SYSREG128_RW_FUNCS(_name) \
|
||||
_DECLARE_SYSREG128_READ_FUNC(_name) \
|
||||
_DECLARE_SYSREG128_WRITE_FUNC(_name)
|
||||
#else
|
||||
|
||||
typedef uint64_t sysreg_t;
|
||||
|
||||
#endif /* ENABLE_FEAT_D128 */
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* SYSREG128_H */
|
|
@ -33,6 +33,7 @@
|
|||
#include <lib/extensions/sme.h>
|
||||
#include <lib/extensions/spe.h>
|
||||
#include <lib/extensions/sve.h>
|
||||
#include <lib/extensions/sysreg128.h>
|
||||
#include <lib/extensions/sys_reg_trace.h>
|
||||
#include <lib/extensions/tcr2.h>
|
||||
#include <lib/extensions/trbe.h>
|
||||
|
@ -275,6 +276,14 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
|
|||
scr_el3 |= SCR_SCTLR2En_BIT;
|
||||
}
|
||||
|
||||
if (is_feat_d128_supported()) {
|
||||
/* Set the D128En bit in SCR_EL3 to enable access to 128-bit
|
||||
* versions of TTBR0_EL1, TTBR1_EL1, RCWMASK_EL1, RCWSMASK_EL1,
|
||||
* PAR_EL1 and TTBR1_EL2, TTBR0_EL2 and VTTBR_EL2 registers.
|
||||
*/
|
||||
scr_el3 |= SCR_D128En_BIT;
|
||||
}
|
||||
|
||||
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
|
||||
|
||||
/* Initialize EL2 context registers */
|
||||
|
@ -1322,12 +1331,13 @@ static void el2_sysregs_context_save_common(el2_sysregs_t *ctx)
|
|||
write_el2_ctx_common(ctx, sp_el2, read_sp_el2());
|
||||
write_el2_ctx_common(ctx, tcr_el2, read_tcr_el2());
|
||||
write_el2_ctx_common(ctx, tpidr_el2, read_tpidr_el2());
|
||||
write_el2_ctx_common(ctx, ttbr0_el2, read_ttbr0_el2());
|
||||
write_el2_ctx_common(ctx, vbar_el2, read_vbar_el2());
|
||||
write_el2_ctx_common(ctx, vmpidr_el2, read_vmpidr_el2());
|
||||
write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2());
|
||||
write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2());
|
||||
write_el2_ctx_common(ctx, vttbr_el2, read_vttbr_el2());
|
||||
|
||||
write_el2_ctx_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2());
|
||||
write_el2_ctx_sysreg128(ctx, vttbr_el2, read_vttbr_el2());
|
||||
}
|
||||
|
||||
static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
|
||||
|
@ -1403,7 +1413,7 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
|
|||
if (is_feat_vhe_supported()) {
|
||||
write_el2_ctx_vhe(el2_sysregs_ctx, contextidr_el2,
|
||||
read_contextidr_el2());
|
||||
write_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
|
||||
write_el2_ctx_vhe_sysreg128(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
|
||||
}
|
||||
|
||||
if (is_feat_ras_supported()) {
|
||||
|
|
139
lib/extensions/sysreg128/sysreg128.S
Normal file
139
lib/extensions/sysreg128/sysreg128.S
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <lib/extensions/sysreg128.h>
|
||||
|
||||
.global read_par_el1
|
||||
.global write_par_el1
|
||||
.global read_ttbr0_el1
|
||||
.global write_ttbr0_el1
|
||||
.global read_ttbr1_el1
|
||||
.global write_ttbr1_el1
|
||||
.global read_ttbr0_el2
|
||||
.global write_ttbr0_el2
|
||||
.global read_ttbr1_el2
|
||||
.global write_ttbr1_el2
|
||||
.global read_vttbr_el2
|
||||
.global write_vttbr_el2
|
||||
.global read_rcwmask_el1
|
||||
.global write_rcwmask_el1
|
||||
.global read_rcwsmask_el1
|
||||
.global write_rcwsmask_el1
|
||||
|
||||
/*
|
||||
* _mrrs - Move System register to two adjacent general-purpose
|
||||
* registers.
|
||||
* Instruction: MRRS <Xt>, <Xt+1>, (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>)
|
||||
*
|
||||
* Arguments/Opcode bit field:
|
||||
* regins: System register opcode.
|
||||
*
|
||||
* Clobbers: x0,x1,x2
|
||||
*/
|
||||
.macro _mrrs regins:req
|
||||
#if ENABLE_FEAT_D128 == 2
|
||||
mrs x0, ID_AA64MMFR3_EL1
|
||||
tst x0, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT)
|
||||
bne 1f
|
||||
/* If FEAT_D128 is not implemented then use mrs */
|
||||
.inst 0xD5300000 | (\regins)
|
||||
ret
|
||||
#endif
|
||||
1:
|
||||
.inst 0xD5700000 | (\regins)
|
||||
ret
|
||||
.endm
|
||||
|
||||
/*
|
||||
* _msrr - Move two adjacent general-purpose registers to System register.
|
||||
* Instruction: MSRR (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>, <Xt+1>
|
||||
*
|
||||
* Arguments/Opcode bit field:
|
||||
* regins: System register opcode.
|
||||
*
|
||||
* Clobbers: x0,x1,x2
|
||||
*/
|
||||
.macro _msrr regins:req
|
||||
/* If FEAT_D128 is not implemented use msr, dont tamper
|
||||
* x0, x1 as they maybe used for mrrs */
|
||||
#if ENABLE_FEAT_D128 == 2
|
||||
mrs x2, ID_AA64MMFR3_EL1
|
||||
tst x2, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT)
|
||||
bne 1f
|
||||
/* If FEAT_D128 is not implemented then use msr */
|
||||
.inst 0xD5100000 | (\regins)
|
||||
ret
|
||||
#endif
|
||||
1:
|
||||
.inst 0xD5500000 | (\regins)
|
||||
ret
|
||||
.endm
|
||||
|
||||
func read_par_el1
|
||||
_mrrs 0x87400 /* S3_0_C7_C4_0 */
|
||||
endfunc read_par_el1
|
||||
|
||||
func write_par_el1
|
||||
_msrr 0x87400
|
||||
endfunc write_par_el1
|
||||
|
||||
func read_ttbr0_el1
|
||||
_mrrs 0x82000 /* S3_0_C2_C0_0 */
|
||||
endfunc read_ttbr0_el1
|
||||
|
||||
func write_ttbr0_el1
|
||||
_msrr 0x82000
|
||||
endfunc write_ttbr0_el1
|
||||
|
||||
func read_ttbr1_el1
|
||||
_mrrs 0x82020 /* S3_0_C2_C0_1 */
|
||||
endfunc read_ttbr1_el1
|
||||
|
||||
func write_ttbr1_el1
|
||||
_msrr 0x82020
|
||||
endfunc write_ttbr1_el1
|
||||
|
||||
func read_ttbr0_el2
|
||||
_mrrs 0xC2000 /* S3_4_C2_C0_0 */
|
||||
endfunc read_ttbr0_el2
|
||||
|
||||
func write_ttbr0_el2
|
||||
_msrr 0xC2000
|
||||
endfunc write_ttbr0_el2
|
||||
|
||||
func read_ttbr1_el2
|
||||
_mrrs 0xC2020 /* S3_4_C2_C0_1 */
|
||||
endfunc read_ttbr1_el2
|
||||
|
||||
func write_ttbr1_el2
|
||||
_msrr 0xC2020
|
||||
endfunc write_ttbr1_el2
|
||||
|
||||
func read_vttbr_el2
|
||||
_mrrs 0xC2100 /* S3_4_C2_C1_0 */
|
||||
endfunc read_vttbr_el2
|
||||
|
||||
func write_vttbr_el2
|
||||
_msrr 0xC2100
|
||||
endfunc write_vttbr_el2
|
||||
|
||||
func read_rcwmask_el1
|
||||
_mrrs 0x8D0C0 /* S3_0_C13_C0_6 */
|
||||
endfunc read_rcwmask_el1
|
||||
|
||||
func write_rcwmask_el1
|
||||
_msrr 0x8D0C0
|
||||
endfunc write_rcwmask_el1
|
||||
|
||||
func read_rcwsmask_el1
|
||||
_mrrs 0x8D060 /* S3_0_C13_C0_3 */
|
||||
endfunc read_rcwsmask_el1
|
||||
|
||||
func write_rcwsmask_el1
|
||||
_msrr 0x8D060
|
||||
endfunc write_rcwsmask_el1
|
|
@ -66,7 +66,7 @@ static unsigned long long calc_physical_addr_size_bits(
|
|||
*/
|
||||
static const unsigned int pa_range_bits_arr[] = {
|
||||
PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
|
||||
PARANGE_0101, PARANGE_0110
|
||||
PARANGE_0101, PARANGE_0110, PARANGE_0111
|
||||
};
|
||||
|
||||
static unsigned long long get_max_supported_pa(void)
|
||||
|
|
|
@ -109,7 +109,7 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr)
|
|||
*/
|
||||
static const unsigned int pa_range_bits_arr[] = {
|
||||
PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
|
||||
PARANGE_0101, PARANGE_0110
|
||||
PARANGE_0101, PARANGE_0110, PARANGE_0111
|
||||
};
|
||||
|
||||
unsigned long long xlat_arch_get_max_supported_pa(void)
|
||||
|
|
|
@ -412,6 +412,12 @@ ENABLE_SME_FOR_SWD ?= 0
|
|||
# if FEAT_BRBE is implemented.
|
||||
ENABLE_BRBE_FOR_NS ?= 0
|
||||
|
||||
#----
|
||||
# 9.3
|
||||
#----
|
||||
# Flag to enable access to Arm v9.3 FEAT_D128 extension
|
||||
ENABLE_FEAT_D128 ?= 0
|
||||
|
||||
#----
|
||||
#9.4
|
||||
#----
|
||||
|
|
|
@ -56,6 +56,7 @@ endif
|
|||
|
||||
ENABLE_BRBE_FOR_NS := 2
|
||||
ENABLE_TRBE_FOR_NS := 2
|
||||
ENABLE_FEAT_D128 := 2
|
||||
endif
|
||||
|
||||
ENABLE_SYS_REG_TRACE_FOR_NS := 2
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/romlib.h>
|
||||
#include <common/par.h>
|
||||
#include <lib/extensions/sysreg128.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/smccc.h>
|
||||
#include <lib/xlat_tables/xlat_tables_compat.h>
|
||||
|
@ -196,7 +198,8 @@ unsigned int plat_get_syscnt_freq2(void)
|
|||
*/
|
||||
int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
|
||||
{
|
||||
uint64_t par, pa;
|
||||
uint64_t pa;
|
||||
sysreg_t par;
|
||||
u_register_t scr_el3;
|
||||
|
||||
/* Doing Non-secure address translation requires SCR_EL3.NS set */
|
||||
|
@ -230,7 +233,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
|
|||
return -1;
|
||||
|
||||
/* Extract Physical Address from PAR */
|
||||
pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT));
|
||||
pa = get_par_el1_pa(par);
|
||||
|
||||
/* Perform NS entry point validation on the physical address */
|
||||
return arm_validate_ns_entrypoint(pa);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
# Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
@ -8,7 +8,9 @@ ifeq (${ERROR_DEPRECATED},0)
|
|||
SPD_INCLUDES := -Iinclude/bl32/payloads
|
||||
endif
|
||||
|
||||
ifeq (${ENABLE_FEAT_D128}, 0)
|
||||
SPD_SOURCES := services/spd/tlkd/tlkd_common.c \
|
||||
services/spd/tlkd/tlkd_helpers.S \
|
||||
services/spd/tlkd/tlkd_main.c \
|
||||
services/spd/tlkd/tlkd_pm.c
|
||||
endif
|
Loading…
Add table
Reference in a new issue