Merge "docs: import MISRA compliance spreadsheet" into integration
diff --git a/Makefile b/Makefile
index 87ff22e..3536763 100644
--- a/Makefile
+++ b/Makefile
@@ -1256,6 +1256,7 @@
ENABLE_FEAT_AMU \
ENABLE_FEAT_AMUv1p1 \
ENABLE_FEAT_CSV2_2 \
+ ENABLE_FEAT_CSV2_3 \
ENABLE_FEAT_DIT \
ENABLE_FEAT_ECV \
ENABLE_FEAT_FGT \
@@ -1411,6 +1412,7 @@
ENABLE_FEAT_SEL2 \
ENABLE_FEAT_VHE \
ENABLE_FEAT_CSV2_2 \
+ ENABLE_FEAT_CSV2_3 \
ENABLE_FEAT_PAN \
ENABLE_FEAT_TCR2 \
ENABLE_FEAT_S2PIE \
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 49b5360..57d6ae0 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -204,6 +204,8 @@
"S1POE", 1, 1);
check_feature(ENABLE_FEAT_MTE_PERM, read_feat_mte_perm_id_field(),
"MTE_PERM", 1, 1);
+ check_feature(ENABLE_FEAT_CSV2_3, read_feat_csv2_id_field(),
+ "CSV2_3", 3, 3);
/* v9.0 features */
check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
diff --git a/docs/about/contact.rst b/docs/about/contact.rst
index 4f482bd..bb73dfe 100644
--- a/docs/about/contact.rst
+++ b/docs/about/contact.rst
@@ -36,9 +36,8 @@
Issue Tracker
^^^^^^^^^^^^^
-Bug reports may be filed on the `issue tracker`_ on the TrustedFirmware.org
-website. Using this tracker gives everyone visibility of the known issues in
-TF-A.
+Bug reports may be filed on the `issue tracker`_ on Github. Using this tracker
+gives everyone visibility of the known issues in TF-A.
Arm Licensees
^^^^^^^^^^^^^
@@ -46,7 +45,7 @@
Arm licensees have an additional support conduit - they may contact Arm directly
via their partner managers.
-.. _`issue tracker`: https://developer.trustedfirmware.org
+.. _`issue tracker`: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
.. _`TF-A development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
.. _`TF-A-Tests development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a-tests.lists.trustedfirmware.org/
.. _`summary of all the lists`: https://lists.trustedfirmware.org/mailman3/lists/
diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst
index 07637dd..9d85bef 100644
--- a/docs/components/granule-protection-tables-design.rst
+++ b/docs/components/granule-protection-tables-design.rst
@@ -80,8 +80,8 @@
below.
In the reference implementation for FVP models, you can find an example of PAS
-region definitions in the file ``include/plat/arm/common/arm_pas_def.h``. Table
-creation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and
+region definitions in the file ``plat/arm/board/fvp/include/fvp_pas_def.h``.
+Table creation API calls can be found in ``plat/arm/common/arm_common.c`` and
runtime initialization API calls can be seen in
``plat/arm/common/arm_bl31_setup.c``.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 077f598..cc20261 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -306,6 +306,13 @@
0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
Default value is ``0``.
+- ``ENABLE_FEAT_CSV2_3``: Numeric value to enable support for ``FEAT_CSV2_3``
+ extension. This feature is supported in AArch64 state only and is an optional
+ feature available in Arm v8.0 implementations.
+ ``FEAT_CSV2_3`` implies the implementation of ``FEAT_CSV2_2``.
+ The flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
+ mechanism. Default value is ``0``.
+
- ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent
Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3.
``FEAT_DIT`` is a mandatory architectural feature and is enabled from v8.4
diff --git a/docs/process/commit-style.rst b/docs/process/commit-style.rst
index d7e937b..c287599 100644
--- a/docs/process/commit-style.rst
+++ b/docs/process/commit-style.rst
@@ -149,5 +149,5 @@
.. _Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0
.. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
.. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
-.. _issue: https://developer.trustedfirmware.org/project/board/1/
+.. _issue: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
.. _quick summary: https://www.conventionalcommits.org/en/v1.0.0/#summary
diff --git a/docs/process/security.rst b/docs/process/security.rst
index c49ca6e..1e7ac2e 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -76,7 +76,7 @@
| |TFV-11| | A Malformed SDEI SMC can cause out of bound memory read |
+-----------+------------------------------------------------------------------+
-.. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
+.. _issue tracker: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
.. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
.. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)`
diff --git a/drivers/st/bsec/bsec3.c b/drivers/st/bsec/bsec3.c
new file mode 100644
index 0000000..a803a3a
--- /dev/null
+++ b/drivers/st/bsec/bsec3.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+#include <drivers/st/bsec3_reg.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#define BSEC_IP_VERSION_1_0 U(0x10)
+#define BSEC_IP_ID_3 U(0x100033)
+
+#define MAX_NB_TRIES U(3)
+
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK GENMASK_32(4, 0)
+#define BSEC_OTP_BANK_SHIFT U(5)
+#define BSEC_TIMEOUT_VALUE U(0x800000) /* ~7sec @1.2GHz */
+
+/* Magic use to indicated valid SHADOW = 'B' 'S' 'E' 'C' */
+#define BSEC_MAGIC U(0x42534543)
+
+#define OTP_MAX_SIZE (STM32MP2_OTP_MAX_ID + U(1))
+
+struct bsec_shadow {
+ uint32_t magic;
+ uint32_t state;
+ uint32_t value[OTP_MAX_SIZE];
+ uint32_t status[OTP_MAX_SIZE];
+};
+
+static uint32_t otp_bank(uint32_t otp)
+{
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ return (otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT;
+}
+
+static uint32_t otp_bit_mask(uint32_t otp)
+{
+ return BIT(otp & BSEC_OTP_MASK);
+}
+
+/*
+ * bsec_get_status: return status register value.
+ */
+static uint32_t bsec_get_status(void)
+{
+ return mmio_read_32(BSEC_BASE + BSEC_OTPSR);
+}
+
+/*
+ * bsec_get_version: return BSEC version.
+ */
+static uint32_t bsec_get_version(void)
+{
+ return mmio_read_32(BSEC_BASE + BSEC_VERR) & BSEC_VERR_MASK;
+}
+
+/*
+ * bsec_get_id: return BSEC ID.
+ */
+static uint32_t bsec_get_id(void)
+{
+ return mmio_read_32(BSEC_BASE + BSEC_IPIDR);
+}
+
+static bool is_fuse_shadowed(uint32_t otp)
+{
+ uint32_t bank = otp_bank(otp);
+ uint32_t otp_mask = otp_bit_mask(otp);
+ uint32_t bank_value;
+
+ bank_value = mmio_read_32(BSEC_BASE + BSEC_SFSR(bank));
+
+ if ((bank_value & otp_mask) != 0U) {
+ return true;
+ }
+
+ return false;
+}
+
+static void poll_otp_status_busy(void)
+{
+ uint32_t timeout = BSEC_TIMEOUT_VALUE;
+
+ while (((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) && (timeout != 0U)) {
+ timeout--;
+ }
+
+ if ((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) {
+ ERROR("BSEC timeout\n");
+ panic();
+ }
+}
+
+static uint32_t check_read_error(uint32_t otp)
+{
+ uint32_t status = bsec_get_status();
+
+ if ((status & BSEC_OTPSR_SECF) != 0U) {
+ VERBOSE("BSEC read %u single error correction detected\n", otp);
+ }
+
+ if ((status & BSEC_OTPSR_PPLF) != 0U) {
+ VERBOSE("BSEC read %u permanent programming lock detected.\n", otp);
+ }
+
+ if ((status & BSEC_OTPSR_PPLMF) != 0U) {
+ ERROR("BSEC read %u error 0x%x\n", otp, status);
+ return BSEC_ERROR;
+ }
+
+ if ((status & (BSEC_OTPSR_DISTURBF | BSEC_OTPSR_DEDF | BSEC_OTPSR_AMEF)) != 0U) {
+ ERROR("BSEC read %u error 0x%x with invalid FVR\n", otp, status);
+ return BSEC_RETRY;
+ }
+
+ return BSEC_OK;
+}
+
+static uint32_t check_program_error(uint32_t otp)
+{
+ uint32_t status = bsec_get_status();
+
+ if ((status & BSEC_OTPSR_PROGFAIL) != 0U) {
+ ERROR("BSEC program %u error 0x%x\n", otp, status);
+ return BSEC_RETRY;
+ }
+
+ return BSEC_OK;
+}
+
+static void check_reset_error(void)
+{
+ uint32_t status = bsec_get_status();
+
+ /* check initial status reporting */
+ if ((status & BSEC_OTPSR_BUSY) != 0U) {
+ VERBOSE("BSEC reset and busy when OTPSR read\n");
+ }
+ if ((status & BSEC_OTPSR_HIDEUP) != 0U) {
+ VERBOSE("BSEC upper fuse are not accessible (HIDEUP)\n");
+ }
+ if ((status & BSEC_OTPSR_OTPSEC) != 0U) {
+ VERBOSE("BSEC reset single error correction detected\n");
+ }
+ if ((status & BSEC_OTPSR_OTPNVIR) == 0U) {
+ VERBOSE("BSEC reset first fuse word 0 is detected zero\n");
+ }
+ if ((status & BSEC_OTPSR_OTPERR) != 0U) {
+ ERROR("BSEC reset critical error 0x%x\n", status);
+ panic();
+ }
+ if ((status & BSEC_OTPSR_FUSEOK) != BSEC_OTPSR_FUSEOK) {
+ ERROR("BSEC reset critical error 0x%x\n", status);
+ panic();
+ }
+}
+
+static bool is_bsec_write_locked(void)
+{
+ return (mmio_read_32(BSEC_BASE + BSEC_LOCKR) & BSEC_LOCKR_GWLOCK_MASK) != 0U;
+}
+
+/*
+ * bsec_probe: initialize BSEC driver.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_probe(void)
+{
+ uint32_t version = bsec_get_version();
+ uint32_t id = bsec_get_id();
+
+ if ((version != BSEC_IP_VERSION_1_0) || (id != BSEC_IP_ID_3)) {
+ ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
+ panic();
+ }
+
+ check_reset_error();
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+static uint32_t bsec_shadow_register(uint32_t otp)
+{
+ uint32_t result;
+ uint32_t i;
+ bool value;
+
+ result = bsec_read_sr_lock(otp, &value);
+ if (result != BSEC_OK) {
+ WARN("BSEC: %u Sticky-read bit read Error %u\n", otp, result);
+ } else if (value) {
+ VERBOSE("BSEC: OTP %u is locked and will not be refreshed\n", otp);
+ }
+
+ for (i = 0U; i < MAX_NB_TRIES; i++) {
+ mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp);
+
+ poll_otp_status_busy();
+
+ result = check_read_error(otp);
+ if (result != BSEC_RETRY) {
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * bsec_write_otp: write a value in shadow OTP.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
+{
+ bool state;
+ uint32_t result;
+
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ if (!is_fuse_shadowed(otp)) {
+ return BSEC_ERROR;
+ }
+
+ if (is_bsec_write_locked()) {
+ return BSEC_WRITE_LOCKED;
+ }
+
+ result = bsec_read_sw_lock(otp, &state);
+ if (result != BSEC_OK) {
+ WARN("Shadow register is SW locked\n");
+ return result;
+ }
+
+ mmio_write_32(BSEC_BASE + BSEC_FVR(otp), val);
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_program_otp: program a bit in SAFMEM after the prog.
+ * The OTP data is not refreshed.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
+{
+ uint32_t result;
+ uint32_t i;
+ bool value;
+
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ if (is_bsec_write_locked() == true) {
+ return BSEC_WRITE_LOCKED;
+ }
+
+ result = bsec_read_sp_lock(otp, &value);
+ if (result != BSEC_OK) {
+ WARN("BSEC: %u Sticky-prog bit read Error %u\n", otp, result);
+ } else if (value) {
+ WARN("BSEC: OTP locked, prog will be ignored\n");
+ return BSEC_WRITE_LOCKED;
+ }
+
+ mmio_write_32(BSEC_BASE + BSEC_WDR, val);
+
+ for (i = 0U; i < MAX_NB_TRIES; i++) {
+ mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp | BSEC_OTPCR_PROG);
+
+ poll_otp_status_busy();
+
+ result = check_program_error(otp);
+ if (result != BSEC_RETRY) {
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * bsec_read_debug_conf: read debug configuration.
+ */
+uint32_t bsec_read_debug_conf(void)
+{
+ return mmio_read_32(BSEC_BASE + BSEC_DENR);
+}
+
+static uint32_t bsec_lock_register_set(uint32_t offset, uint32_t mask)
+{
+ uint32_t value = mmio_read_32(BSEC_BASE + offset);
+
+ /* The lock is already set */
+ if ((value & mask) != 0U) {
+ return BSEC_OK;
+ }
+
+ if (is_bsec_write_locked()) {
+ return BSEC_WRITE_LOCKED;
+ }
+
+ value |= mask;
+
+ mmio_write_32(BSEC_BASE + offset, value);
+
+ return BSEC_OK;
+}
+
+static bool bsec_lock_register_get(uint32_t offset, uint32_t mask)
+{
+ uint32_t value = mmio_read_32(BSEC_BASE + offset);
+
+ return (value & mask) != 0U;
+}
+
+/*
+ * bsec_set_sr_lock: set shadow-read lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sr_lock(uint32_t otp)
+{
+ uint32_t bank = otp_bank(otp);
+ uint32_t otp_mask = otp_bit_mask(otp);
+
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ return bsec_lock_register_set(BSEC_SRLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sr_lock: read shadow-read lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
+{
+ uint32_t bank = otp_bank(otp);
+ uint32_t otp_mask = otp_bit_mask(otp);
+
+ assert(value != NULL);
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ *value = bsec_lock_register_get(BSEC_SRLOCK(bank), otp_mask);
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_set_sw_lock: set shadow-write lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sw_lock(uint32_t otp)
+{
+ uint32_t bank = otp_bank(otp);
+ uint32_t otp_mask = otp_bit_mask(otp);
+
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ return bsec_lock_register_set(BSEC_SWLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sw_lock: read shadow-write lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sw_lock(uint32_t otp, bool *value)
+{
+ uint32_t bank = otp_bank(otp);
+ uint32_t otp_mask = otp_bit_mask(otp);
+
+ assert(value != NULL);
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ *value = bsec_lock_register_get(BSEC_SWLOCK(bank), otp_mask);
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_set_sp_lock: set shadow-program lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sp_lock(uint32_t otp)
+{
+ uint32_t bank = otp_bank(otp);
+ uint32_t otp_mask = otp_bit_mask(otp);
+
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ return bsec_lock_register_set(BSEC_SPLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sp_lock: read shadow-program lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sp_lock(uint32_t otp, bool *value)
+{
+ uint32_t bank = otp_bank(otp);
+ uint32_t otp_mask = otp_bit_mask(otp);
+
+ assert(value != NULL);
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ *value = bsec_lock_register_get(BSEC_SPLOCK(bank), otp_mask);
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_get_secure_state: read state in BSEC status register.
+ * return: secure state
+ */
+uint32_t bsec_get_secure_state(void)
+{
+ uint32_t state = BSEC_STATE_INVALID;
+ uint32_t status = bsec_get_status();
+ uint32_t bsec_sr = mmio_read_32(BSEC_BASE + BSEC_SR);
+
+ if ((status & BSEC_OTPSR_FUSEOK) == BSEC_OTPSR_FUSEOK) {
+ /* NVSTATE is only valid if FUSEOK */
+ uint32_t nvstates = (bsec_sr & BSEC_SR_NVSTATE_MASK) >> BSEC_SR_NVSTATE_SHIFT;
+
+ if (nvstates == BSEC_SR_NVSTATE_OPEN) {
+ state = BSEC_STATE_SEC_OPEN;
+ } else if (nvstates == BSEC_SR_NVSTATE_CLOSED) {
+ state = BSEC_STATE_SEC_CLOSED;
+ } else {
+ VERBOSE("%s nvstates = %u\n", __func__, nvstates);
+ }
+ }
+
+ return state;
+}
+
+/*
+ * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp)
+{
+ assert(val != NULL);
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ *val = 0U;
+
+ if (is_bsec_write_locked()) {
+ return BSEC_WRITE_LOCKED;
+ }
+
+ if (!is_fuse_shadowed(otp)) {
+ uint32_t result = bsec_shadow_register(otp);
+
+ if (result != BSEC_OK) {
+ ERROR("BSEC: %u Shadowing Error %u\n", otp, result);
+ return result;
+ }
+ }
+
+ *val = mmio_read_32(BSEC_BASE + BSEC_FVR(otp));
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_read_otp: read an OTP data value.
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
+{
+ assert(val != NULL);
+ if (otp > STM32MP2_OTP_MAX_ID) {
+ panic();
+ }
+
+ return bsec_shadow_read_otp(val, otp);
+}
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index acc1751..a2063f1 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -137,6 +137,7 @@
static inline bool is_feat_ecv_supported(void) { return false; }
static inline bool is_feat_ecv_v2_supported(void) { return false; }
static inline bool is_feat_csv2_2_supported(void) { return false; }
+static inline bool is_feat_csv2_3_supported(void) { return false; }
static inline bool is_feat_ras_supported(void) { return false; }
/* The following features are supported in AArch64 only. */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index e9d22b6..b88d6c6 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -197,6 +197,7 @@
#define ID_AA64PFR0_CSV2_MASK ULL(0xf)
#define ID_AA64PFR0_CSV2_LENGTH U(4)
#define ID_AA64PFR0_CSV2_2_SUPPORTED ULL(0x2)
+#define ID_AA64PFR0_CSV2_3_SUPPORTED ULL(0x3)
#define ID_AA64PFR0_FEAT_RME_SHIFT U(52)
#define ID_AA64PFR0_FEAT_RME_MASK ULL(0xf)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index deea6d4..c053c4d 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -187,10 +187,28 @@
return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT);
}
-/* FEAT_CSV2_2: Cache Speculation Variant 2 */
-CREATE_FEATURE_FUNCS(feat_csv2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT, 0)
+/*
+ * FEAT_CSV2: Cache Speculation Variant 2. This checks bit fields[56-59]
+ * of id_aa64pfr0_el1 register and can be used to check for below features:
+ * FEAT_CSV2_2: Cache Speculation Variant CSV2_2.
+ * FEAT_CSV2_3: Cache Speculation Variant CSV2_3.
+ * 0b0000 - Feature FEAT_CSV2 is not implemented.
+ * 0b0001 - Feature FEAT_CSV2 is implemented, but FEAT_CSV2_2 and FEAT_CSV2_3
+ * are not implemented.
+ * 0b0010 - Feature FEAT_CSV2_2 is implemented but FEAT_CSV2_3 is not
+ * implemented.
+ * 0b0011 - Feature FEAT_CSV2_3 is implemented.
+ */
+static inline unsigned int read_feat_csv2_id_field(void)
+{
+ return (unsigned int)(read_id_aa64pfr0_el1() >>
+ ID_AA64PFR0_CSV2_SHIFT) & ID_AA64PFR0_CSV2_MASK;
+}
+
CREATE_FEATURE_FUNCS_VER(feat_csv2_2, read_feat_csv2_id_field,
ID_AA64PFR0_CSV2_2_SUPPORTED, ENABLE_FEAT_CSV2_2)
+CREATE_FEATURE_FUNCS_VER(feat_csv2_3, read_feat_csv2_id_field,
+ ID_AA64PFR0_CSV2_3_SUPPORTED, ENABLE_FEAT_CSV2_3)
/* FEAT_SPE: Statistical Profiling Extension */
CREATE_FEATURE_FUNCS(feat_spe, id_aa64dfr0_el1, ID_AA64DFR0_PMS_SHIFT,
diff --git a/include/drivers/st/bsec3_reg.h b/include/drivers/st/bsec3_reg.h
new file mode 100644
index 0000000..177e30b
--- /dev/null
+++ b/include/drivers/st/bsec3_reg.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC3_REG_H
+#define BSEC3_REG_H
+
+#include <lib/utils_def.h>
+
+/* BSEC REGISTER OFFSET (base relative) */
+#define BSEC_FVR(x) (U(0x000) + 4U * (x))
+#define BSEC_SPLOCK(x) (U(0x800) + 4U * (x))
+#define BSEC_SWLOCK(x) (U(0x840) + 4U * (x))
+#define BSEC_SRLOCK(x) (U(0x880) + 4U * (x))
+#define BSEC_OTPVLDR(x) (U(0x8C0) + 4U * (x))
+#define BSEC_SFSR(x) (U(0x940) + 4U * (x))
+#define BSEC_OTPCR U(0xC04)
+#define BSEC_WDR U(0xC08)
+#define BSEC_SCRATCHR0 U(0xE00)
+#define BSEC_SCRATCHR1 U(0xE04)
+#define BSEC_SCRATCHR2 U(0xE08)
+#define BSEC_SCRATCHR3 U(0xE0C)
+#define BSEC_LOCKR U(0xE10)
+#define BSEC_JTAGINR U(0xE14)
+#define BSEC_JTAGOUTR U(0xE18)
+#define BSEC_DENR U(0xE20)
+#define BSEC_UNMAPR U(0xE24)
+#define BSEC_SR U(0xE40)
+#define BSEC_OTPSR U(0xE44)
+#define BSEC_WRCR U(0xF00)
+#define BSEC_HWCFGR U(0xFF0)
+#define BSEC_VERR U(0xFF4)
+#define BSEC_IPIDR U(0xFF8)
+#define BSEC_SIDR U(0xFFC)
+
+/* BSEC_OTPCR register fields */
+#define BSEC_OTPCR_ADDR_MASK GENMASK_32(8, 0)
+#define BSEC_OTPCR_ADDR_SHIFT U(0)
+#define BSEC_OTPCR_PROG BIT_32(13)
+#define BSEC_OTPCR_PPLOCK BIT_32(14)
+#define BSEC_OTPCR_LASTCID_MASK GENMASK_32(21, 19)
+#define BSEC_OTPCR_LASTCID_SHIFT U(19)
+
+/* BSEC_LOCKR register fields */
+#define BSEC_LOCKR_GWLOCK_MASK BIT_32(0)
+#define BSEC_LOCKR_GWLOCK_SHIFT U(0)
+#define BSEC_LOCKR_DENLOCK_MASK BIT_32(1)
+#define BSEC_LOCKR_DENLOCK_SHIFT U(1)
+#define BSEC_LOCKR_HKLOCK_MASK BIT_32(2)
+#define BSEC_LOCKR_HKLOCK_SHIFT U(2)
+
+/* BSEC_DENR register fields */
+#define BSEC_DENR_LPDBGEN BIT_32(0)
+#define BSEC_DENR_DBGENA BIT_32(1)
+#define BSEC_DENR_NIDENA BIT_32(2)
+#define BSEC_DENR_DEVICEEN BIT_32(3)
+#define BSEC_DENR_HDPEN BIT_32(4)
+#define BSEC_DENR_SPIDENA BIT_32(5)
+#define BSEC_DENR_SPNIDENA BIT_32(6)
+#define BSEC_DENR_DBGSWEN BIT_32(7)
+#define BSEC_DENR_DBGENM BIT_32(8)
+#define BSEC_DENR_NIDENM BIT_32(9)
+#define BSEC_DENR_SPIDENM BIT_32(10)
+#define BSEC_DENR_SPNIDENM BIT_32(11)
+#define BSEC_DENR_CFGSDIS BIT_32(12)
+#define BSEC_DENR_CP15SDIS_MASK GENMASK_32(14, 13)
+#define BSEC_DENR_CP15SDIS_SHIFT U(13)
+#define BSEC_DENR_LPDBGDIS BIT_32(15)
+#define BSEC_DENR_ALL_MSK GENMASK_32(15, 0)
+
+/* BSEC_SR register fields */
+#define BSEC_SR_BUSY BIT_32(0)
+#define BSEC_SR_HVALID BIT_32(1)
+#define BSEC_SR_RNGERR BIT_32(2)
+#define BSEC_SR_HKWW_MASK GENMASK_32(15, 8)
+#define BSEC_SR_HKWW_SHIFT U(8)
+#define BSEC_SR_NVSTATE_MASK GENMASK_32(31, 26)
+#define BSEC_SR_NVSTATE_SHIFT U(26)
+#define BSEC_SR_NVSTATE_OPEN U(0x16)
+#define BSEC_SR_NVSTATE_CLOSED U(0x0D)
+#define BSEC_SR_NVSTATE_OTP_LOCKED U(0x23)
+
+/* BSEC_OTPSR register fields */
+#define BSEC_OTPSR_BUSY BIT_32(0)
+#define BSEC_OTPSR_FUSEOK BIT_32(1)
+#define BSEC_OTPSR_HIDEUP BIT_32(2)
+#define BSEC_OTPSR_OTPNVIR BIT_32(4)
+#define BSEC_OTPSR_OTPERR BIT_32(5)
+#define BSEC_OTPSR_OTPSEC BIT_32(6)
+#define BSEC_OTPSR_PROGFAIL BIT_32(16)
+#define BSEC_OTPSR_DISTURBF BIT_32(17)
+#define BSEC_OTPSR_DEDF BIT_32(18)
+#define BSEC_OTPSR_SECF BIT_32(19)
+#define BSEC_OTPSR_PPLF BIT_32(20)
+#define BSEC_OTPSR_PPLMF BIT_32(21)
+#define BSEC_OTPSR_AMEF BIT_32(22)
+
+/* BSEC_VERR register fields */
+#define BSEC_VERR_MASK GENMASK_32(7, 0)
+
+#endif /* BSEC3_REG_H */
diff --git a/include/lib/cpus/aarch64/cortex_a35.h b/include/lib/cpus/aarch64/cortex_a35.h
index cef2960..c82b4eb 100644
--- a/include/lib/cpus/aarch64/cortex_a35.h
+++ b/include/lib/cpus/aarch64/cortex_a35.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,9 @@
/* Cortex-A35 Main ID register for revision 0 */
#define CORTEX_A35_MIDR U(0x410FD040)
+/* L2 Extended Control Register */
+#define CORTEX_A35_L2ECTLR_EL1 S3_1_C11_C0_3
+
/*******************************************************************************
* CPU Extended Control register specific definitions.
* CPUECTLR_EL1 is an implementation-specific register.
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 54b184d..c3a88e7 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -150,10 +150,10 @@
#endif /* (SPD_tspd || SPD_opteed || SPD_spmd) && MEASURED_BOOT */
#if ENABLE_RME
-#define ARM_L1_GPT_ADDR_BASE (ARM_DRAM1_BASE + \
+#define ARM_L1_GPT_BASE (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - \
ARM_L1_GPT_SIZE)
-#define ARM_L1_GPT_END (ARM_L1_GPT_ADDR_BASE + \
+#define ARM_L1_GPT_END (ARM_L1_GPT_BASE + \
ARM_L1_GPT_SIZE - 1U)
#define ARM_REALM_BASE (ARM_EL3_RMM_SHARED_BASE - \
@@ -343,7 +343,7 @@
#define ARM_MAP_GPT_L1_DRAM MAP_REGION_FLAT( \
- ARM_L1_GPT_ADDR_BASE, \
+ ARM_L1_GPT_BASE, \
ARM_L1_GPT_SIZE, \
MT_MEMORY | MT_RW | EL3_PAS)
@@ -422,7 +422,7 @@
* Map L0_GPT with read and write permissions
*/
#if ENABLE_RME
-#define ARM_MAP_L0_GPT_REGION MAP_REGION_FLAT(ARM_L0_GPT_ADDR_BASE, \
+#define ARM_MAP_L0_GPT_REGION MAP_REGION_FLAT(ARM_L0_GPT_BASE, \
ARM_L0_GPT_SIZE, \
MT_MEMORY | MT_RW | MT_ROOT)
#endif
@@ -533,8 +533,8 @@
* configuration memory, 4KB aligned.
*/
#define ARM_L0_GPT_SIZE (PAGE_SIZE)
-#define ARM_L0_GPT_ADDR_BASE (ARM_FW_CONFIGS_LIMIT)
-#define ARM_L0_GPT_LIMIT (ARM_L0_GPT_ADDR_BASE + ARM_L0_GPT_SIZE)
+#define ARM_L0_GPT_BASE (ARM_FW_CONFIGS_LIMIT)
+#define ARM_L0_GPT_LIMIT (ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE)
#else
#define ARM_L0_GPT_SIZE U(0)
#endif
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 0fb06a6..4c425a7 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,7 @@
#include <lib/bakery_lock.h>
#include <lib/cassert.h>
#include <lib/el3_runtime/cpu_data.h>
+#include <lib/gpt_rme/gpt_rme.h>
#include <lib/spinlock.h>
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
@@ -31,6 +32,17 @@
unsigned int nsaid_permissions;
} arm_tzc_regions_info_t;
+typedef struct arm_gpt_info {
+ pas_region_t *pas_region_base;
+ unsigned int pas_region_count;
+ uintptr_t l0_base;
+ uintptr_t l1_base;
+ size_t l0_size;
+ size_t l1_size;
+ gpccr_pps_e pps;
+ gpccr_pgs_e pgs;
+} arm_gpt_info_t;
+
/*******************************************************************************
* Default mapping definition of the TrustZone Controller for ARM standard
* platforms.
@@ -362,6 +374,9 @@
unsigned int plat_arm_calc_core_pos(u_register_t mpidr);
const mmap_region_t *plat_arm_get_mmap(void);
+const arm_gpt_info_t *plat_arm_get_gpt_info(void);
+void arm_gpt_setup(void);
+
/* Allow platform to override psci_pm_ops during runtime */
const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops);
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index da53194..00c6008 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -168,6 +168,7 @@
scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
+ /* CSV2 version 2 and above */
if (is_feat_csv2_2_supported()) {
/* Enable access to the SCXTNUM_ELx registers. */
scr_el3 |= SCR_EnSCXT_BIT;
@@ -236,6 +237,7 @@
scr_el3 |= SCR_TERR_BIT;
#endif
+ /* CSV2 version 2 and above */
if (is_feat_csv2_2_supported()) {
/* Enable access to the SCXTNUM_ELx registers. */
scr_el3 |= SCR_EnSCXT_BIT;
@@ -1293,6 +1295,7 @@
write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
}
+ /* CSV2 version 2 and above */
if (is_feat_csv2_2_supported()) {
write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2, read_scxtnum_el2());
}
@@ -1370,6 +1373,7 @@
write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
}
+ /* CSV2 version 2 and above */
if (is_feat_csv2_2_supported()) {
write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2));
}
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 9ac9332..bb4e224 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -169,6 +169,10 @@
# Flag to enable CSV2_2 extension.
ENABLE_FEAT_CSV2_2 ?= 0
+# Flag to enable CSV2_3 extension. FEAT_CSV2_3 enables access to the
+# SCXTNUM_ELx register.
+ENABLE_FEAT_CSV2_3 ?= 0
+
# By default, disable access of trace system registers from NS lower
# ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
# system register trace is implemented. This feature is available if
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index ebd5266..97d000e 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/arm/sp804_delay_timer.h>
+#include <fvp_pas_def.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/transfer_list.h>
@@ -21,6 +22,32 @@
static struct transfer_list_header *ns_tl __unused;
+#if ENABLE_RME
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+ ARM_PAS_KERNEL,
+ ARM_PAS_SECURE,
+ ARM_PAS_REALM,
+ ARM_PAS_EL3_DRAM,
+ ARM_PAS_GPTS,
+ ARM_PAS_KERNEL_1
+};
+
+static const arm_gpt_info_t arm_gpt_info = {
+ .pas_region_base = pas_regions,
+ .pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
+ .l0_base = (uintptr_t)ARM_L0_GPT_BASE,
+ .l1_base = (uintptr_t)ARM_L1_GPT_BASE,
+ .l0_size = (size_t)ARM_L0_GPT_SIZE,
+ .l1_size = (size_t)ARM_L1_GPT_SIZE,
+ .pps = GPCCR_PPS_64GB,
+ .pgs = GPCCR_PGS_4K
+};
+#endif
+
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
{
arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
@@ -41,6 +68,13 @@
fvp_timer_init();
}
+#if ENABLE_RME
+const arm_gpt_info_t *plat_arm_get_gpt_info(void)
+{
+ return &arm_gpt_info;
+}
+#endif /* ENABLE_RME */
+
/*******************************************************************************
* This function returns the list of executable images
******************************************************************************/
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index c40a3ce..beae242 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,7 +24,6 @@
#endif
#include <plat/arm/common/arm_config.h>
-#include <plat/arm/common/arm_pas_def.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
diff --git a/include/plat/arm/common/arm_pas_def.h b/plat/arm/board/fvp/include/fvp_pas_def.h
similarity index 94%
rename from include/plat/arm/common/arm_pas_def.h
rename to plat/arm/board/fvp/include/fvp_pas_def.h
index fba8d2c..4684387 100644
--- a/include/plat/arm/common/arm_pas_def.h
+++ b/plat/arm/board/fvp/include/fvp_pas_def.h
@@ -1,13 +1,13 @@
/*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef ARM_PAS_DEF_H
-#define ARM_PAS_DEF_H
+#ifndef FVP_PAS_DEF_H
+#define FVP_PAS_DEF_H
#include <lib/gpt_rme/gpt_rme.h>
-#include <plat/arm/common/arm_def.h>
+#include <platform_def.h>
/*****************************************************************************
* PAS regions used to initialize the Granule Protection Table (GPT)
@@ -107,11 +107,11 @@
ARM_EL3_TZC_DRAM1_SIZE, \
GPT_GPI_ROOT)
-#define ARM_PAS_GPTS GPT_MAP_REGION_GRANULE(ARM_L1_GPT_ADDR_BASE, \
+#define ARM_PAS_GPTS GPT_MAP_REGION_GRANULE(ARM_L1_GPT_BASE, \
ARM_L1_GPT_SIZE, \
GPT_GPI_ROOT)
/* GPT Configuration options */
#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS
-#endif /* ARM_PAS_DEF_H */
+#endif /* FVP_PAS_DEF_H */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index df26dd7..eef06d4 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -75,6 +75,7 @@
endif
ENABLE_SYS_REG_TRACE_FOR_NS := 2
ENABLE_FEAT_CSV2_2 := 2
+ENABLE_FEAT_CSV2_3 := 2
ENABLE_FEAT_DIT := 2
ENABLE_FEAT_PAN := 2
ENABLE_FEAT_MTE_PERM := 2
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 3e8109e..30d0647 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,9 +23,6 @@
#include <lib/optee_utils.h>
#endif
#include <lib/utils.h>
-#if ENABLE_RME
-#include <plat/arm/common/arm_pas_def.h>
-#endif
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -134,48 +131,6 @@
arm_bl2_platform_setup();
}
-#if ENABLE_RME
-static void arm_bl2_plat_gpt_setup(void)
-{
- /*
- * The GPT library might modify the gpt regions structure to optimize
- * the layout, so the array cannot be constant.
- */
- pas_region_t pas_regions[] = {
- ARM_PAS_KERNEL,
- ARM_PAS_SECURE,
- ARM_PAS_REALM,
- ARM_PAS_EL3_DRAM,
- ARM_PAS_GPTS,
- ARM_PAS_KERNEL_1
- };
-
- /* Initialize entire protected space to GPT_GPI_ANY. */
- if (gpt_init_l0_tables(GPCCR_PPS_64GB, ARM_L0_GPT_ADDR_BASE,
- ARM_L0_GPT_SIZE) < 0) {
- ERROR("gpt_init_l0_tables() failed!\n");
- panic();
- }
-
- /* Carve out defined PAS ranges. */
- if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
- ARM_L1_GPT_ADDR_BASE,
- ARM_L1_GPT_SIZE,
- pas_regions,
- (unsigned int)(sizeof(pas_regions) /
- sizeof(pas_region_t))) < 0) {
- ERROR("gpt_init_pas_l1_tables() failed!\n");
- panic();
- }
-
- INFO("Enabling Granule Protection Checks\n");
- if (gpt_enable() < 0) {
- ERROR("gpt_enable() failed!\n");
- panic();
- }
-}
-#endif /* ENABLE_RME */
-
/*******************************************************************************
* Perform the very early platform specific architectural setup here.
* When RME is enabled the secure environment is initialised before
@@ -216,7 +171,7 @@
enable_mmu_el3(0);
/* Initialise and enable granule protection after MMU. */
- arm_bl2_plat_gpt_setup();
+ arm_gpt_setup();
#else
enable_mmu_el1(0);
#endif
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index fc68114..21cc39c 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -241,3 +241,43 @@
{
return plat_arm_mmap;
}
+
+#if ENABLE_RME
+void arm_gpt_setup(void)
+{
+ /*
+ * It is to be noted that any Arm platform that reuses arm_gpt_setup
+ * must implement plat_arm_get_gpt_info within its platform code
+ */
+ const arm_gpt_info_t *arm_gpt_info =
+ plat_arm_get_gpt_info();
+
+ if (arm_gpt_info == NULL) {
+ ERROR("arm_gpt_info not initialized!!\n");
+ panic();
+ }
+
+ /* Initialize entire protected space to GPT_GPI_ANY. */
+ if (gpt_init_l0_tables(arm_gpt_info->pps, arm_gpt_info->l0_base,
+ arm_gpt_info->l0_size) < 0) {
+ ERROR("gpt_init_l0_tables() failed!\n");
+ panic();
+ }
+
+ /* Carve out defined PAS ranges. */
+ if (gpt_init_pas_l1_tables(arm_gpt_info->pgs,
+ arm_gpt_info->l1_base,
+ arm_gpt_info->l1_size,
+ arm_gpt_info->pas_region_base,
+ arm_gpt_info->pas_region_count) < 0) {
+ ERROR("gpt_init_pas_l1_tables() failed!\n");
+ panic();
+ }
+
+ INFO("Enabling Granule Protection Checks\n");
+ if (gpt_enable() < 0) {
+ ERROR("gpt_enable() failed!\n");
+ panic();
+ }
+}
+#endif /* ENABLE_RME */
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index ec8631a..f830b64 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -17,6 +17,15 @@
#include <lib/mmio.h>
#include <sci/sci.h>
+#if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+/*
+ * Defined in
+ * table 11. ROM event log buffer address location
+ * AN12853 "i.MX ROMs Log Events"
+ */
+#define ROM_LOG_BUFFER_ADDR 0x9E0
+#endif
+
#if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
#ifdef PLAT_imx8qm
@@ -177,6 +186,76 @@
}
#endif /* defined(PLAT_imx8mm) || defined(PLAT_imx8mq) */
+#if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+static bool is_secondary_boot(void)
+{
+ uint32_t *rom_log_addr = (uint32_t *)ROM_LOG_BUFFER_ADDR;
+ bool is_secondary = false;
+ uint32_t *rom_log;
+ uint8_t event_id;
+
+ /* If the ROM event log pointer is not valid. */
+ if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xB00000 ||
+ *rom_log_addr & 0x3) {
+ return false;
+ }
+
+ /* Parse the ROM event ID version 2 log */
+ rom_log = (uint32_t *)(uintptr_t)(*rom_log_addr);
+ for (size_t i = 0; i < 128; i++) {
+ event_id = rom_log[i] >> 24;
+ switch (event_id) {
+ case 0x00: /* End of list */
+ return is_secondary;
+ /* Log entries with 1 parameter, skip 1 */
+ case 0x80: /* Perform the device initialization */
+ case 0x81: /* The boot device initialization completes */
+ case 0x82: /* Execute boot device driver pre-config */
+ case 0x8F: /* The boot device initialization fails */
+ case 0x90: /* Start to read data from boot device */
+ case 0x91: /* Reading data from boot device completes */
+ case 0x9F: /* Reading data from boot device fails */
+ i += 1;
+ continue;
+ /* Log entries with 2 parameters, skip 2 */
+ case 0xA0: /* Image authentication result */
+ case 0xC0: /* Jump to the boot image soon */
+ i += 2;
+ continue;
+ /* Booted the primary boot image */
+ case 0x50:
+ is_secondary = false;
+ continue;
+ /* Booted the secondary boot image */
+ case 0x51:
+ is_secondary = true;
+ continue;
+ }
+ }
+
+ return is_secondary;
+}
+
+int imx_src_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ void *handle)
+{
+ switch (x1) {
+ case IMX_SIP_SRC_SET_SECONDARY_BOOT:
+ /* we do support that on these SoCs */
+ break;
+ case IMX_SIP_SRC_IS_SECONDARY_BOOT:
+ return is_secondary_boot();
+ default:
+ return SMC_UNK;
+ };
+
+ return 0;
+}
+#endif /* defined(PLAT_imx8mn) || defined(PLAT_imx8mp) */
+
static uint64_t imx_get_commit_hash(u_register_t x2,
u_register_t x3,
u_register_t x4)
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 6d6633c..69d4f05 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -60,7 +60,8 @@
case IMX_SIP_MISC_SET_TEMP:
SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
#endif
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) || defined(PLAT_imx8mn) || \
+ defined(PLAT_imx8mp)
case IMX_SIP_SRC:
SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
break;
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 0e91c71..35a9f47 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -68,7 +68,9 @@
u_register_t x2, u_register_t x3);
#endif
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) || defined(PLAT_imx8mn) || \
+ defined(PLAT_imx8mp)
+
int imx_src_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3, void *handle);
#endif
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 321b8c5..fd86020 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -367,7 +367,9 @@
print_reset_reason();
#if STM32MP15
- update_monotonic_counter();
+ if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
+ update_monotonic_counter();
+ }
#endif
stm32mp1_syscfg_enable_io_compensation_finish();
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 5f05f63..a7cce62 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -7,8 +7,10 @@
#include <cdefs.h>
#include <stdint.h>
+#include <common/debug.h>
#include <plat/common/platform.h>
+#include <platform_def.h>
#include <stm32mp_common.h>
void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
@@ -25,4 +27,8 @@
void bl2_el3_plat_arch_setup(void)
{
+ if (stm32_otp_probe() != 0U) {
+ ERROR("OTP probe failed\n");
+ panic();
+ }
}
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index 6ea4638..0519b16 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -46,6 +46,8 @@
PLAT_BL_COMMON_SOURCES += drivers/st/uart/${ARCH}/stm32_console.S
PLAT_BL_COMMON_SOURCES += plat/st/stm32mp2/${ARCH}/stm32mp2_helper.S
+PLAT_BL_COMMON_SOURCES += drivers/st/bsec/bsec3.c
+
BL2_SOURCES += plat/st/stm32mp2/plat_bl2_mem_params_desc.c
BL2_SOURCES += plat/st/stm32mp2/bl2_plat_setup.c
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index ee105de..56c62e1 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -158,6 +158,96 @@
#define STM32MP_SDMMC3_BASE U(0x48240000)
/*******************************************************************************
+ * STM32MP2 BSEC / OTP
+ ******************************************************************************/
+/*
+ * 367 available OTPs, the other are masked
+ * - ECIES key: 368 to 375 (only readable by bootrom)
+ * - HWKEY: 376 to 383 (never reloadable or readable)
+ */
+#define STM32MP2_OTP_MAX_ID U(0x16F)
+#define STM32MP2_MID_OTP_START U(0x80)
+#define STM32MP2_UPPER_OTP_START U(0x100)
+
+/* OTP labels */
+#define PART_NUMBER_OTP "part-number-otp"
+#define PACKAGE_OTP "package-otp"
+#define HCONF1_OTP "otp124"
+#define NAND_OTP "otp16"
+#define NAND2_OTP "otp20"
+#define BOARD_ID_OTP "board-id"
+#define UID_OTP "uid-otp"
+#define LIFECYCLE2_OTP "otp18"
+#define PKH_OTP "otp144"
+#define ENCKEY_OTP "otp260"
+
+/* OTP mask */
+/* PACKAGE */
+#define PACKAGE_OTP_PKG_MASK GENMASK_32(2, 0)
+#define PACKAGE_OTP_PKG_SHIFT U(0)
+
+/* IWDG OTP */
+#define HCONF1_OTP_IWDG_HW_POS U(0)
+#define HCONF1_OTP_IWDG_FZ_STOP_POS U(1)
+#define HCONF1_OTP_IWDG_FZ_STANDBY_POS U(2)
+
+/* NAND OTP */
+/* NAND parameter storage flag */
+#define NAND_PARAM_STORED_IN_OTP BIT_32(31)
+
+/* NAND page size in bytes */
+#define NAND_PAGE_SIZE_MASK GENMASK_32(30, 29)
+#define NAND_PAGE_SIZE_SHIFT U(29)
+#define NAND_PAGE_SIZE_2K U(0)
+#define NAND_PAGE_SIZE_4K U(1)
+#define NAND_PAGE_SIZE_8K U(2)
+
+/* NAND block size in pages */
+#define NAND_BLOCK_SIZE_MASK GENMASK_32(28, 27)
+#define NAND_BLOCK_SIZE_SHIFT U(27)
+#define NAND_BLOCK_SIZE_64_PAGES U(0)
+#define NAND_BLOCK_SIZE_128_PAGES U(1)
+#define NAND_BLOCK_SIZE_256_PAGES U(2)
+
+/* NAND number of block (in unit of 256 blocks) */
+#define NAND_BLOCK_NB_MASK GENMASK_32(26, 19)
+#define NAND_BLOCK_NB_SHIFT U(19)
+#define NAND_BLOCK_NB_UNIT U(256)
+
+/* NAND bus width in bits */
+#define NAND_WIDTH_MASK BIT_32(18)
+#define NAND_WIDTH_SHIFT U(18)
+
+/* NAND number of ECC bits per 512 bytes */
+#define NAND_ECC_BIT_NB_MASK GENMASK_32(17, 15)
+#define NAND_ECC_BIT_NB_SHIFT U(15)
+#define NAND_ECC_BIT_NB_UNSET U(0)
+#define NAND_ECC_BIT_NB_1_BITS U(1)
+#define NAND_ECC_BIT_NB_4_BITS U(2)
+#define NAND_ECC_BIT_NB_8_BITS U(3)
+#define NAND_ECC_ON_DIE U(4)
+
+/* NAND number of planes */
+#define NAND_PLANE_BIT_NB_MASK BIT_32(14)
+
+/* NAND2 OTP */
+#define NAND2_PAGE_SIZE_SHIFT U(16)
+
+/* NAND2 config distribution */
+#define NAND2_CONFIG_DISTRIB BIT_32(0)
+#define NAND2_PNAND_NAND2_SNAND_NAND1 U(0)
+#define NAND2_PNAND_NAND1_SNAND_NAND2 U(1)
+
+/* MONOTONIC OTP */
+#define MAX_MONOTONIC_VALUE U(32)
+
+/* UID OTP */
+#define UID_WORD_NB U(3)
+
+/* Lifecycle OTP */
+#define SECURE_BOOT_CLOSED_SECURE GENMASK_32(3, 0)
+
+/*******************************************************************************
* STM32MP2 TAMP
******************************************************************************/
#define PLAT_MAX_TAMP_INT U(5)