Merge changes from topics "rcar-tools-fix", "toolchain-cleanup" into integration
* changes:
build: remove the `NM` variable
build: prefer `gcc-ar` over `ar`
build: add `--no-warn-rwx-segments` when linking with GCC
build: always use the C compiler to assemble
build: always use the C compiler to preprocess
fix(rcar): fix implicit rule invocations in tools
diff --git a/.husky/pre-commit.copyright b/.husky/pre-commit.copyright
index a4dfee8..5f838a6 100755
--- a/.husky/pre-commit.copyright
+++ b/.husky/pre-commit.copyright
@@ -17,10 +17,24 @@
exit_code=0
+PLATPROV=
+ORG=`echo "$GIT_AUTHOR_EMAIL" | awk -F '[@]' '{ print $2;}'`
+
+case $ORG in
+ amd.com)
+ PLATPROV="Advanced Micro Devices, Inc. All rights reserved."
+ ;;
+ *arm.com)
+ PLATPROV="$ARM_RGX"
+ ;;
+ *)
+ ;;
+esac
+
function user_warning() {
echo -e "Copyright of $RED$FILE$BLANK is out of date/incorrect"
echo -e "Updated copyright to"
- grep -nr "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE"
+ grep -nr "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE"
echo
}
@@ -29,31 +43,45 @@
then
break
fi
- # Check if correct copyright notice is in file.
- # To reduce false positives, we assume files with no
- # copyright notice do not require it.
- if ! grep "opyright.*$YEAR_NOW.*$ARM_RGX" "$FILE">/dev/null 2>&1
+
+ # Check if copyright header exists for the org
+ if ! grep "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE">/dev/null 2>&1 && [[ $ORG != *arm* ]]
then
- # If it is "from_date - to_date" type of entry - change to_date entry.
- if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
- then
- exit_code=1
- sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$ARM_RGX\)/\1$(date +"%Y"), Arm/" $FILE
- user_warning
- # If it is single "date" type of entry - add the copyright extension to current year.
- elif grep "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+ echo -e "Copyright header ""$RED""$PLATPROV""$BLANK"" is missing in ""$YELLOW""$FILE""$BLANK"
+ fi
+
+ # Check if the copyright year is updated for the org and update it
+ if [ ! -z "$PLATPROV" ]
+ then
+ if ! grep "opyright.*$YEAR_NOW.*$PLATPROV" "$FILE">/dev/null 2>&1
then
- exit_code=1
- sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$ARM_RGX\)/\1-$(date +"%Y"), Arm/" $FILE
- user_warning
+ # If it is "from_date - to_date" type of entry - change to_date entry.
+ if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$PLATPROV" "$FILE" >/dev/null 2>&1
+ then
+ exit_code=1
+ sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$PLATPROV\)/\1$(date +"%Y")\2/" $FILE
+ user_warning
+ # If it is single "date" type of entry - add the copyright extension to current year.
+ elif grep "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE" >/dev/null 2>&1
+ then
+ exit_code=1
+ sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$PLATPROV\)/\1-$(date +"%Y")\2/" $FILE
+ user_warning
+ fi
+
+ # Even if the year is correct - verify that Arm copyright is formatted correctly.
+ if [[ $ORG == *arm* ]]
+ then
+ if grep "opyright.*\(ARM\|arm\)" "$FILE">/dev/null 2>&1
+ then
+ exit_code=1
+ sed -i "s/\(opyright.*\)\(ARM\|arm\)/\1Arm/" $FILE
+ user_warning
+ fi
+ fi
fi
- # Even if the year is correct - verify that Arm copyright is formatted correctly.
- elif grep "opyright.*\(ARM\|arm\)" "$FILE">/dev/null 2>&1
- then
- exit_code=1
- sed -i "s/\(opyright.*\)\(ARM\|arm\)/\1Arm/" $FILE
- user_warning
fi
+
done <<< "$FILES"
if [ $exit_code -eq 1 ]
diff --git a/Makefile b/Makefile
index 792ad1c..87ff22e 100644
--- a/Makefile
+++ b/Makefile
@@ -933,12 +933,6 @@
endif
endif #(CTX_INCLUDE_PAUTH_REGS)
-ifeq ($(CTX_INCLUDE_MTE_REGS),1)
- ifneq (${ARCH},aarch64)
- $(error CTX_INCLUDE_MTE_REGS requires AArch64)
- endif
-endif #(CTX_INCLUDE_MTE_REGS)
-
ifeq ($(PSA_FWU_SUPPORT),1)
$(info PSA_FWU_SUPPORT is an experimental feature)
endif #(PSA_FWU_SUPPORT)
@@ -1252,7 +1246,6 @@
ARM_ARCH_MINOR \
BRANCH_PROTECTION \
CTX_INCLUDE_PAUTH_REGS \
- CTX_INCLUDE_MTE_REGS \
CTX_INCLUDE_NEVE_REGS \
CRYPTO_SUPPORT \
DISABLE_MTPMU \
@@ -1267,6 +1260,7 @@
ENABLE_FEAT_ECV \
ENABLE_FEAT_FGT \
ENABLE_FEAT_HCX \
+ ENABLE_FEAT_MTE \
ENABLE_FEAT_PAN \
ENABLE_FEAT_RNG \
ENABLE_FEAT_RNG_TRAP \
@@ -1322,7 +1316,6 @@
CTX_INCLUDE_PAUTH_REGS \
CTX_INCLUDE_MPAM_REGS \
EL3_EXCEPTION_HANDLING \
- CTX_INCLUDE_MTE_REGS \
CTX_INCLUDE_EL2_REGS \
CTX_INCLUDE_NEVE_REGS \
DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \
@@ -1425,6 +1418,7 @@
ENABLE_FEAT_S2POE \
ENABLE_FEAT_S1POE \
ENABLE_FEAT_GCS \
+ ENABLE_FEAT_MTE \
ENABLE_FEAT_MTE_PERM \
FEATURE_DETECTION \
TWED_DELAY \
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index 1ab2260..b8d336f 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -238,7 +238,7 @@
service_arg0 = (uint64_t)service_args;
service_arg1 = (uint64_t)(service_args >> 64U);
-#if CTX_INCLUDE_MTE_REGS
+#if ENABLE_FEAT_MTE
/*
* Write a dummy value to an MTE register, to simulate usage in the
* secure world
diff --git a/changelog.yaml b/changelog.yaml
index 3263082..35ffaa8 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -1372,6 +1372,9 @@
deprecated:
- cert_create
+ - title: Marvell Tools
+ scope: marvell-tools
+
- title: Dependencies
scope: deps
diff --git a/common/feat_detect.c b/common/feat_detect.c
index be22c6e..49b5360 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -70,18 +70,6 @@
#endif
}
-/************************************************
- * Feature : FEAT_MTE (Memory Tagging Extension)
- ***********************************************/
-static void read_feat_mte(void)
-{
-#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_ALWAYS)
- unsigned int mte = get_armv8_5_mte_support();
-
- feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE");
-#endif
-}
-
/****************************************************
* Feature : FEAT_BTI (Branch Target Identification)
***************************************************/
@@ -179,7 +167,8 @@
"TRF", 1, 1);
/* v8.5 features */
- read_feat_mte();
+ check_feature(ENABLE_FEAT_MTE, read_feat_mte_id_field(), "MTE",
+ MTE_IMPLEMENTED_EL0, MTE_IMPLEMENTED_ASY);
check_feature(ENABLE_FEAT_RNG, read_feat_rng_id_field(), "RNG", 1, 1);
read_feat_bti();
read_feat_rng_trap();
diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst
index 4f8c8b7..702bb56 100644
--- a/docs/components/cot-binding.rst
+++ b/docs/components/cot-binding.rst
@@ -67,14 +67,16 @@
- signing-key
Usage:
- This property is used to refer public key node present in
- parent certificate node and it is required property for all
- non-root certificates which are authenticated using public-key
- present in parent certificate.
+ For non-root certificates, this property is used to refer
+ public key node present in parent certificate node and it is
+ required property for all non-root certificates which are
+ authenticated using public-key present in parent certificate.
- This property is not required for root-certificates
- as root-certificates are validated using root of trust
- public key provided by platform.
+ This property is not required for all root-certificates. If
+ omitted, the root certificate will be validated using the
+ default platform ROTPK. If instead the root certificate needs
+ validating using a different ROTPK, the signing-key property
+ should provide a reference to the ROTPK node to use.
Value type: <phandle>
@@ -323,10 +325,50 @@
};
};
+rot_keys node binding definition
+---------------------------------
+
+- rot_keys node
+ Description: Contains root-of-trust keys for the root certificates.
+
+ SUBNODES
+ - Description:
+
+ Root of trust key information present in the root certificates
+ are shown by these nodes.
+
+ - rot key node
+ Description: Provide ROT key information in the certificate.
+
+ PROPERTIES
+
+ - oid
+ Usage:
+
+ This property provides the Object ID of ROT key provided
+ in the certificate.
+
+ Value type: <string>
+
+Example:
+Below is rot_keys example for CCA platform
+
+.. code:: c
+
+ rot_keys {
+ swd_rot_pk: swd_rot_pk {
+ oid = SWD_ROT_PK_OID;
+ };
+
+ prot_pk: prot_pk {
+ oid = PROT_PK_OID;
+ };
+ };
+
Future update to chain of trust binding
---------------------------------------
This binding document needs to be revisited to generalise some terminologies
which are currently specific to X.509 certificates for e.g. Object IDs.
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2024, Arm Limited. All rights reserved.*
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index 5d3adec..4834d3a 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -215,7 +215,7 @@
ARM_ARCH_MINOR=5 \
BRANCH_PROTECTION=1 \
CTX_INCLUDE_PAUTH_REGS=1 \
- CTX_INCLUDE_MTE_REGS=1 \
+ ENABLE_FEAT_MTE=1 \
BL32=<path-to-hafnium-binary> \
BL33=<path-to-bl33-binary> \
SP_LAYOUT_FILE=sp_layout.json \
@@ -233,7 +233,7 @@
ARM_ARCH_MINOR=5 \
BRANCH_PROTECTION=1 \
CTX_INCLUDE_PAUTH_REGS=1 \
- CTX_INCLUDE_MTE_REGS=1 \
+ ENABLE_FEAT_MTE=1 \
BL32=<path-to-hafnium-binary> \
BL33=<path-to-bl33-binary> \
SP_LAYOUT_FILE=sp_layout.json \
@@ -1670,4 +1670,4 @@
--------------
-*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 905b016..3485dc9 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -384,6 +384,10 @@
Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
erratum is still open.
+- ``ERRATA_A78C_2683027`` : This applies errata 2683027 workaround to
+ Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
+ erratum is still open.
+
- ``ERRATA_A78C_2712575`` : This applies erratum 2712575 workaround to
Cortex-A78C CPU, this erratum affects system configurations that do not use
an ARM interconnect IP. This needs to be enabled for revisions r0p1 and r0p2
@@ -771,6 +775,14 @@
CPU. This needs to be enabled only for revisions r0p0, r1p0, r1p1 and r1p2 of
the CPU and is still open.
+- ``ERRATA_X3_2266875``: This applies errata 2266875 workaround to the Cortex-X3
+ CPU. This needs to be enabled only for revisions r0p0 and r1p0 of the CPU, it
+ is fixed in r1p1.
+
+- ``ERRATA_X3_2302506``: This applies errata 2302506 workaround to the Cortex-X3
+ CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1, it is
+ fixed in r1p2.
+
- ``ERRATA_X3_2313909``: This applies errata 2313909 workaround to
Cortex-X3 CPU. This needs to be enabled only for revisions r0p0 and r1p0
of the CPU, it is fixed in r1p1.
@@ -946,7 +958,7 @@
--------------
-*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.*
.. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
.. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 3fce393..24efabe 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -2771,7 +2771,7 @@
(at EL0 and S-EL0) if it is only supported at EL0. If instead it is
implemented at all ELs, it is unconditionally enabled for only the normal
world. To enable it for the secure world as well, the build option
- ``CTX_INCLUDE_MTE_REGS`` is required. If the hardware does not implement
+ ``ENABLE_FEAT_MTE`` is required. If the hardware does not implement
MTE support at all, it is always disabled, no matter what build options
are used.
@@ -2860,7 +2860,7 @@
--------------
-*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
.. _SMCCC: https://developer.arm.com/docs/den0028/latest
.. _PSCI: https://developer.arm.com/documentation/den0022/latest/
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 5b03967..b859924 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -185,12 +185,6 @@
registers to be included when saving and restoring the CPU context.
Default is '0'.
-- ``CTX_INCLUDE_MTE_REGS``: Numeric value to include Memory Tagging Extension
- registers in cpu context. This must be enabled, if the platform wants to use
- this feature in the Secure world and MTE is enabled at ELX. This flag can
- take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
- Default value is 0.
-
- ``CTX_INCLUDE_NEVE_REGS``: Numeric value, when set will cause the Armv8.4-NV
registers to be saved/restored when entering/exiting an EL2 execution
context. This flag can take values 0 to 2, to align with the
@@ -313,6 +307,11 @@
flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
mechanism. Default value is ``0``.
+- ``ENABLE_FEAT_MTE``: Numeric value to enable Memory Tagging Extension
+ if the platform wants to use this feature in the Secure world and MTE is
+ enabled at ELX. This flag can take values 0 to 2, to align with the
+ ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+
- ``ENABLE_FEAT_MTE_PERM``: Numeric value to enable support for
``FEAT_MTE_PERM``, which introduces Allocation tag access permission to
memory region attributes. ``FEAT_MTE_PERM`` is a optional architectural
@@ -1334,7 +1333,7 @@
--------------
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
.. _DEN0115: https://developer.arm.com/docs/den0115/latest
.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 58b7d99..679de2b 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -142,6 +142,9 @@
PSA
Platform Security Architecture
+ PSR
+ Platform Security Requirements
+
PSCI
Power State Coordination Interface
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 1db7695..3f31d40 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -40,3 +40,16 @@
* `TFA_NO_PM` : Platform Management support.
- 0 : Enable Platform Management (Default)
- 1 : Disable Platform Management
+
+* `CPU_PWRDWN_SGI`: Select the SGI for triggering CPU power down request to
+ secondary cores on receiving power down callback from
+ firmware. Options:
+
+ - `0` : SGI 0
+ - `1` : SGI 1
+ - `2` : SGI 2
+ - `3` : SGI 3
+ - `4` : SGI 4
+ - `5` : SGI 5
+ - `6` : SGI 6 (Default)
+ - `7` : SGI 7
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index e76b955..aa094f7 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -56,6 +56,19 @@
- `spp_itr6` : SPP ITR6
- `emu_itr6` : EMU ITR6
+* `CPU_PWRDWN_SGI`: Select the SGI for triggering CPU power down request to
+ secondary cores on receiving power down callback from
+ firmware. Options:
+
+ - `0` : SGI 0
+ - `1` : SGI 1
+ - `2` : SGI 2
+ - `3` : SGI 3
+ - `4` : SGI 4
+ - `5` : SGI 5
+ - `6` : SGI 6 (Default)
+ - `7` : SGI 7
+
# PLM->TF-A Parameter Passing
------------------------------
The PLM populates a data structure with image information for the TF-A. The TF-A
diff --git a/docs/process/security.rst b/docs/process/security.rst
index bbc939a..c49ca6e 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -73,6 +73,8 @@
| |TFV-10| | Incorrect validation of X.509 certificate extensions can result |
| | in an out-of-bounds read |
+-----------+------------------------------------------------------------------+
+| |TFV-11| | A Malformed SDEI SMC can cause out of bound memory read |
++-----------+------------------------------------------------------------------+
.. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
.. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
@@ -87,6 +89,7 @@
.. |TFV-8| replace:: :ref:`Advisory TFV-8 (CVE-2018-19440)`
.. |TFV-9| replace:: :ref:`Advisory TFV-9 (CVE-2022-23960)`
.. |TFV-10| replace:: :ref:`Advisory TFV-10 (CVE-2022-47630)`
+.. |TFV-11| replace:: :ref:`Advisory TFV-11 (CVE-2023-49100)`
.. _TrustedFirmware.org security incident process: https://trusted-firmware-docs.readthedocs.io/en/latest/security_center/
diff --git a/docs/resources/diagrams/tf-a_attack_tree.png b/docs/resources/diagrams/tf-a_attack_tree.png
new file mode 100755
index 0000000..0ade8e8
--- /dev/null
+++ b/docs/resources/diagrams/tf-a_attack_tree.png
Binary files differ
diff --git a/docs/resources/diagrams/tf-a_data_flow_diagram.png b/docs/resources/diagrams/tf-a_data_flow_diagram.png
new file mode 100755
index 0000000..f65da01
--- /dev/null
+++ b/docs/resources/diagrams/tf-a_data_flow_diagram.png
Binary files differ
diff --git a/docs/resources/diagrams/tf-a_system_diagram.png b/docs/resources/diagrams/tf-a_system_diagram.png
new file mode 100755
index 0000000..f9bb9e9
--- /dev/null
+++ b/docs/resources/diagrams/tf-a_system_diagram.png
Binary files differ
diff --git a/docs/security_advisories/index.rst b/docs/security_advisories/index.rst
index c9b0f78..ad55546 100644
--- a/docs/security_advisories/index.rst
+++ b/docs/security_advisories/index.rst
@@ -15,3 +15,4 @@
security-advisory-tfv-8.rst
security-advisory-tfv-9.rst
security-advisory-tfv-10.rst
+ security-advisory-tfv-11.rst
diff --git a/docs/security_advisories/security-advisory-tfv-10.rst b/docs/security_advisories/security-advisory-tfv-10.rst
index 91dba07..f53bae1 100644
--- a/docs/security_advisories/security-advisory-tfv-10.rst
+++ b/docs/security_advisories/security-advisory-tfv-10.rst
@@ -98,7 +98,7 @@
``drivers/auth/``) require that the certificate's signature has already been
validated prior to calling ``get_ext()``, or any function that calls ``get_ext()``.
Platforms taking their chain of trust from a dynamic configuration file (such as
-``fdts/cot_descriptors.dtsi``) are also safe, as signature verification will
+``fdts/tbbr_cot_descriptors.dtsi``) are also safe, as signature verification will
always be done prior to any calls to ``get_ext()`` or ``auth_nvctr()`` in this
case, no matter the order of the properties in the file. Therefore, it is not
possible to exploit this vulnerability pre-authentication in upstream TF-A.
diff --git a/docs/security_advisories/security-advisory-tfv-11.rst b/docs/security_advisories/security-advisory-tfv-11.rst
new file mode 100644
index 0000000..b5063f0
--- /dev/null
+++ b/docs/security_advisories/security-advisory-tfv-11.rst
@@ -0,0 +1,86 @@
+Advisory TFV-11 (CVE-2023-49100)
+================================
+
++----------------+-------------------------------------------------------------+
+| Title | A Malformed SDEI SMC can cause out of bound memory read. |
++================+=============================================================+
+| CVE ID | `CVE-2023-49100`_ |
++----------------+-------------------------------------------------------------+
+| Date | Reported on 12 Oct 2023 |
++----------------+-------------------------------------------------------------+
+| Versions | TF-A releases v1.5 to v2.9 |
+| Affected | LTS releases lts-v2.8.0 to lts-v2.8.11 |
++----------------+-------------------------------------------------------------+
+| Configurations | Platforms with SDEI support |
+| Affected | |
++----------------+-------------------------------------------------------------+
+| Impact | Denial of Service (secure world panic) |
++----------------+-------------------------------------------------------------+
+| Fix Version | `a7eff3477`_ "fix(sdei): ensure that interrupt ID is valid" |
++----------------+-------------------------------------------------------------+
+| Credit | Christian Lindenmeier `@_chli_`_ |
+| | Marcel Busch `@0ddc0de`_ |
+| | `IT Security Infrastructures Lab`_ |
++----------------+-------------------------------------------------------------+
+
+This security advisory describes a vulnerability in the SDEI services, where a
+rogue Non-secure caller invoking a SDEI_INTERRUPT_BIND SMC call with an invalid
+interrupt ID causes out of bound memory read.
+
+SDEI_INTERRUPT_BIND is used to bind any physical interrupt into a normal
+priority SDEI event. The interrupt can be a private peripheral interrupt
+(PPI) or a shared peripheral interrupt (SPI).
+Refer to SDEI_INTERRUPT_BIND in the `SDEI Specification`_ for further details.
+
+The vulnerability exists when the SDEI client passes an interrupt ID which
+is not implemented by the GIC. This will result in a data abort exception
+or a EL3 panic depending on the GIC version used in the system.
+
+- **GICv2 systems:**
+
+.. code:: c
+
+ Call stack:
+ sdei_interrupt_bind(interrupt ID)
+ -> plat_ic_get_interrupt_type(interrupt ID)
+ -> gicv2_get_interrupt_group(interrupt ID)
+ -> gicd_get_igroupr(distributor base, interrupt ID)
+ -> gicd_read_igroupr(distributor base, interrupt ID).
+
+ gicd_read_igroupr() will eventually do a MMIO read to an unimplemented IGROUPR
+ register. Which may cause a data abort or an access to a random EL3 memory region.
+
+- **GICv3 systems:**
+
+.. code:: c
+
+ Call stack:
+ sdei_interrupt_bind(interrupt ID)
+ -> plat_ic_get_interrupt_type(interrupt ID)
+ -> gicv3_get_interrupt_group(interrupt ID, core ID)
+ -> is_sgi_ppi(interrupt ID)
+
+ is_sgi_ppi() will end up in an EL3 panic on encountering an invalid interrupt ID.
+
+The vulnerability is fixed by ensuring that the Interrupt ID provided by the
+SDEI client is a valid PPI or SPI, otherwise return an error code indicating
+that the parameter is invalid.
+
+.. code:: c
+
+ /* Bind an SDEI event to an interrupt */
+ static int sdei_interrupt_bind(unsigned int intr_num)
+ {
+ sdei_ev_map_t *map;
+ bool retry = true, shared_mapping;
+
+ /* Interrupt must be either PPI or SPI */
+ if (!(plat_ic_is_ppi(intr_num) || plat_ic_is_spi(intr_num)))
+ return SDEI_EINVAL;
+
+.. _CVE-2023-49100: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-49100
+.. _a7eff3477: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=a7eff3477dcf3624c74f5217419b1a27b7ebd2aa
+.. _IT Security Infrastructures Lab: https://www.cs1.tf.fau.de/
+.. _SDEI Specification: https://developer.arm.com/documentation/den0054/latest/
+.. _@_chli_: https://twitter.com/_chli_
+.. _@0ddc0de: https://twitter.com/0ddc0de
diff --git a/docs/threat_model/firmware_threat_model/index.rst b/docs/threat_model/firmware_threat_model/index.rst
new file mode 100644
index 0000000..05b6710
--- /dev/null
+++ b/docs/threat_model/firmware_threat_model/index.rst
@@ -0,0 +1,41 @@
+TF-A Firmware Threat Model
+==========================
+
+As the TF-A codebase is highly configurable to allow tailoring it best for each
+platform's needs, providing a holistic threat model covering all of its features
+is not necessarily the best approach. Instead, we provide a collection of
+documents which, together, form the project's threat model. These are
+articulated around a core document, called the :ref:`Generic Threat Model`,
+which focuses on the most common configuration we expect to see. The other
+documents typically focus on specific features not covered in the core document.
+
+As the TF-A codebase evolves and new features get added, these threat model
+documents will be updated and extended in parallel to reflect at best the
+current status of the code from a security standpoint.
+
+ .. note::
+
+ Although our aim is eventually to provide threat model material for all
+ features within the project, we have not reached that point yet. We expect
+ to gradually fill these gaps over time.
+
+Each of these documents give a description of the target of evaluation using a
+data flow diagram, as well as a list of threats we have identified using the
+`STRIDE threat modeling technique`_ and corresponding mitigations.
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+
+ threat_model
+ threat_model_el3_spm
+ threat_model_fvp_r
+ threat_model_rss_interface
+ threat_model_arm_cca
+ threat_model_fw_update_and_recovery
+
+--------------
+
+*Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.*
+
+.. _STRIDE threat modeling technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/firmware_threat_model/threat_model.rst
similarity index 99%
rename from docs/threat_model/threat_model.rst
rename to docs/threat_model/firmware_threat_model/threat_model.rst
index 0da2558..d93547f 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model.rst
@@ -42,6 +42,8 @@
- No experimental features are enabled. We do not consider threats that may come
from them.
+- The platform's hardware complies with the `PSR specification`_, defining the
+ bare-minimum security prerequisites for System-on-Chips (SoC).
Data Flow Diagram
=================
@@ -53,7 +55,7 @@
trust boundaries. Components outside of the broken lines
are considered untrusted by TF-A.
-.. uml:: ../resources/diagrams/plantuml/tfa_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/tfa_dfd.puml
:caption: Figure 1: TF-A Data Flow Diagram
.. table:: Table 1: TF-A Data Flow Diagram Description
@@ -1088,7 +1090,7 @@
--------------
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
.. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
@@ -1101,3 +1103,4 @@
.. _Secure Development Guidelines: https://trustedfirmware-a.readthedocs.io/en/latest/process/security-hardening.html#secure-development-guidelines
.. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
.. _OP-TEE Dispatcher: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/spd/optee-dispatcher.rst
+.. _PSR Specification: https://developer.arm.com/documentation/den0106/0100
diff --git a/docs/threat_model/threat_model_arm_cca.rst b/docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
similarity index 98%
rename from docs/threat_model/threat_model_arm_cca.rst
rename to docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
index fbf3327..af38ea3 100644
--- a/docs/threat_model/threat_model_arm_cca.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
@@ -86,7 +86,7 @@
diagram, the red broken lines indicate trust boundaries. Components outside of
the broken lines are considered untrusted by TF-A.
-.. uml:: ../resources/diagrams/plantuml/tfa_arm_cca_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/tfa_arm_cca_dfd.puml
:caption: Figure 1: Data Flow Diagram
.. table:: Table 1: Data Flow Diagram Description
@@ -220,6 +220,6 @@
| 14 | Yes | |
+----+-------------+-------------------------------------------------------+
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
.. _Arm CCA Security Model: https://developer.arm.com/documentation/DEN0096/A_a
diff --git a/docs/threat_model/threat_model_el3_spm.rst b/docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
similarity index 99%
rename from docs/threat_model/threat_model_el3_spm.rst
rename to docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
index 8adf3df..a2d6798 100644
--- a/docs/threat_model/threat_model_el3_spm.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
@@ -37,7 +37,7 @@
Components outside of the broken lines are considered untrusted.
-.. uml:: ../resources/diagrams/plantuml/el3_spm_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/el3_spm_dfd.puml
:caption: Figure 1: EL3 SPMC Data Flow Diagram
.. table:: Table 1: EL3 SPMC Data Flow Diagram Description
@@ -644,7 +644,7 @@
---------------
-*Copyright (c) 2022-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2022-2024, Arm Limited. All rights reserved.*
.. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
.. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
diff --git a/docs/threat_model/threat_model_fvp_r.rst b/docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
similarity index 98%
rename from docs/threat_model/threat_model_fvp_r.rst
rename to docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
index 725eeed..0b71bf0 100644
--- a/docs/threat_model/threat_model_fvp_r.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
@@ -96,4 +96,4 @@
--------------
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst b/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst
new file mode 100644
index 0000000..7b55c74
--- /dev/null
+++ b/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst
@@ -0,0 +1,103 @@
+Threat Model for TF-A with PSA FWU or TBBR FWU support
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduction
+************
+
+This document provides a threat model of TF-A firmware for platforms with
+the feature PSA firmware update or TBBR firmware update or both enabled.
+To understand the design of the firmware update refer
+:ref:`Firmware Update (FWU)`.
+
+Although it is a separate document, it references the :ref:`Generic Threat
+Model` in a number of places, as some of the contents are applicable to this
+threat model.
+
+Target of Evaluation
+********************
+
+In this threat model, the target of evaluation is the Trusted Firmware for
+A-class Processors (TF-A) when PSA FWU support is enabled or TBBR FWU mode
+is enabled. This includes the boot ROM (BL1), the trusted boot firmware (BL2).
+
+Threat Assessment
+*****************
+
+For this section, please reference the Threat Assessment under the
+:ref:`Generic Threat Model`. Here only the differences are highlighted.
+
+PSA FWU
+*******
+
+Threats to be Mitigated by the Boot Firmware
+--------------------------------------------
+
+The following table analyses the :ref:`Boot Firmware Threats` in the context
+of this threat model. Only additional details are pointed out.
+
++----+-------------+-------------------------------------------------------+
+| ID | Applicable? | Comments |
++====+=============+=======================================================+
+| 01 | Yes | | Attacker can use arbitrary images to update the |
+| | | system. |
++----+-------------+-------------------------------------------------------+
+| 02 | Yes | | Attacker tries to update the system with the |
+| | | vulnerable/older firmware. |
++----+-------------+-------------------------------------------------------+
+| 03 | Yes | |
++----+-------------+-------------------------------------------------------+
+| 04 | Yes | |
++----+-------------+-------------------------------------------------------+
+
+
+Threats to be mitigated by platform design
+------------------------------------------
+
+PSA FWU is driven by metadata stored in non-volatile storage. This metadata
+is not cryptographically signed. Also, depending on the hardware design,
+it may be stored in untrusted storage, which makes it possible for software
+outside of TF-A security boundary or for a physical attacker to modify it
+in order to change the behaviour of the FWU process.
+
+Below we provide some possible FWU metadata corruption scenarios:
+
+1. The FWU metadata includes the firmware bank for booting; the attacker
+ tries to modify it to prevent the execution of the updated firmware.
+2. The FWU metadata features a field indicating the firmware's status, either
+ in trial run or accepted run. The attacker tries to manipulate this field,
+ ensuring the updated firmware consistently runs in trial mode, with the
+ intention of preventing the anti-rollback update.
+
+By design, no software mitigations exist to prevent this. The safeguarding
+of FWU metadata relies on the platform's hardware design to mitigate potential
+attacks on it, if this is a concern in the platform's threat model.
+For example, FWU metadata may be stored in secure storage under exclusive
+access from secure software, protecting it from physical, unauthenticated
+accesses and from non-secure software accesses.
+
+TBBR FWU - Firmware Recovery
+****************************
+
+Threats to be Mitigated by the Boot Firmware
+--------------------------------------------
+
+The following table analyses the :ref:`Boot Firmware Threats` in the context
+of this threat model. Only additional details are pointed out.
+
++----+-------------+-------------------------------------------------------+
+| ID | Applicable? | Comments |
++====+=============+=======================================================+
+| 01 | Yes | | Attacker can use arbitrary images to recover the |
+| | | system. |
++----+-------------+-------------------------------------------------------+
+| 02 | Yes | | Attacker tries to recover the system with the |
+| | | vulnerable/older firmware. |
++----+-------------+-------------------------------------------------------+
+| 03 | Yes | |
++----+-------------+-------------------------------------------------------+
+| 04 | Yes | |
++----+-------------+-------------------------------------------------------+
+
+--------------
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/threat_model_rss_interface.rst b/docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst
similarity index 95%
rename from docs/threat_model/threat_model_rss_interface.rst
rename to docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst
index 4bceb63..025d2d9 100644
--- a/docs/threat_model/threat_model_rss_interface.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst
@@ -24,7 +24,7 @@
cores. The interface description only focuses on the AP-RSS interface the rest
is the same as in the general TF-A threat-model document.
-.. uml:: ../resources/diagrams/plantuml/tfa_rss_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/tfa_rss_dfd.puml
:caption: Figure 1: TF-A Data Flow Diagram including RSS
.. table:: Table 1: TF-A - RSS data flow diagram
@@ -56,4 +56,4 @@
--------------
-*Copyright (c) 2022, Arm Limited. All rights reserved.*
\ No newline at end of file
+*Copyright (c) 2022-2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/index.rst b/docs/threat_model/index.rst
index e22378b..446e610 100644
--- a/docs/threat_model/index.rst
+++ b/docs/threat_model/index.rst
@@ -4,40 +4,14 @@
Threat modeling is an important part of Secure Development Lifecycle (SDL)
that helps us identify potential threats and mitigations affecting a system.
-As the TF-A codebase is highly configurable to allow tailoring it best for each
-platform's needs, providing a holistic threat model covering all of its features
-is not necessarily the best approach. Instead, we provide a collection of
-documents which, together, form the project's threat model. These are
-articulated around a core document, called the :ref:`Generic Threat Model`,
-which focuses on the most common configuration we expect to see. The other
-documents typically focus on specific features not covered in the core document.
-
-As the TF-A codebase evolves and new features get added, these threat model
-documents will be updated and extended in parallel to reflect at best the
-current status of the code from a security standpoint.
-
- .. note::
-
- Although our aim is eventually to provide threat model material for all
- features within the project, we have not reached that point yet. We expect
- to gradually fill these gaps over time.
-
-Each of these documents give a description of the target of evaluation using a
-data flow diagram, as well as a list of threats we have identified using the
-`STRIDE threat modeling technique`_ and corresponding mitigations.
.. toctree::
:maxdepth: 1
:caption: Contents
- threat_model
- threat_model_el3_spm
- threat_model_fvp_r
- threat_model_rss_interface
- threat_model_arm_cca
+ firmware_threat_model/index
+ supply_chain_threat_model
--------------
-*Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.*
-
-.. _STRIDE threat modeling technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
+*Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/threat_model/supply_chain_threat_model.rst b/docs/threat_model/supply_chain_threat_model.rst
new file mode 100644
index 0000000..386a4b0
--- /dev/null
+++ b/docs/threat_model/supply_chain_threat_model.rst
@@ -0,0 +1,760 @@
+TF-A Supply Chain Threat Model
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduction
+************
+
+Software supply chain attacks aim to inject malicious code into a software
+product. There are several ways a malicious code can be injected into a
+software product (open-source project). These include:
+
+- Malicious code commits: This attack directly injects code into a project
+ repository. This can happen for example through developer/maintainer
+ credential hijacks, or malicious external contributors.
+
+- Malicious dependencies: In this case malicious code is introduced into a
+ project through other piece of code or packages the project depends on. This
+ can happen through for example typosquatting attack where an attacker creates
+ a malicious package with a very similar name to a popular package and hosts
+ it on popular package repositories.
+
+- Malicious toolchains: This involves malicious code introduced by compromised
+ resources used throughout the development and/or build process such as
+ compilers and IDEs.
+
+This document provides analysis of software supply chain attack threats for the
+TF-A project.
+
+TF-A Overview
+*************
+
+Figure 1 shows the different software components surrounding the TF-A project.
+A brief description of each component is provided below.
+
+TF-A Repository
+===============
+
+The TF-A repository contains generic and platform code contributed by TF-A
+contributors as well as libraries imported from other open-source projects,
+referred to as internal dependencies on Figure 1. These libraries include:
+
+- *libfdt*: libfdt is a utility library for reading and manipulating Device
+ Tree Binary (DTB) files. It is part of the Device Tree Compiler (DTC)
+ toolchain [1]_. DTC is used as part of the build process on the host machine
+ to build DTB files. libfdt is used to parse the DTB files at boot time.
+
+- *zlib*: zlib is a data compression library imported from [2]_.
+
+- *compiler-rt*: This is a collection of runtime libraries from the LLVM
+ compiler infrastructure project [3]_. We import the builtins library which
+ provides low-level, target-specific compiler builtins from compiler-rt.
+
+The TF-A repository also includes source code for host tools that supplement
+the TF-A build process. These tools include:
+
+- *fiptool*: This tool is used to create a Firmware Image Package (FIP) which
+ allows for packing bootloader images into a single archive that can be
+ loaded by TF-A from non-volatile platform storage.
+
+- *cert_create*: This tool is used to generate certificates for binary images.
+
+- *encrypt_fw*: This tool takes the plain firmware image as input and generates
+ the encrypted firmware image which can then be passed as input to the fiptool
+ utility for creating the FIP.
+
+- *sptool*: This tool is used to build the secure partition packages.
+
+|TF-A System Diagram|
+*Figure 1: TF-A System Diagram*
+
+External Dependencies
+=====================
+
+These are software components that are not part of the TF-A repository but are
+required to build TF-A binaries and host tools.
+
+- *Mbed TLS Library*: This is a cryptography library from trustedfirmware.org
+ (tf.org). It is required to build TF-A binaries where cryptography features
+ are needed, such as Trusted Board Boot (TBB).
+
+- *OpenSSL Library*: This is another cryptography library used by TF-A host
+ tools: fiptool, cert_create, and encrypt_fw.
+
+The following table lists TF-A dependencies including the sources of the
+dependencies.
+
+.. table:: Table 1: TF-A Dependencies
+
+ +-------------+------------------------+------------------------------------+
+ | Dependency | Location of Dependency | Original Source |
+ +=============+========================+====================================+
+ | libfdt | Local copy | [1]_ |
+ +-------------+------------------------+------------------------------------+
+ | zlib | Local copy | [2]_ |
+ +-------------+------------------------+------------------------------------+
+ | compiler-rt | Local copy | [3]_ |
+ +-------------+------------------------+------------------------------------+
+ | Mbed TLS | External | [4]_ |
+ +-------------+------------------------+------------------------------------+
+ | OpenSSL | External | [5]_ |
+ +-------------+------------------------+------------------------------------+
+
+Supplementary Binaries
+======================
+
+These are binaries used to test TF-A based systems. Below is a brief
+description of each component and where they are sourced from.
+
+- *SCP-firmware*: For our tests, we use SCP-firmware binaries supplied by the
+ Arm SCP team built from the source from the GitHub repository [6]_.
+
+- *OP-TEE*: Trusted Execution Environment (TEE) from tf.org that runs as
+ Secure EL1. We use OP-TEE built from source or binaries supplied with Arm
+ Reference Platforms depending on the test configuration.
+
+- *EDK2 UEFI*: Normal world bootloader from the EDK2 project [7]_. We use EDK2
+ UEFI binaries hosted on tf.org servers for testing [8]_.
+
+Other software components used to test TF-A include U-Boot, Linux kernel, RSS,
+MCP, and file systems, all sourced from the Arm Reference Platforms teams.
+
+TF-A Toolchain
+==============
+
+The TF-A project uses several tools to build, analyze and test the TF-A source
+code.
+
+Node.js Tools
+-------------
+
+These are optional quality assurance and developer utility tools that are
+installed through the use of the Node.js package manager. They are pinned to
+specific versions described by the package.json file in the root of the TF-A
+repository, and their dependencies are downloaded from the internet at the
+point of installation. These tools may be installed locally on the developer
+machine and are installed within a Docker container in certain CI jobs. At
+present, these are:
+
+- Commitlint
+
+- Commitizen
+
+- Husky
+
+Infrastructure
+==============
+
+TF-A uses trustedfirmware.org (tf.org) and Arm infrastructures to host the
+source code, review code and run tests. Appendix A provides a security analysis
+of tf.org infrastructure.
+
+TF-A Data Flow
+**************
+
+Figure 2 below shows the data flow diagram for TF-A. The broken red lines
+indicate trust boundaries.
+
+|TF-A Data Flow Diagram|
+*Figure 2: TF-A Data Flow Diagram*
+
+Attack Tree
+***********
+
+|TF-A Attack Tree|
+*Figure 3: TF-A Attack Tree*
+
+Threat Assessment and Mitigations
+*********************************
+
+Impact and Likelihood Ratings
+=============================
+
+ +--------+------------------------------+-----------------------------------+
+ | Rating | Impact | Likelihood |
+ +========+==============================+===================================+
+ | HIGH | Major impact to entire | Threat is relatively easy to |
+ | | organization or single line | exploit by an attacker with |
+ | | of business if exploited. | little effort and skill. |
+ +--------+------------------------------+-----------------------------------+
+ | MEDIUM | Noticeable impact to line of | An expert attacker could exploit |
+ | | business if exploited. | the threat without much |
+ | | | difficulty. |
+ +--------+------------------------------+-----------------------------------+
+ | LOW | Minor damage if exploited or | Exploiting the threat would |
+ | | could be used in conjunction | require considerable effort and |
+ | | with other vulnerabilities | resources. |
+ | | to perform a more serious | |
+ | | attack. | |
+ +--------+------------------------------+-----------------------------------+
+
+Threats and Mitigations
+=======================
+
+Threat naming convention key
+
+- SC – Supply Chain
+
+- SRC – Source
+
+- DEP – Dependency
+
+- TOOL – Toolchain
+
+- REPO – Repository
+
+- MAIN – Maintainer
+
+- CONT – Contributor
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-SRC-MAIN-01 |
+ +=============+=============================================================+
+ | Description | An attacker can submit and merge malicious code by posing |
+ | | as a maintainer after compromising maintainers’ |
+ | | credentials. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | MEDIUM |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | In the TF-A code review process all submitted changes |
+ | impact | undergo review by a code owner and a maintainer. If the |
+ | | change is accepted, it will be merged (integrated) into  |
+ | | an integration branch by a maintainer. A maintainer has |
+ | | the right to give a code owner review, a maintainer |
+ | | review and merge the submitted change.  |
+ | | |
+ | | | tf.org users (including maintainers) are authenticated |
+ | | through GitHub. The likelihood of a credential compromise |
+ | | depends on multiple factors. The authentication mechanism |
+ | | of GitHub is strong if the recommended best practices are |
+ | | followed [9]_ making credential compromise unlikely. |
+ | | GitHub (therefore tf.org) allows logins with two-factor |
+ | | authentication, requiring both a password and access to |
+ | | the user's authentication code. Depending on the strength |
+ | | of the password and factors such as whether the |
+ | | maintainer reuses passwords across services, the |
+ | | likelihood of a compromise can be higher. |
+ | | |
+ | | | If an attacker manages to compromise a maintainer’s |
+ | | credentials, posing as the maintainer, they can in theory |
+ | | submit a malicious change (as a maintainer or as a |
+ | | contributor), give all the necessary reviews and merge |
+ | | the change. |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | | - Enforce best practices recommended by GitHub [9]_ |
+ | | |
+ | | | - Not allowing a committer to both self-review and merge |
+ | | patches they have submitted. To achieve the commit the |
+ | | attacker would be required to compromise at least two |
+ | | credentials (reviewers and maintainer). |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | We have not disallowed self-review/merge of patches |
+ | implemented?| |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-SRC-MAIN-02 |
+ +=============+=============================================================+
+ | Description | An attacker can submit and merge malicious code after |
+ | | becoming a maintainer through social engineering |
+ | | techniques. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | LOW |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | According to the TF project maintenance process [10]_, |
+ | impact | maintainers of TF-A are selected by their peers based on |
+ | | merit. Some of the criteria of becoming a maintainer |
+ | | include being an active member of the project for a |
+ | | minimum duration and contributing a substantial number of |
+ | | non-trivial and high-quality patches. However, there are |
+ | | some weaknesses in the process: |
+ | | |
+ | | | - There is no structured mechanism to establish trust |
+ | | with a maintainer other than the recommendations by |
+ | | peers |
+ | | | - There is no continuous monitoring of the status of a |
+ | | maintainer (e.g. maintainer can move from one |
+ | | organization to another) |
+ | | |
+ | | | To perform such an attack, in addition to becoming a |
+ | | maintainer, an attacker also must deal with all |
+ | | restrictions put on maintainers. |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | | - Structured mechanism to establish trust with |
+ | | maintainers |
+ | | |
+ | | | - Not allowing a committer to both self-review and merge |
+ | | patches they have submitted. To achieve the commit the |
+ | | attacker would be required to compromise at least two |
+ | | credentials (reviewers and maintainer). |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | There is a structured mechanism to establish trust with |
+ | implemented?| maintainers, but self-review/merge of patches is not |
+ | | disallowed |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-SRC-CONT-01 |
+ +=============+=============================================================+
+ | Description | An attacker can submit malicious code patch as a |
+ | | contributor. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | LOW |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | TF-A accepts external contributions to both the generic |
+ | impact | and platform code. Unlike maintainers, contributors do |
+ | | not have maintainer review or merging privileges, |
+ | | therefore the likelihood of injecting malicious code as a |
+ | | contributor is lower. However, even though unlikely, it |
+ | | is still possible for a malicious commit to go unnoticed |
+ | | through the code review and verification processes. |
+ | | |
+ | | | If successful, the impact can range from low to high |
+ | | depending on the injected code. For example, an attacker |
+ | | can potentially deliberately insert a memory corruption |
+ | | vulnerability that is hard to notice on code review and |
+ | | will not be detected by the verification process. This |
+ | | vulnerability by itself may have a low impact but can |
+ | | have a major impact if used in combination with other |
+ | | vulnerabilities. |
+ +-------------+-------------------------------------------------------------+
+ | Proposed | - Code review and verification |
+ | Mitigations | - Static analysis to try to pick up issues that typically |
+ | | end in some form of attack vector |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | Yes, contributions go through the thorough review, |
+ | implemented?| verification, and static analysis process automated through |
+ | | CI |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-DEP-01 |
+ +=============+=============================================================+
+ | Description | An attacker can inject malicious code into TF-A internal |
+ | | dependencies. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | LOW |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | TF-A has two types of dependencies: those that are copied |
+ | impact | into the TF-A repository and shipped as part of TF-A code |
+ | | (referred to as *internal dependencies* here) and those |
+ | | that are downloaded from external repositories and used |
+ | | when building TF-A (referred to as |
+ | | *external dependencies* here).  |
+ | | |
+ | | | Currently TF-A has three internal dependencies: *libfdt* |
+ | | [1]_, *zlib* [2]_ and *compiler-rt* [3]_ libraries. These |
+ | | libraries are periodically updated by copying them from |
+ | | their source repositories. Although unlikely, it is |
+ | | possible for a contributor to copy the libraries from the |
+ | | wrong (and potentially malicious) repositories. For |
+ | | example, there are already multiple forks of *libfdt* |
+ | | (DTC) on GitHub. In addition to this, the official |
+ | | repositories are not immune to threats described above |
+ | | (TFA-SC-SRC-MAIN-01, TFA-SC-SRC-MAIN-02 and |
+ | | TFA-SC-SRC-CONT-01). |
+ | | |
+ | | | The likelihood of an attack on TF-A through internal |
+ | | dependencies is lower than external dependencies for the |
+ | | following reasons:  |
+ | | |
+ | | | - Internal dependencies go through the normal code review |
+ | | process during upgrade |
+ | | | - Once upgraded internal dependencies stay unchanged |
+ | | until the next upgrade. The upgrade window is typically |
+ | | long (for example *libfdt* has only changed 4 times |
+ | | over the past 4 years). This reduces the window of |
+ | | opportunity for an attacker to inject malicious code |
+ | | into the dependencies |
+ +-------------+-------------------------------------------------------------+
+ | Proposed | - Explicitly document versions and official sources of |
+ | Mitigations | dependencies |
+ | | - Keep a copy of a pinned version of the source code inside |
+ | | the TF-A tree so that the risk of getting malicious code |
+ | | from dependencies only arises when we upgrade them |
+ | | - Monitor alerts for vulnerable dependencies from GitHub |
+ | | [11]_ |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | Yes, we explicitly document versions and official sources |
+ | implemented?| of dependencies, keep a copy of pinned versions of the |
+ | | source code, and monitor alerts for vulnerable dependencies |
+ | | for Python and Node.js, but we aren't able to do this for C |
+ | | dependencies |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-DEP-02 |
+ +=============+=============================================================+
+ | Description | An attacker can inject malicious code into TF-A external |
+ | | dependencies. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | MEDIUM |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | Unlike internal dependencies, external dependencies are |
+ | impact | downloaded from external repositories by end-users. |
+ | | Although the TF-A documentation provides information |
+ | | about the versions of dependencies used for testing and |
+ | | links to repositories, it is up to the end-user to decide |
+ | | where to get the dependencies from. As such, the |
+ | | likelihood of an attack through an external dependency is |
+ | | higher compared to an internal dependency. |
+ | | |
+ | | | The impact of an attack ranges from low to critical |
+ | | depending on which dependency and what part of the |
+ | | dependency is affected. For example, a malicious code |
+ | | that affects the signature verification functions in |
+ | | MbedTLS is considered critical as it can be used to |
+ | | bypass the TBB process of TF-A. |
+ +-------------+-------------------------------------------------------------+
+ | Proposed | - Explicitly document versions and official sources of |
+ | Mitigations | dependencies |
+ | | - Provide scripts and build options to automatically fetch |
+ | | the latest stable release of external dependencies |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | We explicitly document versions and official sources of |
+ | implemented?| dependencies, but do not yet provide scripts and build |
+ | | options to automatically fetch the latest stable release of |
+ | | external dependencies |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-REPO-01 |
+ +=============+=============================================================+
+ | Description | An attacker can upload malicious versions of TF-A by |
+ | | compromising credentials of administrator accounts on |
+ | | tf.org or GitHub. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | LOW |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | This attack is like TFA-SC-SRC-MAIN-01, but the |
+ | impact | likelihood and impact of the two attacks are different. |
+ | | |
+ | | | The likelihood of compromising administrator credentials |
+ | | is lower than that of a maintainer’s (assuming both use |
+ | | authentication methods of similar strength) as there are |
+ | | smaller number of administrators than maintainers. On the |
+ | | other hand, the impact is higher since an administrator |
+ | | has more privileges than a maintainer: |
+ | | |
+ | | | - An administrator can upload a malicious TF-A |
+ | | contribution unnoticed by other reviewers |
+ | | - An administrator can potentially rewrite the history of |
+ | | the repository to evade detection |
+ +-------------+-------------------------------------------------------------+
+ | Proposed | Strong authentication (Follow best practices recommended by |
+ | Mitigations | GitHub [9]_) |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | Yes, strong authentication is implemented through |
+ | implemented?| recommended best practices |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-REPO-02 |
+ +=============+=============================================================+
+ | Description | An attacker can upload malicious versions of TF-A after |
+ | | getting write access to the repository by exploiting a |
+ | | vulnerability on tf.org or GitHub. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | LOW |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | There are no reports of someone exploiting a |
+ | impact | vulnerability on GitHub or tf.org to upload malicious |
+ | | contributions. However, there are examples of |
+ | | vulnerabilities that allowed arbitrary code execution on |
+ | | popular hosting services [12]_. Such vulnerabilities can |
+ | | potentially be used to upload malicious packages. In |
+ | | addition to being hard to exploit, vulnerabilities on |
+ | | popular hosting sites such as GitHub are typically |
+ | | detected quickly, making the window of opportunity for |
+ | | such attack small. |
+ +-------------+-------------------------------------------------------------+
+ | Proposed | - Monitor alerts of any vulnerabilities that might affect |
+ | Mitigations | TF-A repository |
+ | | - Ensure tf.org is up to date with latest security patches |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | Yes, alerts of vulnerabilities are monitored and tf.org is |
+ | implemented?| ensured to be up to date with the latest security patches |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-REPO-03 |
+ +=============+=============================================================+
+ | Description | An attacker can host a malicious version of TF-A on an |
+ | | attacker-controlled repository, and trick end-users into |
+ | | downloading from that repository. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | MEDIUM |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | It is not difficult for an attacker to create a website |
+ | impact | with a similar domain name and look as tf.org (website |
+ | | spoofing) and host a malicious TF-A source repository. |
+ | | Similarly, an attacker can create a mirror of the TF-A |
+ | | repository on GitHub with malicious code in it. However, |
+ | | for this attack to succeed the attacker needs to trick |
+ | | the end-user into using the attacker-controlled |
+ | | repositories. |
+ +-------------+-------------------------------------------------------------+
+ | Proposed | - Users should carefully check the URL of the website |
+ | Mitigations | before visiting it and the URL of the repository before |
+ | | checking it out |
+ | | - Accept reports of spoofing attacks on tf.org and |
+ | | broadcast a warning to partners |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | We accept reports of spoofing attacks on tf.org and will |
+ | implemented?| broadcast a warning to partners |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-TOOL-01 |
+ +=============+=============================================================+
+ | Description | Malicious code can be injected at build time through |
+ | | malicious tools. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | LOW |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | End-users of TF-A use make (or cmake), compilers and |
+ | impact | linkers (armgcc, armclang or LLVM) to build TF-A |
+ | | binaries. Although TF-A documentation specifies versions |
+ | | and official sources of tools used to build TF-A, users |
+ | | can potentially be tricked into using unofficial, |
+ | | malicious toolchains. Similar attacks have been used in |
+ | | the past to inject malicious code into final products |
+ | | [13]_. |
+ +-------------+-------------------------------------------------------------+
+ | Proposed | - Explicitly document versions and official sources of |
+ | Mitigations | toolchains |
+ | | - Provide scripts to automatically fetch the latest stable |
+ | | release of toolchains |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | We explicitly document versions and official sources of |
+ | implemented?| toolchains, but have not yet provided scripts to |
+ | | automatically fetch the latest stable release of toolchains |
+ +-------------+-------------------------------------------------------------+
+
+ +---------------------------------------------------------------------------+
+ | Threat: TFA-SC-TOOL-02 |
+ +=============+=============================================================+
+ | Description | Malicious code can be executed by developer’s tools at |
+ | | installation time through malicious Node.js dependencies. |
+ +-------------+-------------------------------------------------------------+
+ | Impact | HIGH |
+ +-------------+-------------------------------------------------------------+
+ | Likelihood | LOW |
+ +-------------+-------------------------------------------------------------+
+ | Threat and | | Users of the Node.js tools, including the CI, may be |
+ | impact | exposed to malicious dependencies that have been missed |
+ | | by the Node.js dependency auditor. Users of these tools |
+ | | could potentially be executing malicious code when using |
+ | | these tools, which could potentially allow a malicious |
+ | | actor to make silent modifications to the repository or |
+ | | enable retrieval of user credentials. |
+ | | |
+ | | | If successful, the impact can range from low to high |
+ | | depending on the user's credentials. If the user is an |
+ | | administrator, this could imply TFA-SC-REPO-01. |
+ +-------------+-------------------------------------------------------------+
+ | Proposed | - Limit Node.js tools to a minimal set of trusted packages |
+ | Mitigations | - Pin Node.js packages to known versions |
+ | | - Update dependencies for which Node.js’s auditor reports |
+ | | known CVEs |
+ | | - Execute Node.js tools in the CI only from within a |
+ | | trusted container |
+ +-------------+-------------------------------------------------------------+
+ | Mitigations | Yes, Node.js tools are limited to a minimal set of trusted |
+ | implemented?| packages, packages are pinned to known versions, |
+ | | dependencies are updated when there are known CVEs |
+ | | reported, and Node.js tools are only executed within a |
+ | | trusted container in CI |
+ +-------------+-------------------------------------------------------------+
+
+Appendix A
+**********
+
+Summary of trustedfirmware.org security:
+
+.. table:: Table 2: Security information of trustedfirmware.org
+
+ +------------+--------------------+--------------------+--------------------+
+ | Software/ | Source and | Credential and | Security incident |
+ | System | integrity | permission | response plan |
+ | | | management | |
+ +============+====================+====================+====================+
+ | Jenkins | - Jenkins is built | - Use oauth from | - Monitor CVE’s |
+ | (including | using Dockerfile | Github only | and update |
+ | plugins) | which is based | - The password | Jenkins LTS on a |
+ | | on the official | strength follows | monthly cycle |
+ | | Jenkins docker | Github policy | - Keep plugins up- |
+ | | image | - Do not enforce | to-date. But it |
+ | | - Jenkins plugins | using two-factor | is up to the |
+ | | are built using | authentication | plugin owner to |
+ | | the official | - Jenkins uses | maintain said |
+ | | install- | matrix auth | plugin |
+ | | plugins.sh | which allows | |
+ | | | users to manage | |
+ | | | "job" level ACL | |
+ | | | using Jenkins | |
+ | | | Job Builder | |
+ | | | - No API token | |
+ | | | enabled | |
+ | | | - Jenkins uses the | |
+ | | | inbuilt | |
+ | | | credential store | |
+ | | | where we store | |
+ | | | credentials for | |
+ | | | LAVA, Jenkins | |
+ | | | Job Builder, | |
+ | | | DockerHub, AWS | |
+ | | | and Gerrit | |
+ | | | tokens. The | |
+ | | | credentials are | |
+ | | | stored as a | |
+ | | | secret in | |
+ | | | Jenkins | |
+ | | | credential | |
+ | | | store. These | |
+ | | | credentials | |
+ | | | can be accessed | |
+ | | | via a Jenkins | |
+ | | | job, but someone | |
+ | | | would have to | |
+ | | | push a Jenkins | |
+ | | | Job through a | |
+ | | | Gerrit review to | |
+ | | | do this. Gerrit | |
+ | | | maintains the | |
+ | | | ACL for this and | |
+ | | | only admins and | |
+ | | | project approver | |
+ | | | can +2 a review. | |
+ +------------+--------------------+--------------------+--------------------+
+ | Gerrit | - Gerrit package | - Use oauth from | - Keep plugins up- |
+ | (including | is installed | Github only | to-date. But it |
+ | plugins) | from Linaro top | - The password | is up to the |
+ | | level role, | strength follows | plugin owner to |
+ | | which has a | Github policy | maintain said |
+ | | md5sum check | - Do not enforce | plugin |
+ | | - Gerrit Plugins | using two-factor | |
+ | | are installed | authentication | |
+ | | from Ansible | - Gerrit has ACL | |
+ | | playbook, from | setup within the | |
+ | | the official | UI per-project | |
+ | | Gerrit CI. The | level | |
+ | | plugins are | - No API token | |
+ | | downloaded from | enabled | |
+ | | https://gerrit- | - A ci-bot-user | |
+ | | ci.gerritforge. | created for | |
+ | | com/ | getting comments | |
+ | | - Do not check | from Jenkins | |
+ | | md5sum for every | | |
+ | | plugin | | |
+ +------------+--------------------+--------------------+--------------------+
+ | Git | - Package is from | - All credentials | - Monitor all |
+ | | Linaro OBS (Open | use GitHub. So | CVE's and apply |
+ | | Build Service) | password | them immediately |
+ | | with a couple of | strength etc are | and keep servers |
+ | | “Linaro | based on GitHub | up-to-date |
+ | | modifications”. | policy | monthly |
+ | | (reference: | | - The security |
+ | | Ansible playbook | | incident |
+ | | and cgit repo) | | response plan is |
+ | | - No special | | working in |
+ | | integrity check | | progress |
+ +------------+--------------------+--------------------+--------------------+
+ | Mailman | - Installed from | - It has | - Plan to monitor |
+ | | Ubuntu- | administrator | the CVE’s but no |
+ | | distributed | passwords for | timetable at the |
+ | | package | the various | moment |
+ | | - No special | mailing lists | |
+ | | integrity check | - The password | |
+ | | (reply on APT | strength is not | |
+ | | security) | specified | |
+ +------------+--------------------+--------------------+--------------------+
+ | Website | The website is | There are no | - The websites |
+ | | built on the IT | credentials | themselves are |
+ | | Services' CI/CD | associated with | static files |
+ | | server, | the website | hosted on AWS S3 |
+ | | bamboo.linaro.org, | itself. Any | and cached by |
+ | | from a Jekyll git | permissions | AWS CloudFront |
+ | | repository stored | required by bamboo | - The software |
+ | | on GitHub | to carry out its | used to build |
+ | | | tasks are provided | the website is |
+ | | | through AWS | all open source |
+ | | | instance role | and Linaro |
+ | | | permissions | occasionally |
+ | | | | gets reports |
+ | | | | from GitHub when |
+ | | | | an issue is |
+ | | | | detected. Apply |
+ | | | | a fix if it is |
+ | | | | available. This |
+ | | | | includes any |
+ | | | | Javascript |
+ | | | | frameworks that |
+ | | | | might be used |
+ | | | | within the web |
+ | | | | pages |
+ +------------+--------------------+--------------------+--------------------+
+ | ReadTheDocs| - One webhook ID | - One TF-A account | - Keep database |
+ | | per project is | with password | access list up |
+ | | used by TF CI | stored in | to date |
+ | | for building | engineering | - Monitor security |
+ | | documentation | password | advisories |
+ | | hosted by | database is used | |
+ | | ReadTheDocs | to manage | |
+ | | - Secret token | documentation | |
+ | | supplied as part | - Access request | |
+ | | of the webhook | is required | |
+ | | post build | for database | |
+ | | - Updated content | access | |
+ | | goes live | - Token for | |
+ | | automatically | Jenkins webhook | |
+ | | | for CI uses | |
+ | | | secret | |
+ | | | credential | |
+ | | | storage in | |
+ | | | internal Jenkins | |
+ | | | and viewable | |
+ | | | only through | |
+ | | | ReadTheDocs | |
+ | | | admin page | |
+ +------------+--------------------+--------------------+--------------------+
+
+References
+**********
+
+.. [1] https://git.kernel.org/pub/scm/utils/dtc/dtc.git
+.. [2] http://zlib.net/
+.. [3] https://compiler-rt.llvm.org/
+.. [4] https://tls.mbed.org/
+.. [5] https://www.openssl.org/
+.. [6] https://github.com/ARM-software/SCP-firmware
+.. [7] https://github.com/tianocore/edk2
+.. [8] https://downloads.trustedfirmware.org/tf-a/
+.. [9] https://docs.github.com/en/github/authenticating-to-github/creating-a-strong-password
+.. [10] https://trustedfirmware-a.readthedocs.io/en/latest/process/maintenance.html#how-to-become-a-maintainer
+.. [11] https://docs.github.com/en/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies
+.. [12] "Backstabber’s Knife Collection: A Review of Open Source Software Supply Chain Attacks"
+.. [13] https://www.wired.com/story/supply-chain-hackers-videogames-asus-ccleaner/
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. |TF-A System Diagram| image:: ../resources/diagrams/tf-a_system_diagram.png
+.. |TF-A Data Flow Diagram| image:: ../resources/diagrams/tf-a_data_flow_diagram.png
+.. |TF-A Attack Tree| image:: ../resources/diagrams/tf-a_attack_tree.png
diff --git a/drivers/cadence/nand/cdns_nand.c b/drivers/cadence/nand/cdns_nand.c
index 5a66262..20147d0 100644
--- a/drivers/cadence/nand/cdns_nand.c
+++ b/drivers/cadence/nand/cdns_nand.c
@@ -20,8 +20,12 @@
/* NAND flash device information struct */
static cnf_dev_info_t dev_info;
-/* Scratch buffers for read and write operations */
-static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+/*
+ * Scratch buffers for read and write operations
+ * DMA transfer of Cadence NAND expects data 8 bytes aligned
+ * to be written to register
+ */
+static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE] __aligned(8);
/* Wait for controller to be in idle state */
static inline void cdns_nand_wait_idle(void)
@@ -111,7 +115,8 @@
cdns_nand_wait_thread_ready(thread_id);
/* Select memory */
- mmio_write_32(CNF_CMDREG(CMD_REG4), (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+ mmio_write_32(CNF_CMDREG(CMD_REG4),
+ (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
/* Issue reset command */
uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
@@ -150,21 +155,19 @@
/* Async mode timing settings */
mmio_write_32(CNF_MINICTRL(ASYNC_TOGGLE_TIMINGS),
- (2 << CNF_ASYNC_TIMINGS_TRH) |
- (4 << CNF_ASYNC_TIMINGS_TRP) |
- (2 << CNF_ASYNC_TIMINGS_TWH) |
- (4 << CNF_ASYNC_TIMINGS_TWP));
+ (2 << CNF_ASYNC_TIMINGS_TRH) |
+ (4 << CNF_ASYNC_TIMINGS_TRP) |
+ (2 << CNF_ASYNC_TIMINGS_TWH) |
+ (4 << CNF_ASYNC_TIMINGS_TWP));
/* Set extended read and write mode */
reg |= (1 << CNF_DLL_PHY_EXT_RD_MODE);
reg |= (1 << CNF_DLL_PHY_EXT_WR_MODE);
/* Set operation work mode in common settings */
- uint32_t data = mmio_read_32(CNF_MINICTRL(CMN_SETTINGS));
-
- data |= (CNF_OPR_WORK_MODE_SDR << CNF_CMN_SETTINGS_OPR);
- mmio_write_32(CNF_MINICTRL(CMN_SETTINGS), data);
-
+ mmio_clrsetbits_32(CNF_MINICTRL(CMN_SETTINGS),
+ CNF_CMN_SETTINGS_OPR_MASK,
+ CNF_OPR_WORK_MODE_SDR);
} else if (opr_mode == CNF_OPR_WORK_MODE_NVDDR) {
; /* ToDo: add DDR mode settings also once available on SIMICS */
} else {
@@ -189,13 +192,13 @@
/* DMA burst select */
mmio_write_32(CNF_CTRLCFG(DMA_SETTINGS),
- (CNF_DMA_BURST_SIZE_MAX << CNF_DMA_SETTINGS_BURST) |
- (1 << CNF_DMA_SETTINGS_OTE));
+ (CNF_DMA_BURST_SIZE_MAX << CNF_DMA_SETTINGS_BURST) |
+ (1 << CNF_DMA_SETTINGS_OTE));
/* Enable pre-fetching for 1K */
mmio_write_32(CNF_CTRLCFG(FIFO_TLEVEL),
- (CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_POS) |
- (CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_DMA_SIZE));
+ (CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_POS) |
+ (CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_DMA_SIZE));
/* Select access type */
mmio_write_32(CNF_CTRLCFG(MULTIPLANE_CFG), 0);
@@ -235,12 +238,13 @@
/* Calculate block size and total device size */
dev_info.block_size = (dev_info.npages_per_block * dev_info.page_size);
- dev_info.total_size = (dev_info.block_size * dev_info.nblocks_per_lun *
- dev_info.nluns);
+ dev_info.total_size = ((unsigned long long)dev_info.block_size *
+ (unsigned long long)dev_info.nblocks_per_lun *
+ dev_info.nluns);
- VERBOSE("CNF params: page %d, spare %d, block %d, total %lld\n",
- dev_info.page_size, dev_info.spare_size,
- dev_info.block_size, dev_info.total_size);
+ VERBOSE("CNF params: page_size %d, spare_size %d, block_size %u, total_size %llu\n",
+ dev_info.page_size, dev_info.spare_size,
+ dev_info.block_size, dev_info.total_size);
return 0;
}
@@ -323,25 +327,44 @@
return 0;
}
+static uint32_t cdns_nand_get_row_address(uint32_t page, uint32_t block)
+{
+ uint32_t row_address = 0U;
+ uint32_t req_bits = 0U;
+
+ /* The device info is not populated yet. */
+ if (dev_info.npages_per_block == 0U)
+ return 0;
+
+ for (uint32_t i = 0U; i < sizeof(uint32_t) * 8; i++) {
+ if ((1U << i) & dev_info.npages_per_block)
+ req_bits = i;
+ }
+
+ row_address = ((page & GENMASK_32((req_bits - 1), 0)) |
+ (block << req_bits));
+
+ return row_address;
+}
+
/* NAND Flash page read */
static int cdns_nand_read_page(uint32_t block, uint32_t page, uintptr_t buffer)
{
+
/* Wait for thread to be ready */
cdns_nand_wait_thread_ready(CNF_DEF_TRD);
/* Select device */
mmio_write_32(CNF_CMDREG(CMD_REG4),
- (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+ (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
/* Set host memory address for DMA transfers */
- mmio_write_32(CNF_CMDREG(CMD_REG2), (buffer & 0xFFFF));
- mmio_write_32(CNF_CMDREG(CMD_REG3), ((buffer >> 32) & 0xFFFF));
+ mmio_write_32(CNF_CMDREG(CMD_REG2), (buffer & UINT32_MAX));
+ mmio_write_32(CNF_CMDREG(CMD_REG3), ((buffer >> 32) & UINT32_MAX));
/* Set row address */
- uint32_t row_address = 0U;
-
- row_address |= ((page & 0x3F) | (block << 6));
- mmio_write_32(CNF_CMDREG(CMD_REG1), row_address);
+ mmio_write_32(CNF_CMDREG(CMD_REG1),
+ cdns_nand_get_row_address(page, block));
/* Page read command */
uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
@@ -375,8 +398,8 @@
uint32_t page = 0U;
int result = 0;
- VERBOSE("CNF: block %u-%u, page_start %u, len %zu, offset %u\n",
- block, end_block, page_start, length, offset);
+ INFO("CNF: %s: block %u-%u, page_start %u, len %zu, offset %u\n",
+ __func__, block, end_block, page_start, length, offset);
if ((offset >= dev_info.total_size) ||
(offset + length-1 >= dev_info.total_size) ||
@@ -392,7 +415,7 @@
if ((start_offset != 0U) || (length < dev_info.page_size)) {
/* Partial page read */
result = cdns_nand_read_page(block, page,
- (uintptr_t)scratch_buff);
+ (uintptr_t)scratch_buff);
if (result != 0) {
return result;
}
diff --git a/drivers/st/bsec/bsec2.c b/drivers/st/bsec/bsec2.c
index 68d3a5b..a6e5220 100644
--- a/drivers/st/bsec/bsec2.c
+++ b/drivers/st/bsec/bsec2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,15 +21,26 @@
#define BSEC_IP_VERSION_2_0 U(0x20)
#define BSEC_IP_ID_2 U(0x100032)
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK GENMASK(4, 0)
+#define BSEC_OTP_BANK_SHIFT 5
+#define BSEC_TIMEOUT_VALUE U(0xFFFF)
+
#define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
-static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused;
+static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __maybe_unused;
+static uint32_t bsec_shadow_register(uint32_t otp);
static uint32_t bsec_power_safmem(bool power);
+static uint32_t bsec_get_version(void);
+static uint32_t bsec_get_id(void);
+static uint32_t bsec_get_status(void);
+static uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value);
/* BSEC access protection */
static spinlock_t bsec_spinlock;
-static uintptr_t bsec_base;
static void bsec_lock(void)
{
@@ -47,7 +58,7 @@
static bool is_otp_invalid_mode(void)
{
- bool ret = ((bsec_get_status() & BSEC_MODE_INVALID) == BSEC_MODE_INVALID);
+ bool ret = ((bsec_get_status() & BSEC_OTP_STATUS_INVALID) == BSEC_OTP_STATUS_INVALID);
if (ret) {
ERROR("OTP mode is OTP-INVALID\n");
@@ -163,7 +174,7 @@
panic();
}
- assert(bsec_base == bsec_info.base);
+ assert(bsec_info.base == BSEC_BASE);
bsec_dt_otp_nsec_access(fdt, node);
}
@@ -177,6 +188,11 @@
sizeof(uint32_t);
}
+static uint32_t otp_bit_mask(uint32_t otp)
+{
+ return BIT(otp & BSEC_OTP_MASK);
+}
+
/*
* bsec_check_error: check BSEC error status.
* otp: OTP number.
@@ -186,10 +202,10 @@
*/
static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed)
{
- uint32_t bit = BIT(otp & BSEC_OTP_MASK);
+ uint32_t bit = otp_bit_mask(otp);
uint32_t bank = otp_bank_offset(otp);
- if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) {
+ if ((mmio_read_32(BSEC_BASE + BSEC_ERROR_OFF + bank) & bit) != 0U) {
return BSEC_ERROR;
}
@@ -197,7 +213,7 @@
return BSEC_OK;
}
- if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
+ if ((mmio_read_32(BSEC_BASE + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
return BSEC_DISTURBED;
}
@@ -210,14 +226,12 @@
*/
uint32_t bsec_probe(void)
{
- bsec_base = BSEC_BASE;
-
if (is_otp_invalid_mode()) {
return BSEC_ERROR;
}
- if ((((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_1_1) &&
- ((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_2_0)) ||
+ if (((bsec_get_version() != BSEC_IP_VERSION_1_1) &&
+ (bsec_get_version() != BSEC_IP_VERSION_2_0)) ||
(bsec_get_id() != BSEC_IP_ID_2)) {
panic();
}
@@ -229,102 +243,11 @@
}
/*
- * bsec_get_base: return BSEC base address.
- */
-uint32_t bsec_get_base(void)
-{
- return bsec_base;
-}
-
-/*
- * bsec_set_config: enable and configure BSEC.
- * cfg: pointer to param structure used to set register.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_set_config(struct bsec_config *cfg)
-{
- uint32_t value;
- uint32_t result;
-
- if (is_otp_invalid_mode()) {
- return BSEC_ERROR;
- }
-
- value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) &
- BSEC_CONF_FRQ_MASK) |
- (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) &
- BSEC_CONF_PRG_WIDTH_MASK) |
- (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) &
- BSEC_CONF_TREAD_MASK));
-
- bsec_lock();
-
- mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value);
-
- bsec_unlock();
-
- result = bsec_power_safmem((bool)cfg->power &
- BSEC_CONF_POWER_UP_MASK);
- if (result != BSEC_OK) {
- return result;
- }
-
- value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) &
- UPPER_OTP_LOCK_MASK) |
- (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) &
- DENREG_LOCK_MASK) |
- (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) &
- GPLOCK_LOCK_MASK));
-
- bsec_lock();
-
- mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value);
-
- bsec_unlock();
-
- return BSEC_OK;
-}
-
-/*
- * bsec_get_config: return config parameters set in BSEC registers.
- * cfg: config param return.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_get_config(struct bsec_config *cfg)
-{
- uint32_t value;
-
- if (cfg == NULL) {
- return BSEC_INVALID_PARAM;
- }
-
- value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
- cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >>
- BSEC_CONF_POWER_UP_SHIFT);
- cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >>
- BSEC_CONF_FRQ_SHIFT);
- cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >>
- BSEC_CONF_PRG_WIDTH_SHIFT);
- cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >>
- BSEC_CONF_TREAD_SHIFT);
-
- value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF);
- cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >>
- UPPER_OTP_LOCK_SHIFT);
- cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >>
- DENREG_LOCK_SHIFT);
- cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >>
- GPLOCK_LOCK_SHIFT);
-
- return BSEC_OK;
-}
-
-/*
* bsec_shadow_register: copy SAFMEM OTP to BSEC data.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
-uint32_t bsec_shadow_register(uint32_t otp)
+static uint32_t bsec_shadow_register(uint32_t otp)
{
uint32_t result;
bool value;
@@ -345,7 +268,7 @@
otp);
}
- if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+ if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
result = bsec_power_safmem(true);
if (result != BSEC_OK) {
@@ -357,9 +280,9 @@
bsec_lock();
- mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
+ mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
- while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+ while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
;
}
@@ -392,7 +315,7 @@
return BSEC_INVALID_PARAM;
}
- *val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF +
+ *val = mmio_read_32(BSEC_BASE + BSEC_OTP_DATA_OFF +
(otp * sizeof(uint32_t)));
return BSEC_OK;
@@ -427,7 +350,7 @@
/* Ensure integrity of each register access sequence */
bsec_lock();
- mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF +
+ mmio_write_32(BSEC_BASE + BSEC_OTP_DATA_OFF +
(otp * sizeof(uint32_t)), val);
bsec_unlock();
@@ -470,12 +393,11 @@
return BSEC_PROG_FAIL;
}
- if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) &
- BIT(BSEC_LOCK_PROGRAM)) != 0U) {
+ if ((mmio_read_32(BSEC_BASE + BSEC_OTP_LOCK_OFF) & GPLOCK_LOCK_MASK) != 0U) {
WARN("BSEC: GPLOCK activated, prog will be ignored\n");
}
- if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+ if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
result = bsec_power_safmem(true);
if (result != BSEC_OK) {
@@ -487,15 +409,15 @@
bsec_lock();
- mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val);
+ mmio_write_32(BSEC_BASE + BSEC_OTP_WRDATA_OFF, val);
- mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
+ mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
- while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+ while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
;
}
- if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+ if ((bsec_get_status() & BSEC_OTP_STATUS_PROGFAIL) != 0U) {
result = BSEC_PROG_FAIL;
} else {
result = bsec_check_error(otp, true);
@@ -517,6 +439,7 @@
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
+#if defined(IMAGE_BL32)
uint32_t bsec_permanent_lock_otp(uint32_t otp)
{
uint32_t result;
@@ -532,7 +455,7 @@
return BSEC_INVALID_PARAM;
}
- if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+ if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
result = bsec_power_safmem(true);
if (result != BSEC_OK) {
@@ -554,16 +477,16 @@
bsec_lock();
- mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data);
+ mmio_write_32(BSEC_BASE + BSEC_OTP_WRDATA_OFF, data);
- mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF,
+ mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF,
addr | BSEC_WRITE | BSEC_LOCK);
- while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+ while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
;
}
- if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+ if ((bsec_get_status() & BSEC_OTP_STATUS_PROGFAIL) != 0U) {
result = BSEC_PROG_FAIL;
} else {
result = bsec_check_error(otp, false);
@@ -579,30 +502,14 @@
return result;
}
-
-/*
- * bsec_write_debug_conf: write value in debug feature.
- * to enable/disable debug service.
- * val: value to write.
- * return value: none.
- */
-void bsec_write_debug_conf(uint32_t val)
-{
- if (is_otp_invalid_mode()) {
- return;
- }
-
- bsec_lock();
- mmio_write_32(bsec_base + BSEC_DEN_OFF, val & BSEC_DEN_ALL_MSK);
- bsec_unlock();
-}
+#endif
/*
* bsec_read_debug_conf: return debug configuration register value.
*/
uint32_t bsec_read_debug_conf(void)
{
- return mmio_read_32(bsec_base + BSEC_DEN_OFF);
+ return mmio_read_32(BSEC_BASE + BSEC_DEN_OFF);
}
/*
@@ -618,7 +525,7 @@
}
bsec_lock();
- mmio_write_32(bsec_base + BSEC_SCRATCH_OFF, val);
+ mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val);
bsec_unlock();
#else
mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val);
@@ -626,54 +533,30 @@
}
/*
- * bsec_read_scratch: return scratch register value.
- */
-uint32_t bsec_read_scratch(void)
-{
- return mmio_read_32(bsec_base + BSEC_SCRATCH_OFF);
-}
-
-/*
* bsec_get_status: return status register value.
*/
-uint32_t bsec_get_status(void)
-{
- return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF);
-}
-
-/*
- * bsec_get_hw_conf: return hardware configuration register value.
- */
-uint32_t bsec_get_hw_conf(void)
+static uint32_t bsec_get_status(void)
{
- return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF);
+ return mmio_read_32(BSEC_BASE + BSEC_OTP_STATUS_OFF);
}
/*
* bsec_get_version: return BSEC version register value.
*/
-uint32_t bsec_get_version(void)
+static uint32_t bsec_get_version(void)
{
- return mmio_read_32(bsec_base + BSEC_IPVR_OFF);
+ return mmio_read_32(BSEC_BASE + BSEC_IPVR_OFF) & BSEC_IPVR_MSK;
}
/*
* bsec_get_id: return BSEC ID register value.
*/
-uint32_t bsec_get_id(void)
+static uint32_t bsec_get_id(void)
{
- return mmio_read_32(bsec_base + BSEC_IP_ID_OFF);
+ return mmio_read_32(BSEC_BASE + BSEC_IP_ID_OFF);
}
/*
- * bsec_get_magic_id: return BSEC magic number register value.
- */
-uint32_t bsec_get_magic_id(void)
-{
- return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF);
-}
-
-/*
* bsec_set_sr_lock: set shadow-read lock.
* otp: OTP number.
* return value: BSEC_OK if no error.
@@ -681,7 +564,7 @@
uint32_t bsec_set_sr_lock(uint32_t otp)
{
uint32_t bank = otp_bank_offset(otp);
- uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t otp_mask = otp_bit_mask(otp);
if (is_otp_invalid_mode()) {
return BSEC_ERROR;
@@ -692,7 +575,7 @@
}
bsec_lock();
- mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, otp_mask);
+ mmio_write_32(BSEC_BASE + BSEC_SRLOCK_OFF + bank, otp_mask);
bsec_unlock();
return BSEC_OK;
@@ -707,14 +590,14 @@
uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
{
uint32_t bank = otp_bank_offset(otp);
- uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t otp_mask = otp_bit_mask(otp);
uint32_t bank_value;
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
- bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+ bank_value = mmio_read_32(BSEC_BASE + BSEC_SRLOCK_OFF + bank);
*value = ((bank_value & otp_mask) != 0U);
@@ -729,7 +612,7 @@
uint32_t bsec_set_sw_lock(uint32_t otp)
{
uint32_t bank = otp_bank_offset(otp);
- uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t otp_mask = otp_bit_mask(otp);
if (is_otp_invalid_mode()) {
return BSEC_ERROR;
@@ -740,7 +623,7 @@
}
bsec_lock();
- mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, otp_mask);
+ mmio_write_32(BSEC_BASE + BSEC_SWLOCK_OFF + bank, otp_mask);
bsec_unlock();
return BSEC_OK;
@@ -762,7 +645,7 @@
return BSEC_INVALID_PARAM;
}
- bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+ bank_value = mmio_read_32(BSEC_BASE + BSEC_SWLOCK_OFF + bank);
*value = ((bank_value & otp_mask) != 0U);
@@ -777,7 +660,7 @@
uint32_t bsec_set_sp_lock(uint32_t otp)
{
uint32_t bank = otp_bank_offset(otp);
- uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t otp_mask = otp_bit_mask(otp);
if (is_otp_invalid_mode()) {
return BSEC_ERROR;
@@ -788,7 +671,7 @@
}
bsec_lock();
- mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, otp_mask);
+ mmio_write_32(BSEC_BASE + BSEC_SPLOCK_OFF + bank, otp_mask);
bsec_unlock();
return BSEC_OK;
@@ -810,7 +693,7 @@
return BSEC_INVALID_PARAM;
}
- bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+ bank_value = mmio_read_32(BSEC_BASE + BSEC_SPLOCK_OFF + bank);
*value = ((bank_value & otp_mask) != 0U);
@@ -823,17 +706,17 @@
* value: read value (true or false).
* return value: BSEC_OK if no error.
*/
-uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value)
+static uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value)
{
uint32_t bank = otp_bank_offset(otp);
- uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t otp_mask = otp_bit_mask(otp);
uint32_t bank_value;
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
- bank_value = mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank);
+ bank_value = mmio_read_32(BSEC_BASE + BSEC_WRLOCK_OFF + bank);
*value = ((bank_value & otp_mask) != 0U);
@@ -841,36 +724,6 @@
}
/*
- * bsec_otp_lock: Lock Upper OTP or Global Programming or Debug Enable.
- * service: Service to lock, see header file.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_otp_lock(uint32_t service)
-{
- uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF;
-
- if (is_otp_invalid_mode()) {
- return BSEC_ERROR;
- }
-
- switch (service) {
- case BSEC_LOCK_UPPER_OTP:
- mmio_write_32(reg, BIT(BSEC_LOCK_UPPER_OTP));
- break;
- case BSEC_LOCK_DEBUG:
- mmio_write_32(reg, BIT(BSEC_LOCK_DEBUG));
- break;
- case BSEC_LOCK_PROGRAM:
- mmio_write_32(reg, BIT(BSEC_LOCK_PROGRAM));
- break;
- default:
- return BSEC_INVALID_PARAM;
- }
-
- return BSEC_OK;
-}
-
-/*
* bsec_power_safmem: Activate or deactivate SAFMEM power.
* power: true to power up, false to power down.
* return value: BSEC_OK if no error.
@@ -882,7 +735,7 @@
bsec_lock();
- register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+ register_val = mmio_read_32(BSEC_BASE + BSEC_OTP_CONF_OFF);
if (power) {
register_val |= BSEC_CONF_POWER_UP_MASK;
@@ -890,15 +743,15 @@
register_val &= ~BSEC_CONF_POWER_UP_MASK;
}
- mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val);
+ mmio_write_32(BSEC_BASE + BSEC_OTP_CONF_OFF, register_val);
if (power) {
- while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) &&
+ while (((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) &&
(timeout != 0U)) {
timeout--;
}
} else {
- while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) &&
+ while (((bsec_get_status() & BSEC_OTP_STATUS_PWRON) != 0U) &&
(timeout != 0U)) {
timeout--;
}
@@ -915,28 +768,29 @@
/*
* bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value.
- * otp_value: read value.
- * word: OTP number.
+ * val: read value.
+ * otp: OTP number.
* return value: BSEC_OK if no error.
*/
-uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp)
{
uint32_t result;
- result = bsec_shadow_register(word);
+ result = bsec_shadow_register(otp);
if (result != BSEC_OK) {
- ERROR("BSEC: %u Shadowing Error %u\n", word, result);
+ ERROR("BSEC: %u Shadowing Error %u\n", otp, result);
return result;
}
- result = bsec_read_otp(otp_value, word);
+ result = bsec_read_otp(val, otp);
if (result != BSEC_OK) {
- ERROR("BSEC: %u Read Error %u\n", word, result);
+ ERROR("BSEC: %u Read Error %u\n", otp, result);
}
return result;
}
+#if defined(IMAGE_BL32)
/*
* bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
* otp: OTP number.
@@ -944,7 +798,6 @@
*/
uint32_t bsec_check_nsec_access_rights(uint32_t otp)
{
-#if defined(IMAGE_BL32)
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
@@ -954,8 +807,33 @@
return BSEC_ERROR;
}
}
-#endif
return BSEC_OK;
}
+#endif
+
+uint32_t bsec_get_secure_state(void)
+{
+ uint32_t status = bsec_get_status();
+ uint32_t result = BSEC_STATE_INVALID;
+ uint32_t otp_enc_id __maybe_unused;
+ uint32_t otp_bit_len __maybe_unused;
+ int res __maybe_unused;
+ if ((status & BSEC_OTP_STATUS_INVALID) != 0U) {
+ result = BSEC_STATE_INVALID;
+ } else {
+ if ((status & BSEC_OTP_STATUS_SECURE) != 0U) {
+ if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
+ result = BSEC_STATE_SEC_CLOSED;
+ } else {
+ result = BSEC_STATE_SEC_OPEN;
+ }
+ } else {
+ /* OTP modes OPEN1 and OPEN2 are not supported */
+ result = BSEC_STATE_INVALID;
+ }
+ }
+
+ return result;
+}
diff --git a/fdts/cca_cot_descriptors.dtsi b/fdts/cca_cot_descriptors.dtsi
new file mode 100644
index 0000000..d52431b
--- /dev/null
+++ b/fdts/cca_cot_descriptors.dtsi
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <tools_share/cca_oid.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
+
+cot {
+ manifests {
+ compatible = "arm, cert-descs";
+
+ cca_content_cert: cca_content_cert {
+ root-certificate;
+ image-id =<CCA_CONTENT_CERT_ID>;
+ antirollback-counter = <&cca_nv_counter>;
+
+ tb_fw_hash: tb_fw_hash {
+ oid = TRUSTED_BOOT_FW_HASH_OID;
+ };
+ tb_fw_config_hash: tb_fw_config_hash {
+ oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID;
+ };
+ hw_config_hash: hw_config_hash {
+ oid = HW_CONFIG_HASH_OID;
+ };
+ fw_config_hash: fw_config_hash {
+ oid = FW_CONFIG_HASH_OID;
+ };
+ soc_fw_hash: soc_fw_hash {
+ oid = SOC_AP_FW_HASH_OID;
+ };
+ soc_fw_config_hash: soc_fw_config_hash {
+ oid = SOC_FW_CONFIG_HASH_OID;
+ };
+ rmm_hash: rmm_hash {
+ oid = RMM_HASH_OID;
+ };
+ };
+
+ core_swd_key_cert: core_swd_key_cert {
+ root-certificate;
+ image-id = <CORE_SWD_KEY_CERT_ID>;
+ signing-key = <&swd_rot_pk>;
+ antirollback-counter = <&trusted_nv_counter>;
+
+ core_swd_pk: core_swd_pk {
+ oid = CORE_SWD_PK_OID;
+ };
+ };
+
+ trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+ image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+ parent = <&core_swd_key_cert>;
+ signing-key = <&core_swd_pk>;
+ antirollback-counter = <&trusted_nv_counter>;
+
+ tos_fw_hash: tos_fw_hash {
+ oid = TRUSTED_OS_FW_HASH_OID;
+ };
+ tos_fw_config_hash: tos_fw_config_hash {
+ oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+ };
+ };
+
+ plat_key_cert: plat_key_cert {
+ root-certificate;
+ image-id = <PLAT_KEY_CERT_ID>;
+ signing-key = <&prot_pk>;
+ antirollback-counter = <&non_trusted_nv_counter>;
+
+ plat_pk: plat_pk {
+ oid = PLAT_PK_OID;
+ };
+ };
+
+ non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+ image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+ parent = <&plat_key_cert>;
+ signing-key = <&plat_pk>;
+ antirollback-counter = <&non_trusted_nv_counter>;
+
+ nt_world_bl_hash: nt_world_bl_hash {
+ oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
+ };
+ nt_fw_config_hash: nt_fw_config_hash {
+ oid = NON_TRUSTED_FW_CONFIG_HASH_OID;
+ };
+ };
+
+#if defined(SPD_spmd)
+ sip_sp_content_cert: sip_sp_content_cert {
+ image-id = <SIP_SP_CONTENT_CERT_ID>;
+ parent = <&core_swd_key_cert>;
+ signing-key = <&core_swd_pk>;
+ antirollback-counter = <&trusted_nv_counter>;
+
+ sp_pkg1_hash: sp_pkg1_hash {
+ oid = SP_PKG1_HASH_OID;
+ };
+ sp_pkg2_hash: sp_pkg2_hash {
+ oid = SP_PKG2_HASH_OID;
+ };
+ sp_pkg3_hash: sp_pkg3_hash {
+ oid = SP_PKG3_HASH_OID;
+ };
+ sp_pkg4_hash: sp_pkg4_hash {
+ oid = SP_PKG4_HASH_OID;
+ };
+ };
+
+ plat_sp_content_cert: plat_sp_content_cert {
+ image-id = <PLAT_SP_CONTENT_CERT_ID>;
+ parent = <&plat_key_cert>;
+ signing-key = <&plat_pk>;
+ antirollback-counter = <&non_trusted_nv_counter>;
+
+ sp_pkg5_hash: sp_pkg5_hash {
+ oid = SP_PKG5_HASH_OID;
+ };
+ sp_pkg6_hash: sp_pkg6_hash {
+ oid = SP_PKG6_HASH_OID;
+ };
+ sp_pkg7_hash: sp_pkg7_hash {
+ oid = SP_PKG7_HASH_OID;
+ };
+ sp_pkg8_hash: sp_pkg8_hash {
+ oid = SP_PKG8_HASH_OID;
+ };
+ };
+#endif
+ };
+
+ images {
+ compatible = "arm, img-descs";
+
+ fw_config {
+ image-id = <FW_CONFIG_ID>;
+ parent = <&cca_content_cert>;
+ hash = <&fw_config_hash>;
+ };
+
+ hw_config {
+ image-id = <HW_CONFIG_ID>;
+ parent = <&cca_content_cert>;
+ hash = <&hw_config_hash>;
+ };
+
+ tb_fw_hash {
+ image-id = <BL2_IMAGE_ID>;
+ parent = <&cca_content_cert>;
+ hash = <&tb_fw_hash>;
+ };
+
+ tb_fw_config {
+ image-id = <TB_FW_CONFIG_ID>;
+ parent = <&cca_content_cert>;
+ hash = <&tb_fw_config_hash>;
+ };
+
+ bl31_image {
+ image-id = <BL31_IMAGE_ID>;
+ parent = <&cca_content_cert>;
+ hash = <&soc_fw_hash>;
+ };
+
+ soc_fw_config {
+ image-id = <SOC_FW_CONFIG_ID>;
+ parent = <&cca_content_cert>;
+ hash = <&soc_fw_config_hash>;
+ };
+
+ rmm_image {
+ image-id = <RMM_IMAGE_ID>;
+ parent = <&cca_content_cert>;
+ hash = <&rmm_hash>;
+ };
+
+ bl32_image {
+ image-id = <BL32_IMAGE_ID>;
+ parent = <&trusted_os_fw_content_cert>;
+ hash = <&tos_fw_hash>;
+ };
+
+ tos_fw_config {
+ image-id = <TOS_FW_CONFIG_ID>;
+ parent = <&trusted_os_fw_content_cert>;
+ hash = <&tos_fw_config_hash>;
+ };
+
+ bl33_image {
+ image-id = <BL33_IMAGE_ID>;
+ parent = <&non_trusted_fw_content_cert>;
+ hash = <&nt_world_bl_hash>;
+ };
+
+ nt_fw_config {
+ image-id = <NT_FW_CONFIG_ID>;
+ parent = <&non_trusted_fw_content_cert>;
+ hash = <&nt_fw_config_hash>;
+ };
+
+#if defined(SPD_spmd)
+ sp_pkg1 {
+ image-id = <SP_PKG1_ID>;
+ parent = <&sip_sp_content_cert>;
+ hash = <&sp_pkg1_hash>;
+ };
+
+ sp_pkg2 {
+ image-id = <SP_PKG2_ID>;
+ parent = <&sip_sp_content_cert>;
+ hash = <&sp_pkg2_hash>;
+ };
+
+ sp_pkg3 {
+ image-id = <SP_PKG3_ID>;
+ parent = <&sip_sp_content_cert>;
+ hash = <&sp_pkg3_hash>;
+ };
+
+ sp_pkg4 {
+ image-id = <SP_PKG4_ID>;
+ parent = <&sip_sp_content_cert>;
+ hash = <&sp_pkg4_hash>;
+ };
+
+ sp_pkg5 {
+ image-id = <SP_PKG5_ID>;
+ parent = <&plat_sp_content_cert>;
+ hash = <&sp_pkg5_hash>;
+ };
+
+ sp_pkg6 {
+ image-id = <SP_PKG6_ID>;
+ parent = <&plat_sp_content_cert>;
+ hash = <&sp_pkg6_hash>;
+ };
+
+ sp_pkg7 {
+ image-id = <SP_PKG7_ID>;
+ parent = <&plat_sp_content_cert>;
+ hash = <&sp_pkg7_hash>;
+ };
+
+ sp_pkg8 {
+ image-id = <SP_PKG8_ID>;
+ parent = <&plat_sp_content_cert>;
+ hash = <&sp_pkg8_hash>;
+ };
+#endif
+ };
+};
+
+non_volatile_counters: non_volatile_counters {
+ compatible = "arm, non-volatile-counter";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cca_nv_counter: cca_nv_counter {
+ id = <TRUSTED_NV_CTR_ID>;
+ oid = CCA_FW_NVCOUNTER_OID;
+ };
+
+ trusted_nv_counter: trusted_nv_counter {
+ id = <TRUSTED_NV_CTR_ID>;
+ oid = TRUSTED_FW_NVCOUNTER_OID;
+ };
+
+ non_trusted_nv_counter: non_trusted_nv_counter {
+ id = <NON_TRUSTED_NV_CTR_ID>;
+ oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+ };
+};
+
+rot_keys {
+ swd_rot_pk: swd_rot_pk {
+ oid = SWD_ROT_PK_OID;
+ };
+
+ prot_pk: prot_pk {
+ oid = PROT_PK_OID;
+ };
+};
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
index 8bcf363..520d90b 100644
--- a/fdts/stm32mp131.dtsi
+++ b/fdts/stm32mp131.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
#include <dt-bindings/clock/stm32mp13-clks.h>
@@ -420,25 +420,25 @@
#address-cells = <1>;
#size-cells = <1>;
- cfg0_otp: cfg0_otp@0 {
+ cfg0_otp: cfg0-otp@0 {
reg = <0x0 0x2>;
};
part_number_otp: part-number-otp@4 {
reg = <0x4 0x2>;
};
- monotonic_otp: monotonic_otp@10 {
+ monotonic_otp: monotonic-otp@10 {
reg = <0x10 0x4>;
};
- nand_otp: cfg9_otp@24 {
+ nand_otp: cfg9-otp@24 {
reg = <0x24 0x4>;
};
- nand2_otp: cfg10_otp@28 {
+ nand2_otp: cfg10-otp@28 {
reg = <0x28 0x4>;
};
- uid_otp: uid_otp@34 {
+ uid_otp: uid-otp@34 {
reg = <0x34 0xc>;
};
- hw2_otp: hw2_otp@48 {
+ hw2_otp: hw2-otp@48 {
reg = <0x48 0x4>;
};
ts_cal1: calib@5c {
@@ -447,14 +447,14 @@
ts_cal2: calib@5e {
reg = <0x5e 0x2>;
};
- pkh_otp: pkh_otp@60 {
+ pkh_otp: pkh-otp@60 {
reg = <0x60 0x20>;
};
- mac_addr: mac_addr@e4 {
+ mac_addr: mac@e4 {
reg = <0xe4 0xc>;
st,non-secure-otp;
};
- enckey_otp: enckey_otp@170 {
+ oem_enc_key: oem-enc-key@170 {
reg = <0x170 0x10>;
};
};
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index 1204692..7a7d461 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
@@ -50,7 +50,7 @@
};
&bsec {
- board_id: board_id@f0 {
+ board_id: board-id@f0 {
reg = <0xf0 0x4>;
st,non-secure-otp;
};
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index 7a22a1c..449ddbb 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -458,25 +458,25 @@
#address-cells = <1>;
#size-cells = <1>;
- cfg0_otp: cfg0_otp@0 {
+ cfg0_otp: cfg0-otp@0 {
reg = <0x0 0x1>;
};
part_number_otp: part-number-otp@4 {
reg = <0x4 0x1>;
};
- monotonic_otp: monotonic_otp@10 {
+ monotonic_otp: monotonic-otp@10 {
reg = <0x10 0x4>;
};
- nand_otp: nand_otp@24 {
+ nand_otp: nand-otp@24 {
reg = <0x24 0x4>;
};
- uid_otp: uid_otp@34 {
+ uid_otp: uid-otp@34 {
reg = <0x34 0xc>;
};
- package_otp: package_otp@40 {
+ package_otp: package-otp@40 {
reg = <0x40 0x4>;
};
- hw2_otp: hw2_otp@48 {
+ hw2_otp: hw2-otp@48 {
reg = <0x48 0x4>;
};
ts_cal1: calib@5c {
@@ -485,10 +485,10 @@
ts_cal2: calib@5e {
reg = <0x5e 0x2>;
};
- pkh_otp: pkh_otp@60 {
+ pkh_otp: pkh-otp@60 {
reg = <0x60 0x20>;
};
- mac_addr: mac_addr@e4 {
+ ethernet_mac_address: mac@e4 {
reg = <0xe4 0x8>;
st,non-secure-otp;
};
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index 949c929..d7bcc84 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
/dts-v1/;
@@ -31,7 +31,7 @@
};
&bsec {
- board_id: board_id@ec {
+ board_id: board-id@ec {
reg = <0xec 0x4>;
st,non-secure-otp;
};
diff --git a/fdts/stm32mp157c-odyssey-som.dtsi b/fdts/stm32mp157c-odyssey-som.dtsi
index 091e327..a0be718 100644
--- a/fdts/stm32mp157c-odyssey-som.dtsi
+++ b/fdts/stm32mp157c-odyssey-som.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019, STMicroelectronics. All Rights Reserved.
+ * Copyright (C) 2019-2024, STMicroelectronics. All Rights Reserved.
* Copyright (C) 2021, Grzegorz Szymaszek.
*
* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
@@ -28,7 +28,7 @@
};
&bsec {
- board_id: board_id@ec {
+ board_id: board-id@ec {
reg = <0xec 0x4>;
st,non-secure-otp;
};
diff --git a/fdts/stm32mp15xx-dhcom-som.dtsi b/fdts/stm32mp15xx-dhcom-som.dtsi
index 7737a44..5138868 100644
--- a/fdts/stm32mp15xx-dhcom-som.dtsi
+++ b/fdts/stm32mp15xx-dhcom-som.dtsi
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
* Copyright (C) 2022 DH electronics GmbH
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
*/
#include "stm32mp15-pinctrl.dtsi"
@@ -18,7 +18,7 @@
};
&bsec {
- board_id: board_id@ec {
+ board_id: board-id@ec {
reg = <0xec 0x4>;
st,non-secure-otp;
};
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index f8baa9d..d8b7c48 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2024, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
*/
@@ -29,7 +29,7 @@
};
&bsec {
- board_id: board_id@ec {
+ board_id: board-id@ec {
reg = <0xec 0x4>;
st,non-secure-otp;
};
diff --git a/fdts/stm32mp15xx-osd32.dtsi b/fdts/stm32mp15xx-osd32.dtsi
index 52a5d38..ef4c3c0 100644
--- a/fdts/stm32mp15xx-osd32.dtsi
+++ b/fdts/stm32mp15xx-osd32.dtsi
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) */
/*
- * Copyright (C) 2020 STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2020-2024 STMicroelectronics - All Rights Reserved
* Copyright (C) 2020 Ahmad Fatoum, Pengutronix
*/
@@ -157,7 +157,7 @@
};
&bsec {
- board_id: board_id@ec {
+ board_id: board-id@ec {
reg = <0xec 0x4>;
st,non-secure-otp;
};
diff --git a/fdts/stm32mp251.dtsi b/fdts/stm32mp251.dtsi
index f55a3b9..6e262bb 100644
--- a/fdts/stm32mp251.dtsi
+++ b/fdts/stm32mp251.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
/*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
@@ -99,6 +99,41 @@
};
};
+ bsec: efuse@44000000 {
+ compatible = "st,stm32mp25-bsec";
+ reg = <0x44000000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uid_otp: uid-otp@14 {
+ reg = <0x14 0xc>;
+ };
+ part_number_otp: part-number-otp@24 {
+ reg = <0x24 0x4>;
+ };
+ nand_otp: otp16@40 {
+ reg = <0x40 0x4>;
+ };
+ lifecycle2_otp: otp18@48 {
+ reg = <0x48 0x4>;
+ };
+ nand2_otp: otp20@50 {
+ reg = <0x50 0x4>;
+ };
+ package_otp: package-otp@1e8 {
+ reg = <0x1e8 0x1>;
+ };
+ hconf1_otp: otp124@1f0 {
+ reg = <0x1f0 0x4>;
+ };
+ pkh_otp: otp144@240 {
+ reg = <0x240 0x20>;
+ };
+ oem_fip_enc_key: otp260@410 {
+ reg = <0x410 0x20>;
+ };
+ };
+
rcc: rcc@44200000 {
compatible = "st,stm32mp25-rcc";
reg = <0x44200000 0x10000>;
diff --git a/fdts/stm32mp257f-ev1.dts b/fdts/stm32mp257f-ev1.dts
index b7e92e4..09e83d8 100644
--- a/fdts/stm32mp257f-ev1.dts
+++ b/fdts/stm32mp257f-ev1.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
/*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
@@ -29,6 +29,12 @@
};
};
+&bsec {
+ board_id: board-id@3d8 {
+ reg = <0x3d8 0x4>;
+ };
+};
+
&usart2 {
pinctrl-names = "default";
pinctrl-0 = <&usart2_pins_a>;
diff --git a/fdts/cot_descriptors.dtsi b/fdts/tbbr_cot_descriptors.dtsi
similarity index 99%
rename from fdts/cot_descriptors.dtsi
rename to fdts/tbbr_cot_descriptors.dtsi
index 411bae6..ac39e4e 100644
--- a/fdts/cot_descriptors.dtsi
+++ b/fdts/tbbr_cot_descriptors.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index f19c4c2..acc1751 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -147,6 +147,7 @@
static inline bool is_feat_spe_supported(void) { return false; }
static inline bool is_feat_rng_supported(void) { return false; }
static inline bool is_feat_gcs_supported(void) { return false; }
+static inline bool is_feat_mte_supported(void) { return false; }
static inline bool is_feat_mpam_supported(void) { return false; }
static inline bool is_feat_hcx_supported(void) { return false; }
static inline bool is_feat_sve_supported(void) { return false; }
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index cf8da5e..deea6d4 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -89,12 +89,8 @@
ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
}
-static inline unsigned int get_armv8_5_mte_support(void)
-{
- return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
- ID_AA64PFR1_EL1_MTE_MASK);
-}
-
+CREATE_FEATURE_FUNCS(feat_mte, id_aa64pfr1_el1, ID_AA64PFR1_EL1_MTE_SHIFT,
+ ENABLE_FEAT_MTE)
CREATE_FEATURE_FUNCS(feat_sel2, id_aa64pfr0_el1, ID_AA64PFR0_SEL2_SHIFT,
ENABLE_FEAT_SEL2)
CREATE_FEATURE_FUNCS(feat_twed, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_TWED_SHIFT,
diff --git a/include/drivers/cadence/cdns_nand.h b/include/drivers/cadence/cdns_nand.h
index 64ba267..f20627b 100644
--- a/include/drivers/cadence/cdns_nand.h
+++ b/include/drivers/cadence/cdns_nand.h
@@ -198,6 +198,7 @@
#define CNF_OPR_WORK_MODE_RES 3
/* Mini controller common settings register field offsets */
+#define CNF_CMN_SETTINGS_OPR_MASK 0x00000003
#define CNF_CMN_SETTINGS_WR_WUP 20
#define CNF_CMN_SETTINGS_RD_WUP 16
#define CNF_CMN_SETTINGS_DEV16 8
diff --git a/include/drivers/st/bsec.h b/include/drivers/st/bsec.h
index 60dcf3c..4a1517a 100644
--- a/include/drivers/st/bsec.h
+++ b/include/drivers/st/bsec.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,13 +13,6 @@
#include <lib/utils_def.h>
/*
- * IP configuration
- */
-#define BSEC_OTP_MASK GENMASK(4, 0)
-#define BSEC_OTP_BANK_SHIFT 5
-#define BSEC_TIMEOUT_VALUE 0xFFFF
-
-/*
* Return status
*/
#define BSEC_OK 0U
@@ -32,98 +25,49 @@
#define BSEC_RETRY 0xFFFFFFF8U
#define BSEC_NOT_SUPPORTED 0xFFFFFFF7U
#define BSEC_WRITE_LOCKED 0xFFFFFFF6U
-#define BSEC_ERROR_INVALID_FVR 0xFFFFFFF5U
-
-/*
- * OTP MODE
- */
-#define BSEC_MODE_OPEN1 0x00U
-#define BSEC_MODE_SECURED 0x01U
-#define BSEC_MODE_OPEN2 0x02U
-#define BSEC_MODE_INVALID 0x04U
-
-/*
- * OTP Lock services definition.
- * Value must corresponding to the bit number in the register.
- * Special case: (bit number << 1) for BSEC3.
- */
-#define BSEC_LOCK_UPPER_OTP 0x00
-#define BSEC_LOCK_GWLOCK 0x01
-#define BSEC_LOCK_DEBUG 0x02
-#define BSEC_LOCK_PROGRAM 0x03
-#define BSEC_LOCK_KVLOCK 0x04
/*
- * Values for struct bsec_config::freq
+ * get BSEC global state: result for bsec_get_secure_state()
+ * @state: global state
+ * [1:0] BSEC state
+ * 00b: Sec Open
+ * 01b: Sec Closed
+ * 11b: Invalid
+ * [8]: Hardware Key set = 1b
*/
-#define FREQ_10_20_MHZ 0x0
-#define FREQ_20_30_MHZ 0x1
-#define FREQ_30_45_MHZ 0x2
-#define FREQ_45_67_MHZ 0x3
-
-/*
- * Device info structure, providing device-specific functions and a means of
- * adding driver-specific state.
- */
-struct bsec_config {
- uint8_t den_lock; /*
- * Debug enable sticky lock
- * 1 debug enable is locked until next reset
- */
-
- /* BSEC2 only */
- uint8_t tread; /* SAFMEM Reading current level default 0 */
- uint8_t pulse_width; /* SAFMEM Programming pulse width default 1 */
- uint8_t freq; /*
- * SAFMEM CLOCK see freq value define
- * default FREQ_45_67_MHZ
- */
- uint8_t power; /* Power up SAFMEM. 1 power up, 0 power off */
- uint8_t prog_lock; /*
- * Programming Sticky lock
- * 1 programming is locked until next reset
- */
- uint8_t upper_otp_lock; /*
- * Shadowing of upper OTP sticky lock
- * 1 shadowing of upper OTP is locked
- * until next reset
- */
-};
+#define BSEC_STATE_SEC_OPEN U(0x0)
+#define BSEC_STATE_SEC_CLOSED U(0x1)
+#define BSEC_STATE_INVALID U(0x3)
+#define BSEC_STATE_MASK GENMASK_32(1, 0)
uint32_t bsec_probe(void);
-uint32_t bsec_get_base(void);
-uint32_t bsec_set_config(struct bsec_config *cfg);
-uint32_t bsec_get_config(struct bsec_config *cfg);
-
-uint32_t bsec_shadow_register(uint32_t otp);
uint32_t bsec_read_otp(uint32_t *val, uint32_t otp);
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp);
uint32_t bsec_write_otp(uint32_t val, uint32_t otp);
uint32_t bsec_program_otp(uint32_t val, uint32_t otp);
-uint32_t bsec_permanent_lock_otp(uint32_t otp);
-void bsec_write_debug_conf(uint32_t val);
uint32_t bsec_read_debug_conf(void);
void bsec_write_scratch(uint32_t val);
-uint32_t bsec_read_scratch(void);
-
-uint32_t bsec_get_status(void);
-uint32_t bsec_get_hw_conf(void);
-uint32_t bsec_get_version(void);
-uint32_t bsec_get_id(void);
-uint32_t bsec_get_magic_id(void);
+/* Sticky lock support */
uint32_t bsec_set_sr_lock(uint32_t otp);
uint32_t bsec_read_sr_lock(uint32_t otp, bool *value);
uint32_t bsec_set_sw_lock(uint32_t otp);
uint32_t bsec_read_sw_lock(uint32_t otp, bool *value);
uint32_t bsec_set_sp_lock(uint32_t otp);
uint32_t bsec_read_sp_lock(uint32_t otp, bool *value);
-uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value);
-uint32_t bsec_otp_lock(uint32_t service);
-uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word);
+uint32_t bsec_get_secure_state(void);
+static inline bool bsec_mode_is_closed_device(void)
+{
+ return (bsec_get_secure_state() & BSEC_STATE_MASK) == BSEC_STATE_SEC_CLOSED;
+}
+
+#if defined(IMAGE_BL32)
+uint32_t bsec_permanent_lock_otp(uint32_t otp);
uint32_t bsec_check_nsec_access_rights(uint32_t otp);
+#endif
#endif /* BSEC_H */
diff --git a/include/drivers/st/bsec2_reg.h b/include/drivers/st/bsec2_reg.h
index f895020..fa44cf1 100644
--- a/include/drivers/st/bsec2_reg.h
+++ b/include/drivers/st/bsec2_reg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -80,22 +80,17 @@
#define GPLOCK_LOCK_SHIFT 4
/* BSEC_OTP_STATUS Register */
-#define BSEC_MODE_STATUS_MASK GENMASK(2, 0)
-#define BSEC_MODE_SECURE_MASK BIT(0)
-#define BSEC_MODE_FULLDBG_MASK BIT(1)
-#define BSEC_MODE_INVALID_MASK BIT(2)
-#define BSEC_MODE_BUSY_MASK BIT(3)
-#define BSEC_MODE_PROGFAIL_MASK BIT(4)
-#define BSEC_MODE_PWR_MASK BIT(5)
-#define BSEC_MODE_BIST1_LOCK_MASK BIT(6)
-#define BSEC_MODE_BIST2_LOCK_MASK BIT(7)
+#define BSEC_OTP_STATUS_SECURE BIT(0)
+#define BSEC_OTP_STATUS_INVALID BIT(2)
+#define BSEC_OTP_STATUS_BUSY BIT(3)
+#define BSEC_OTP_STATUS_PROGFAIL BIT(4)
+#define BSEC_OTP_STATUS_PWRON BIT(5)
/* BSEC_DENABLE Register */
#define BSEC_HDPEN BIT(4)
#define BSEC_SPIDEN BIT(5)
#define BSEC_SPINDEN BIT(6)
#define BSEC_DBGSWGEN BIT(10)
-#define BSEC_DEN_ALL_MSK GENMASK(10, 0)
/* BSEC_FENABLE Register */
#define BSEC_FEN_ALL_MSK GENMASK(14, 0)
diff --git a/include/lib/cpus/aarch64/cortex_x3.h b/include/lib/cpus/aarch64/cortex_x3.h
index 4a3ac77..5429078 100644
--- a/include/lib/cpus/aarch64/cortex_x3.h
+++ b/include/lib/cpus/aarch64/cortex_x3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,6 +26,11 @@
#define CORTEX_X3_CPUPWRCTLR_EL1_WFE_RET_CTRL_BITS_SHIFT U(7)
/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_X3_CPUACTLR_EL1 S3_0_C15_C1_0
+
+/*******************************************************************************
* CPU Auxiliary Control register 2 specific definitions.
******************************************************************************/
#define CORTEX_X3_CPUACTLR2_EL1 S3_0_C15_C1_1
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index f637619..910026e 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -140,7 +140,7 @@
#define CTX_TIMER_SYSREGS_END CTX_AARCH32_END
#endif /* NS_TIMER_SWITCH */
-#if CTX_INCLUDE_MTE_REGS
+#if ENABLE_FEAT_MTE
#define CTX_TFSRE0_EL1 (CTX_TIMER_SYSREGS_END + U(0x0))
#define CTX_TFSR_EL1 (CTX_TIMER_SYSREGS_END + U(0x8))
#define CTX_RGSR_EL1 (CTX_TIMER_SYSREGS_END + U(0x10))
@@ -150,7 +150,7 @@
#define CTX_MTE_REGS_END (CTX_TIMER_SYSREGS_END + U(0x20))
#else
#define CTX_MTE_REGS_END CTX_TIMER_SYSREGS_END
-#endif /* CTX_INCLUDE_MTE_REGS */
+#endif /* ENABLE_FEAT_MTE */
/*
* End of system registers.
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index c5f6000..01dbea9 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,7 +24,7 @@
/* The macros below are used to identify FFA calls from the SMC function ID */
#define FFA_FNUM_MIN_VALUE U(0x60)
-#define FFA_FNUM_MAX_VALUE U(0x8C)
+#define FFA_FNUM_MAX_VALUE U(0x8E)
#define is_ffa_fid(fid) __extension__ ({ \
__typeof__(fid) _fid = (fid); \
((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) && \
@@ -123,6 +123,8 @@
/* FF-A v1.2 */
#define FFA_FNUM_PARTITION_INFO_GET_REGS U(0x8B)
#define FFA_FNUM_EL3_INTR_HANDLE U(0x8C)
+#define FFA_FNUM_MSG_SEND_DIRECT_REQ2 U(0x8D)
+#define FFA_FNUM_MSG_SEND_DIRECT_RESP2 U(0x8E)
#define FFA_FNUM_CONSOLE_LOG U(0x8A)
@@ -195,6 +197,10 @@
#define FFA_PARTITION_INFO_GET_REGS_SMC64 \
FFA_FID(SMC_64, FFA_FNUM_PARTITION_INFO_GET_REGS)
#define FFA_CONSOLE_LOG_SMC64 FFA_FID(SMC_64, FFA_FNUM_CONSOLE_LOG)
+#define FFA_MSG_SEND_DIRECT_REQ2_SMC64 \
+ FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ2)
+#define FFA_MSG_SEND_DIRECT_RESP2_SMC64 \
+ FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP2)
/*
* FF-A partition properties values.
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 2e6e8b6..0dc34f7 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -72,6 +72,19 @@
check_erratum_range cortex_a78c, ERRATUM(2395411), CPU_REV(0, 1), CPU_REV(0, 2)
+workaround_reset_start cortex_a78c, ERRATUM(2683027), ERRATA_A78C_2683027
+ ldr x0, =0x3
+ msr CORTEX_A78C_IMP_CPUPSELR_EL3, x0
+ ldr x0, =0xEE010F10
+ msr CORTEX_A78C_IMP_CPUPOR_EL3, x0
+ ldr x0, =0xFF1F0FFE
+ msr CORTEX_A78C_IMP_CPUPMR_EL3, x0
+ ldr x0, =0x100000004003FF
+ msr CORTEX_A78C_IMP_CPUPCR_EL3, x0
+workaround_reset_end cortex_a78c, ERRATUM(2683027)
+
+check_erratum_range cortex_a78c, ERRATUM(2683027), CPU_REV(0, 1), CPU_REV(0, 2)
+
workaround_reset_start cortex_a78c, ERRATUM(2743232), ERRATA_A78C_2743232
/* Set CPUACTLR5_EL1[56:55] to 2'b01 */
sysreg_bit_set CORTEX_A78C_ACTLR5_EL1, BIT(55)
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index 7e9a7fc..ea89267 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -33,6 +33,18 @@
check_erratum_ls cortex_x3, ERRATUM(2070301), CPU_REV(1, 2)
+workaround_reset_start cortex_x3, ERRATUM(2266875), ERRATA_X3_2266875
+ sysreg_bit_set CORTEX_X3_CPUACTLR_EL1, BIT(22)
+workaround_reset_end cortex_x3, ERRATUM(2266875)
+
+check_erratum_ls cortex_x3, ERRATUM(2266875), CPU_REV(1, 0)
+
+workaround_runtime_start cortex_x3, ERRATUM(2302506), ERRATA_X3_2302506
+ sysreg_bit_set CORTEX_X3_CPUACTLR2_EL1, BIT(0)
+workaround_runtime_end cortex_x3, ERRATUM(2302506), NO_ISB
+
+check_erratum_ls cortex_x3, ERRATUM(2302506), CPU_REV(1, 1)
+
workaround_runtime_start cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909
sysreg_bit_set CORTEX_X3_CPUACTLR2_EL1, CORTEX_X3_CPUACTLR2_EL1_BIT_36
workaround_runtime_end cortex_x3, ERRATUM(2313909), NO_ISB
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 0ad5e78..a99c082 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
# Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
@@ -388,6 +388,10 @@
# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
CPU_FLAG_LIST += ERRATA_A78C_2395411
+# Flag to apply erratum 2683027 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+CPU_FLAG_LIST += ERRATA_A78C_2683027
+
# Flag to apply erratum 2712575 workaround for non-arm interconnect ip. This
# erratum applies to revisions r0p1 and r0p2 of the A78C cpu.
# It is still open.
@@ -774,6 +778,14 @@
# still open.
CPU_FLAG_LIST += ERRATA_X3_2070301
+# Flag to apply erratum 2266875 workaround during reset. This erratum applies
+# to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_X3_2266875
+
+# Flag to apply erratum 2302506 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0 and r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_X3_2302506
+
# Flag to apply erratum 2313909 workaround on powerdown. This erratum applies
# to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
CPU_FLAG_LIST += ERRATA_X3_2313909
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 9ba4d09..780537d 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.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.
* Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -123,22 +123,10 @@
scr_el3 |= get_scr_el3_from_routing_model(SECURE);
#endif
-#if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
- /* Get Memory Tagging Extension support level */
- unsigned int mte = get_armv8_5_mte_support();
-#endif
- /*
- * Allow access to Allocation Tags when CTX_INCLUDE_MTE_REGS
- * is set, or when MTE is only implemented at EL0.
- */
-#if CTX_INCLUDE_MTE_REGS
- assert((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY));
- scr_el3 |= SCR_ATA_BIT;
-#else
- if (mte == MTE_IMPLEMENTED_EL0) {
+ /* Allow access to Allocation Tags when mte is set*/
+ if (is_feat_mte_supported()) {
scr_el3 |= SCR_ATA_BIT;
}
-#endif /* CTX_INCLUDE_MTE_REGS */
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
@@ -1267,9 +1255,10 @@
el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
el2_sysregs_context_save_common(el2_sysregs_ctx);
-#if CTX_INCLUDE_MTE_REGS
- write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
-#endif
+
+ if (is_feat_mte_supported()) {
+ write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
+ }
#if CTX_INCLUDE_MPAM_REGS
if (is_feat_mpam_supported()) {
diff --git a/lib/fconf/fconf_cot_getter.c b/lib/fconf/fconf_cot_getter.c
index 1033018..b9bc9de 100644
--- a/lib/fconf/fconf_cot_getter.c
+++ b/lib/fconf/fconf_cot_getter.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -237,13 +237,17 @@
* verified by signature and images are verified by hash.
*/
if (type == IMG_CERT) {
- if (root_certificate) {
- oid = NULL;
- } else {
- rc = get_oid(dtb, node, "signing-key", &oid);
- if (rc < 0) {
+ rc = get_oid(dtb, node, "signing-key", &oid);
+ if (rc < 0) {
+ /*
+ * The signing-key property is optional in root
+ * certificates, mandatory otherwise.
+ */
+ if (root_certificate) {
+ oid = NULL;
+ } else {
ERROR("FCONF: Can't read %s property\n",
- "signing-key");
+ "signing-key");
return rc;
}
}
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index a337e76..9ac9332 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2022-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -239,10 +239,18 @@
# registers, by setting SCR_EL3.TRNDR.
ENABLE_FEAT_RNG_TRAP ?= 0
-# Include Memory Tagging Extension registers in cpu context. This must be set
-# to 1 if the platform wants to use this feature in the Secure world and MTE is
-# enabled at ELX.
-CTX_INCLUDE_MTE_REGS ?= 0
+# Enable Memory Tagging Extension. This must be set to 1 if the platform wants
+# to use this feature in the Secure world and MTE is enabled at ELX.
+ifeq ($(CTX_INCLUDE_MTE_REGS),1)
+ $(warning CTX_INCLUDE_MTE_REGS option is deprecated use ENABLE_FEAT_MTE, Enabling ENABLE_FEAT_MTE)
+ ENABLE_FEAT_MTE ?= 1
+endif
+ifeq (${ARCH},aarch32)
+ ifneq ($(or $(ENABLE_FEAT_MTE),0),0)
+ $(error ENABLE_FEAT_MTE is not supported for AArch32)
+ endif
+endif
+ENABLE_FEAT_MTE ?= 0
#----
# 8.6
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 6ba76db..9eb2177 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -104,7 +104,11 @@
};
#if COT_DESC_IN_DTB
- #include "cot_descriptors.dtsi"
+ #if defined(ARM_COT_cca)
+ #include "cca_cot_descriptors.dtsi"
+ #elif defined(ARM_COT_tbbr)
+ #include "tbbr_cot_descriptors.dtsi"
+ #endif
#endif
#if MEASURED_BOOT
@@ -117,6 +121,13 @@
#include "../fvp_def.h"
+#if defined(ARM_COT_cca)
+/* FVP does not support the CCA NV Counter so use the Trusted one. */
+&cca_nv_counter {
+ reg = <TFW_NVCTR_BASE>;
+};
+#endif
+
&trusted_nv_counter {
reg = <TFW_NVCTR_BASE>;
};
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index ae0d85d..5084ea9 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -383,7 +383,12 @@
else ifeq (${COT},dualroot)
AUTH_SOURCES += drivers/auth/dualroot/cot.c
else ifeq (${COT},cca)
- AUTH_SOURCES += drivers/auth/cca/cot.c
+ BL1_SOURCES += drivers/auth/cca/cot.c
+ ifneq (${COT_DESC_IN_DTB},0)
+ BL2_SOURCES += lib/fconf/fconf_cot_getter.c
+ else
+ BL2_SOURCES += drivers/auth/cca/cot.c
+ endif
else
$(error Unknown chain of trust ${COT})
endif
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 211a7b7..61c0ef2 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -28,6 +28,7 @@
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
#include "socfpga_reset_manager.h"
+#include "socfpga_ros.h"
#include "socfpga_system_manager.h"
#include "wdt/watchdog.h"
@@ -92,6 +93,7 @@
void bl2_el3_plat_arch_setup(void)
{
+ unsigned long offset = 0;
const mmap_region_t bl_regions[] = {
MAP_REGION_FLAT(BL2_BASE, BL2_END - BL2_BASE,
MT_MEMORY | MT_RW | MT_SECURE),
@@ -123,14 +125,17 @@
switch (boot_source) {
case BOOT_SOURCE_SDMMC:
dw_mmc_init(¶ms, &mmc_info);
- socfpga_io_setup(boot_source);
+ socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
break;
case BOOT_SOURCE_QSPI:
cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
- socfpga_io_setup(boot_source);
+ if (ros_qspi_get_ssbl_offset(&offset) != ROS_RET_OK) {
+ offset = PLAT_QSPI_DATA_BASE;
+ }
+ socfpga_io_setup(boot_source, offset);
break;
default:
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index f81480d..6780845 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -47,6 +47,7 @@
plat/intel/soc/agilex/soc/agilex_pinmux.c \
plat/intel/soc/common/bl2_plat_mem_params_desc.c \
plat/intel/soc/common/socfpga_image_load.c \
+ plat/intel/soc/common/socfpga_ros.c \
plat/intel/soc/common/socfpga_storage.c \
plat/intel/soc/common/soc/socfpga_emac.c \
plat/intel/soc/common/soc/socfpga_firewall.c \
@@ -77,6 +78,8 @@
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
PROGRAMMABLE_RESET_ADDRESS := 0
RESET_TO_BL2 := 1
BL2_INV_DCACHE := 0
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
index 5c15148..c74d799 100644
--- a/plat/intel/soc/agilex5/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -34,6 +34,7 @@
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
#include "socfpga_reset_manager.h"
+#include "socfpga_ros.h"
#include "wdt/watchdog.h"
@@ -96,6 +97,7 @@
void bl2_el3_plat_arch_setup(void)
{
handoff reverse_handoff_ptr;
+ unsigned long offset = 0;
struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
@@ -109,7 +111,7 @@
case BOOT_SOURCE_SDMMC:
NOTICE("SDMMC boot\n");
sdmmc_init(&reverse_handoff_ptr, ¶ms, &mmc_info);
- socfpga_io_setup(boot_source);
+ socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
break;
case BOOT_SOURCE_QSPI:
@@ -117,13 +119,16 @@
cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
- socfpga_io_setup(boot_source);
+ if (ros_qspi_get_ssbl_offset(&offset) != ROS_RET_OK) {
+ offset = PLAT_QSPI_DATA_BASE;
+ }
+ socfpga_io_setup(boot_source, offset);
break;
case BOOT_SOURCE_NAND:
NOTICE("NAND boot\n");
nand_init(&reverse_handoff_ptr);
- socfpga_io_setup(boot_source);
+ socfpga_io_setup(boot_source, PLAT_NAND_DATA_BASE);
break;
default:
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
index 1ce1cff..acdbe17 100644
--- a/plat/intel/soc/agilex5/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -56,7 +56,7 @@
#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE 0x10d21300
/* Define maximum page size for NAND flash devices */
-#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000)
+#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x2000)
/*******************************************************************************
* Platform memory map related constants
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
index b42253b..7302164 100644
--- a/plat/intel/soc/agilex5/platform.mk
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -60,6 +60,7 @@
plat/intel/soc/agilex5/soc/agilex5_power_manager.c \
plat/intel/soc/common/bl2_plat_mem_params_desc.c \
plat/intel/soc/common/socfpga_image_load.c \
+ plat/intel/soc/common/socfpga_ros.c \
plat/intel/soc/common/socfpga_storage.c \
plat/intel/soc/common/socfpga_vab.c \
plat/intel/soc/common/soc/socfpga_emac.c \
@@ -100,6 +101,10 @@
CTX_INCLUDE_AARCH32_REGS := 0
ERRATA_A55_1530923 := 1
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33 := 0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
PROGRAMMABLE_RESET_ADDRESS := 0
diff --git a/plat/intel/soc/common/bl2_plat_mem_params_desc.c b/plat/intel/soc/common/bl2_plat_mem_params_desc.c
index 187c53a..a09fb70 100644
--- a/plat/intel/soc/common/bl2_plat_mem_params_desc.c
+++ b/plat/intel/soc/common/bl2_plat_mem_params_desc.c
@@ -88,9 +88,27 @@
.image_info.image_base = PLAT_NS_IMAGE_OFFSET,
.image_info.image_max_size =
0x0 + 0x40000000 - PLAT_NS_IMAGE_OFFSET,
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+ .next_handoff_image_id = NT_FW_CONFIG_ID,
+ },
+
+ {
+ .image_id = NT_FW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = ARM_PRELOADED_DTB_BASE,
+ .image_info.image_max_size =
+ 0x0 + 0x40000000 - ARM_PRELOADED_DTB_BASE,
.next_handoff_image_id = INVALID_IMAGE_ID,
},
+#else
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+# endif
};
REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/intel/soc/common/drivers/nand/nand.c b/plat/intel/soc/common/drivers/nand/nand.c
index c6acbe3..7fd955a 100644
--- a/plat/intel/soc/common/drivers/nand/nand.c
+++ b/plat/intel/soc/common/drivers/nand/nand.c
@@ -38,18 +38,12 @@
mmio_write_32(SOCFPGA_PINMUX(PIN12SEL), SOCFPGA_PINMUX_SEL_NAND);
mmio_write_32(SOCFPGA_PINMUX(PIN13SEL), SOCFPGA_PINMUX_SEL_NAND);
mmio_write_32(SOCFPGA_PINMUX(PIN14SEL), SOCFPGA_PINMUX_SEL_NAND);
- mmio_write_32(SOCFPGA_PINMUX(PIN16SEL), SOCFPGA_PINMUX_SEL_NAND);
- mmio_write_32(SOCFPGA_PINMUX(PIN17SEL), SOCFPGA_PINMUX_SEL_NAND);
- mmio_write_32(SOCFPGA_PINMUX(PIN18SEL), SOCFPGA_PINMUX_SEL_NAND);
- mmio_write_32(SOCFPGA_PINMUX(PIN19SEL), SOCFPGA_PINMUX_SEL_NAND);
- mmio_write_32(SOCFPGA_PINMUX(PIN20SEL), SOCFPGA_PINMUX_SEL_NAND);
- mmio_write_32(SOCFPGA_PINMUX(PIN21SEL), SOCFPGA_PINMUX_SEL_NAND);
- mmio_write_32(SOCFPGA_PINMUX(PIN22SEL), SOCFPGA_PINMUX_SEL_NAND);
- mmio_write_32(SOCFPGA_PINMUX(PIN23SEL), SOCFPGA_PINMUX_SEL_NAND);
}
int nand_init(handoff *hoff_ptr)
{
+ (void)(hoff_ptr);
+
/* NAND pin mux configuration */
nand_pinmux_config();
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 49fc567..1946898 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -44,6 +44,10 @@
#define PLAT_HANDOFF_OFFSET 0xFFE3F000
#endif
+#define PLAT_QSPI_DATA_BASE (0x3C00000)
+#define PLAT_NAND_DATA_BASE (0x0200000)
+#define PLAT_SDMMC_DATA_BASE (0x0)
+
/*******************************************************************************
* Platform binary types for linking
******************************************************************************/
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index 242dd73..041c282 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -33,7 +33,7 @@
void enable_nonsecure_access(void);
-void socfpga_io_setup(int boot_source);
+void socfpga_io_setup(int boot_source, unsigned long offset);
void socfgpa_configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
diff --git a/plat/intel/soc/common/include/socfpga_ros.h b/plat/intel/soc/common/include/socfpga_ros.h
new file mode 100644
index 0000000..10cabd3
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_ros.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2024, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_ROS_H
+#define SOCFPGA_ROS_H
+
+#include <arch_helpers.h>
+#include <lib/utils_def.h>
+
+/** status response*/
+#define ROS_RET_OK (0x00U)
+#define ROS_RET_INVALID (0x01U)
+#define ROS_RET_NOT_RSU_MODE (0x02U)
+#define ROS_QSPI_READ_ERROR (0x03U)
+#define ROS_SPT_BAD_MAGIC_NUM (0x04U)
+#define ROS_SPT_CRC_ERROR (0x05U)
+#define ROS_IMAGE_INDEX_ERR (0x06U)
+#define ROS_IMAGE_PARTNUM_OVFL (0x07U)
+
+#define ADDR_64(h, l) (((((unsigned long)(h)) & 0xffffffff) << 32) | \
+ (((unsigned long)(l)) & 0xffffffff))
+
+#define RSU_GET_SPT_RESP_SIZE (4U)
+
+#define RSU_STATUS_RES_SIZE (9U)
+
+#define SPT_MAGIC_NUMBER (0x57713427U)
+#define SPT_VERSION (0U)
+#define SPT_FLAG_RESERVED (1U)
+#define SPT_FLAG_READONLY (2U)
+
+#define SPT_MAX_PARTITIONS (127U)
+#define SPT_PARTITION_NAME_LENGTH (16U)
+#define SPT_RSVD_LENGTH (4U)
+#define SPT_SIZE (4096U)
+/*BOOT_INFO + FACTORY_IMAGE + SPT0 + SPT1 + CPB0 + CPB1 + FACTORY_IM.SSBL+ *APP* + *APP*.SSBL*/
+#define SPT_MIN_PARTITIONS (9U)
+
+#define FACTORY_IMAGE "FACTORY_IMAGE"
+#define FACTORY_SSBL "FACTORY_IM.SSBL"
+#define SSBL_SUFFIX ".SSBL"
+
+typedef struct {
+ const uint32_t magic_number;
+ const uint32_t version;
+ const uint32_t partitions;
+ uint32_t checksum;
+ const uint32_t __RSVD[SPT_RSVD_LENGTH];
+ struct {
+ const char name[SPT_PARTITION_NAME_LENGTH];
+ const uint64_t offset;
+ const uint32_t length;
+ const uint32_t flags;
+ } partition[SPT_MAX_PARTITIONS];
+} __packed spt_table_t;
+
+uint32_t ros_qspi_get_ssbl_offset(unsigned long *offset);
+
+#endif /* SOCFPGA_ROS_H */
diff --git a/plat/intel/soc/common/socfpga_ros.c b/plat/intel/soc/common/socfpga_ros.c
new file mode 100644
index 0000000..ea37384
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_ros.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2024, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* system header files*/
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+/* CRC function header */
+#include <common/tf_crc32.h>
+
+/* Cadense qspi driver*/
+#include <qspi/cadence_qspi.h>
+
+/* Mailbox driver*/
+#include <socfpga_mailbox.h>
+
+#include <socfpga_ros.h>
+
+static void swap_bits(char *const data, uint32_t len)
+{
+ uint32_t x, y;
+ char tmp;
+
+ for (x = 0U; x < len; x++) {
+ tmp = 0U;
+ for (y = 0U; y < 8; y++) {
+ tmp <<= 1;
+ if (data[x] & 1) {
+ tmp |= 1;
+ }
+ data[x] >>= 1;
+ }
+ data[x] = tmp;
+ }
+}
+
+static uint32_t get_current_image_index(spt_table_t *spt_buf, uint32_t *const img_index)
+{
+ if (spt_buf == NULL || img_index == NULL) {
+ return ROS_RET_INVALID;
+ }
+
+ uint32_t ret;
+ unsigned long current_image;
+ uint32_t rsu_status[RSU_STATUS_RES_SIZE];
+
+ if (spt_buf->partitions < SPT_MIN_PARTITIONS || spt_buf->partitions > SPT_MAX_PARTITIONS) {
+ return ROS_IMAGE_PARTNUM_OVFL;
+ }
+
+ ret = mailbox_rsu_status(rsu_status, RSU_STATUS_RES_SIZE);
+ if (ret != MBOX_RET_OK) {
+ return ROS_RET_NOT_RSU_MODE;
+ }
+
+ current_image = ADDR_64(rsu_status[1], rsu_status[0]);
+ NOTICE("ROS: Current image is at 0x%08lx\n", current_image);
+
+ *img_index = 0U;
+ for (uint32_t index = 0U ; index < spt_buf->partitions; index++) {
+ if (spt_buf->partition[index].offset == current_image) {
+ *img_index = index;
+ break;
+ }
+ }
+
+ if (*img_index == 0U) {
+ return ROS_IMAGE_INDEX_ERR;
+ }
+
+ return ROS_RET_OK;
+}
+
+static uint32_t load_and_check_spt(spt_table_t *spt_ptr, size_t offset)
+{
+
+ if (spt_ptr == NULL || offset == 0U) {
+ return ROS_RET_INVALID;
+ }
+
+ int ret;
+ uint32_t calc_crc;
+ static spt_table_t spt_data;
+
+ ret = cad_qspi_read(spt_ptr, offset, SPT_SIZE);
+ if (ret != 0U) {
+ return ROS_QSPI_READ_ERROR;
+ }
+
+ if (spt_ptr->magic_number != SPT_MAGIC_NUMBER) {
+ return ROS_SPT_BAD_MAGIC_NUM;
+ }
+
+ if (spt_ptr->partitions < SPT_MIN_PARTITIONS || spt_ptr->partitions > SPT_MAX_PARTITIONS) {
+ return ROS_IMAGE_PARTNUM_OVFL;
+ }
+
+ memcpy_s(&spt_data, SPT_SIZE, spt_ptr, SPT_SIZE);
+ spt_data.checksum = 0U;
+ swap_bits((char *)&spt_data, SPT_SIZE);
+
+ calc_crc = tf_crc32(0, (uint8_t *)&spt_data, SPT_SIZE);
+ if (bswap32(spt_ptr->checksum) != calc_crc) {
+ return ROS_SPT_CRC_ERROR;
+ }
+
+ NOTICE("ROS: SPT table at 0x%08lx is verified\n", offset);
+ return ROS_RET_OK;
+}
+
+static uint32_t get_spt(spt_table_t *spt_buf)
+{
+ if (spt_buf == NULL) {
+ return ROS_RET_INVALID;
+ }
+
+ uint32_t ret;
+ uint32_t spt_offset[RSU_GET_SPT_RESP_SIZE];
+
+ /* Get SPT offset from SDM via mailbox commands */
+ ret = mailbox_rsu_get_spt_offset(spt_offset, RSU_GET_SPT_RESP_SIZE);
+ if (ret != MBOX_RET_OK) {
+ WARN("ROS: Not booted in RSU mode\n");
+ return ROS_RET_NOT_RSU_MODE;
+ }
+
+ /* Print the SPT table addresses */
+ VERBOSE("ROS: SPT0 0x%08lx\n", ADDR_64(spt_offset[0], spt_offset[1]));
+ VERBOSE("ROS: SPT1 0x%08lx\n", ADDR_64(spt_offset[2], spt_offset[3]));
+
+ /* Load and validate SPT1*/
+ ret = load_and_check_spt(spt_buf, ADDR_64(spt_offset[2], spt_offset[3]));
+ if (ret != ROS_RET_OK) {
+ /* Load and validate SPT0*/
+ ret = load_and_check_spt(spt_buf, ADDR_64(spt_offset[0], spt_offset[1]));
+ if (ret != ROS_RET_OK) {
+ WARN("Both SPT tables are unusable\n");
+ return ret;
+ }
+ }
+
+ return ROS_RET_OK;
+}
+
+uint32_t ros_qspi_get_ssbl_offset(unsigned long *offset)
+{
+ if (offset == NULL) {
+ return ROS_RET_INVALID;
+ }
+
+ uint32_t ret, img_index;
+ char ssbl_name[SPT_PARTITION_NAME_LENGTH];
+ static spt_table_t spt;
+
+ ret = get_spt(&spt);
+ if (ret != ROS_RET_OK) {
+ return ret;
+ }
+
+ ret = get_current_image_index(&spt, &img_index);
+ if (ret != ROS_RET_OK) {
+ return ret;
+ }
+
+ if (strncmp(spt.partition[img_index].name, FACTORY_IMAGE,
+ SPT_PARTITION_NAME_LENGTH) == 0U) {
+ strlcpy(ssbl_name, FACTORY_SSBL, SPT_PARTITION_NAME_LENGTH);
+ } else {
+ strlcpy(ssbl_name, spt.partition[img_index].name,
+ SPT_PARTITION_NAME_LENGTH);
+ strlcat(ssbl_name, SSBL_SUFFIX, SPT_PARTITION_NAME_LENGTH);
+ }
+
+ for (uint32_t index = 0U; index < spt.partitions; index++) {
+ if (strncmp(spt.partition[index].name, ssbl_name,
+ SPT_PARTITION_NAME_LENGTH) == 0U) {
+ *offset = spt.partition[index].offset;
+ NOTICE("ROS: Corresponding SSBL is at 0x%08lx\n", *offset);
+ return ROS_RET_OK;
+ }
+ }
+
+ return ROS_IMAGE_INDEX_ERR;
+}
diff --git a/plat/intel/soc/common/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index e80f074..d250d9e 100644
--- a/plat/intel/soc/common/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -24,16 +24,13 @@
#include "drivers/sdmmc/sdmmc.h"
#include "socfpga_private.h"
+#include "socfpga_ros.h"
#define PLAT_FIP_BASE (0)
#define PLAT_FIP_MAX_SIZE (0x1000000)
#define PLAT_MMC_DATA_BASE (0xffe3c000)
#define PLAT_MMC_DATA_SIZE (0x2000)
-#define PLAT_QSPI_DATA_BASE (0x3C00000)
-#define PLAT_QSPI_DATA_SIZE (0x1000000)
-#define PLAT_NAND_DATA_BASE (0x0200000)
-#define PLAT_NAND_DATA_SIZE (0x1000000)
static const io_dev_connector_t *fip_dev_con;
static const io_dev_connector_t *boot_dev_con;
@@ -55,6 +52,12 @@
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
};
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+static const io_uuid_spec_t nt_fw_config_uuid_spec = {
+ .uuid = UUID_NT_FW_CONFIG,
+};
+# endif
+
uintptr_t a2_lba_offset;
const char a2[] = {0xa2, 0x0};
@@ -101,6 +104,13 @@
(uintptr_t) &bl33_uuid_spec,
check_fip
},
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+ [NT_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_config_uuid_spec,
+ check_fip
+ },
+# endif
[GPT_IMAGE_ID] = {
&boot_dev_handle,
(uintptr_t) &gpt_block_spec,
@@ -136,9 +146,10 @@
return result;
}
-void socfpga_io_setup(int boot_source)
+void socfpga_io_setup(int boot_source, unsigned long offset)
{
int result;
+ fip_spec.offset = offset;
switch (boot_source) {
case BOOT_SOURCE_SDMMC:
@@ -152,7 +163,6 @@
case BOOT_SOURCE_QSPI:
register_io_dev = ®ister_io_dev_memmap;
- fip_spec.offset = PLAT_QSPI_DATA_BASE;
break;
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
@@ -161,7 +171,6 @@
nand_dev_spec.ops.init = cdns_nand_init_mtd;
nand_dev_spec.ops.read = cdns_nand_read;
nand_dev_spec.ops.write = NULL;
- fip_spec.offset = PLAT_NAND_DATA_BASE;
break;
#endif
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 95f076f..29fd0eb 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -46,6 +46,8 @@
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
PROGRAMMABLE_RESET_ADDRESS := 0
RESET_TO_BL2 := 1
BL2_INV_DCACHE := 0
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 73e3216..d140394 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -122,14 +122,14 @@
switch (boot_source) {
case BOOT_SOURCE_SDMMC:
dw_mmc_init(¶ms, &mmc_info);
- socfpga_io_setup(boot_source);
+ socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
break;
case BOOT_SOURCE_QSPI:
cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
- socfpga_io_setup(boot_source);
+ socfpga_io_setup(boot_source, PLAT_QSPI_DATA_BASE);
break;
default:
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 9567c45..afcf514 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -76,6 +76,8 @@
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
PROGRAMMABLE_RESET_ADDRESS := 0
RESET_TO_BL2 := 1
USE_COHERENT_MEM := 1
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index 8c7518d..cd83a98 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -19,9 +19,7 @@
#include <common/fdt_fixup.h>
#include <common/fdt_wrappers.h>
#include <lib/optee_utils.h>
-#if TRANSFER_LIST
#include <lib/transfer_list.h>
-#endif
#include <lib/utils.h>
#include <plat/common/platform.h>
#if ENABLE_RME
@@ -55,9 +53,7 @@
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
-#if TRANSFER_LIST
static struct transfer_list_header *bl2_tl;
-#endif
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
@@ -122,7 +118,7 @@
ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
#if TRANSFER_LIST
- // create a TE
+ /* create a TE */
te = transfer_list_add(bl2_tl, TL_TAG_FDT, fdt_totalsize(fdt), fdt);
if (!te) {
ERROR("Failed to add FDT entry to Transfer List\n");
@@ -321,6 +317,23 @@
}
#endif /*defined(SPD_spmd) && SPMD_SPM_AT_SEL2*/
+#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
+static int handoff_pageable_part(uint64_t pagable_part)
+{
+#if TRANSFER_LIST
+ struct transfer_list_entry *te;
+
+ te = transfer_list_add(bl2_tl, TL_TAG_OPTEE_PAGABLE_PART,
+ sizeof(pagable_part), &pagable_part);
+ if (!te) {
+ INFO("Cannot add TE for pageable part\n");
+ return -1;
+ }
+#endif
+ return 0;
+}
+#endif
+
static int qemu_bl2_handle_post_image_load(unsigned int image_id)
{
int err = 0;
@@ -334,12 +347,24 @@
#endif
#if TRANSFER_LIST
struct transfer_list_header *ns_tl = NULL;
- struct transfer_list_entry *te = NULL;
#endif
assert(bl_mem_params);
switch (image_id) {
+#if TRANSFER_LIST
+ case BL31_IMAGE_ID:
+ /*
+ * arg0 is a bl_params_t reserved for bl31_early_platform_setup2
+ * we just need arg1 and arg3 for BL31 to update th TL from S
+ * to NS memory before it exits
+ */
+ bl_mem_params->ep_info.args.arg1 =
+ TRANSFER_LIST_SIGNATURE |
+ REGISTER_CONVENTION_VERSION_MASK;
+ bl_mem_params->ep_info.args.arg3 = (uintptr_t)bl2_tl;
+ break;
+#endif
case BL32_IMAGE_ID:
#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
@@ -354,8 +379,21 @@
if (err != 0) {
WARN("OPTEE header parse error.\n");
}
+
+ /* add TL_TAG_OPTEE_PAGABLE_PART entry to the TL */
+ if (handoff_pageable_part(bl_mem_params->ep_info.args.arg1)) {
+ return -1;
+ }
#endif
+ INFO("Handoff to BL32\n");
+ bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
+ if (TRANSFER_LIST &&
+ transfer_list_set_handoff_args(bl2_tl,
+ &bl_mem_params->ep_info))
+ break;
+
+ INFO("Using default arguments\n");
#if defined(SPMC_OPTEE)
/*
* Explicit zeroes to unused registers since they may have
@@ -379,7 +417,6 @@
bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE;
bl_mem_params->ep_info.args.arg3 = 0;
#endif
- bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
break;
case BL33_IMAGE_ID:
@@ -406,7 +443,7 @@
bl_mem_params->ep_info.args.arg3 = 0U;
#elif TRANSFER_LIST
if (bl2_tl) {
- // relocate the tl to pre-allocate NS memory
+ /* relocate the tl to pre-allocate NS memory */
ns_tl = transfer_list_relocate(bl2_tl,
(void *)(uintptr_t)FW_NS_HANDOFF_BASE,
bl2_tl->max_size);
@@ -415,37 +452,18 @@
(unsigned long)FW_NS_HANDOFF_BASE);
return -1;
}
- NOTICE("Transfer list handoff to BL33\n");
- transfer_list_dump(ns_tl);
-
- te = transfer_list_find(ns_tl, TL_TAG_FDT);
-
- bl_mem_params->ep_info.args.arg1 =
- TRANSFER_LIST_SIGNATURE |
- REGISTER_CONVENTION_VERSION_MASK;
- bl_mem_params->ep_info.args.arg3 = (uintptr_t)ns_tl;
+ }
- if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_32) {
- // aarch32
- bl_mem_params->ep_info.args.arg0 = 0;
- bl_mem_params->ep_info.args.arg2 = te ?
- (uintptr_t)transfer_list_entry_data(te)
- : 0;
- } else {
- // aarch64
- bl_mem_params->ep_info.args.arg0 = te ?
- (uintptr_t)transfer_list_entry_data(te)
- : 0;
- bl_mem_params->ep_info.args.arg2 = 0;
- }
- } else {
- // Legacy handoff
+ INFO("Handoff to BL33\n");
+ if (!transfer_list_set_handoff_args(ns_tl,
+ &bl_mem_params->ep_info)) {
+ INFO("Invalid TL, fallback to default arguments\n");
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
}
#else
/* BL33 expects to receive the primary CPU MPID (through r0) */
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
-#endif // ARM_LINUX_KERNEL_AS_BL33
+#endif /* ARM_LINUX_KERNEL_AS_BL33 */
break;
#ifdef SPD_spmd
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index 894b842..eb88b12 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -9,6 +9,7 @@
#include <common/bl_common.h>
#include <drivers/arm/pl061_gpio.h>
#include <lib/gpt_rme/gpt_rme.h>
+#include <lib/transfer_list.h>
#include <plat/common/platform.h>
#include "qemu_private.h"
@@ -44,6 +45,7 @@
#if ENABLE_RME
static entry_point_info_t rmm_image_ep_info;
#endif
+static struct transfer_list_header *bl31_tl;
/*******************************************************************************
* Perform any BL3-1 early platform setup. Here is an opportunity to copy
@@ -100,6 +102,12 @@
if (!rmm_image_ep_info.pc)
panic();
#endif
+
+ if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE |
+ REGISTER_CONVENTION_VERSION_MASK) &&
+ transfer_list_check_header((void *)arg3) != TL_OPS_NON) {
+ bl31_tl = (void *)arg3; /* saved TL address from BL2 */
+ }
}
void bl31_plat_arch_setup(void)
@@ -188,3 +196,18 @@
else
return NULL;
}
+
+void bl31_plat_runtime_setup(void)
+{
+ console_switch_state(CONSOLE_FLAG_RUNTIME);
+
+#if TRANSFER_LIST
+ if (bl31_tl) {
+ /*
+ * update the TL from S to NS memory before jump to BL33
+ * to reflect all changes in TL done by BL32
+ */
+ memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
+ }
+#endif
+}
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index 14030e3..e8f0344 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -62,6 +62,11 @@
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
/*
+ * Define the max number of memory nodes.
+ */
+#define PLAT_MAX_MEM_NODES 128
+
+/*
* Partition memory into secure ROM, non-secure DRAM, secure "SRAM",
* and secure DRAM.
*/
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
index ed49e91..535f0eb 100644
--- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -30,6 +30,8 @@
#define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101)
#define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200)
#define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201)
+#define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300)
+#define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301)
static uint64_t gic_its_addr;
@@ -38,9 +40,17 @@
uint32_t mpidr;
} cpu_data;
+typedef struct{
+ uint32_t nodeid;
+ uint64_t addr_base;
+ uint64_t addr_size;
+} memory_data;
+
static struct {
uint32_t num_cpus;
+ uint32_t num_memnodes;
cpu_data cpu[PLATFORM_CORE_COUNT];
+ memory_data memory[PLAT_MAX_MEM_NODES];
} dynamic_platform_info;
void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
@@ -127,6 +137,79 @@
INFO("Found %d cpus\n", dynamic_platform_info.num_cpus);
}
+void read_meminfo_from_dt(void *dtb)
+{
+ const fdt32_t *prop;
+ const char *type;
+ int prev, node;
+ int len;
+ uint32_t nodeid = 0;
+ uint32_t memnode = 0;
+ uint32_t higher_value, lower_value;
+ uint64_t cur_base, cur_size;
+
+ /*
+ * QEMU gives us this DeviceTree node:
+ *
+ * memory@100c0000000 {
+ * numa-node-id = <0x01>;
+ * reg = <0x100 0xc0000000 0x00 0x40000000>;
+ * device_type = "memory";
+ * };
+ *
+ * memory@10000000000 {
+ * numa-node-id = <0x00>;
+ * reg = <0x100 0x00 0x00 0xc0000000>;
+ * device_type = "memory";
+ * }
+ */
+
+ for (prev = 0;; prev = node) {
+ node = fdt_next_node(dtb, prev, NULL);
+ if (node < 0) {
+ break;
+ }
+
+ type = fdt_getprop(dtb, node, "device_type", &len);
+ if (type && strncmp(type, "memory", len) == 0) {
+ if (fdt_getprop(dtb, node, "numa-node-id", NULL)) {
+ fdt_read_uint32(dtb, node, "numa-node-id", &nodeid);
+ }
+
+ dynamic_platform_info.memory[memnode].nodeid = nodeid;
+
+ /*
+ * Get the 'reg' property of this node and
+ * assume two 8 bytes for base and size.
+ */
+ prop = fdt_getprop(dtb, node, "reg", &len);
+ if (prop != 0 && len == (2 * sizeof(int64_t))) {
+ higher_value = fdt32_to_cpu(*prop);
+ lower_value = fdt32_to_cpu(*(prop + 1));
+ cur_base = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
+
+ higher_value = fdt32_to_cpu(*(prop + 2));
+ lower_value = fdt32_to_cpu(*(prop + 3));
+ cur_size = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
+
+ dynamic_platform_info.memory[memnode].addr_base = cur_base;
+ dynamic_platform_info.memory[memnode].addr_size = cur_size;
+
+ INFO("RAM %d: node-id: %d, address: 0x%lx - 0x%lx\n",
+ memnode,
+ dynamic_platform_info.memory[memnode].nodeid,
+ dynamic_platform_info.memory[memnode].addr_base,
+ dynamic_platform_info.memory[memnode].addr_base +
+ dynamic_platform_info.memory[memnode].addr_size - 1);
+ }
+
+ memnode++;
+ }
+ }
+
+ dynamic_platform_info.num_memnodes = memnode;
+}
+
void read_platform_config_from_dt(void *dtb)
{
int node;
@@ -222,6 +305,7 @@
read_platform_config_from_dt(dtb);
read_cpuinfo_from_dt(dtb);
+ read_meminfo_from_dt(dtb);
}
/*
@@ -270,6 +354,20 @@
SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
}
+ case SIP_SVC_GET_MEMORY_NODE_COUNT:
+ SMC_RET2(handle, NULL, dynamic_platform_info.num_memnodes);
+
+ case SIP_SVC_GET_MEMORY_NODE:
+ index = x1;
+ if (index < PLAT_MAX_MEM_NODES) {
+ SMC_RET4(handle, NULL,
+ dynamic_platform_info.memory[index].nodeid,
+ dynamic_platform_info.memory[index].addr_base,
+ dynamic_platform_info.memory[index].addr_size);
+ } else {
+ SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
+ }
+
default:
ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid,
smc_fid - SIP_FUNCTION);
diff --git a/plat/renesas/common/aarch64/plat_helpers.S b/plat/renesas/common/aarch64/plat_helpers.S
index a7fdfa0..572620d 100644
--- a/plat/renesas/common/aarch64/plat_helpers.S
+++ b/plat/renesas/common/aarch64/plat_helpers.S
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -172,15 +172,16 @@
* BL31 will initialize the address space according to its
* own requirement.
*/
-#if RCAR_BL2_DCACHE == 1
/* Disable mmu and data cache */
bl disable_mmu_el3
+#if RCAR_BL2_DCACHE == 1
/* Data cache clean and invalidate */
mov x0, #DCCISW
bl dcsw_op_all
+#endif /* RCAR_BL2_DCACHE == 1 */
/* TLB invalidate all, EL3 */
tlbi alle3
-#endif /* RCAR_BL2_DCACHE == 1 */
+
bl disable_mmu_icache_el3
/* Invalidate instruction cache */
ic iallu
diff --git a/plat/renesas/common/aarch64/platform_common.c b/plat/renesas/common/aarch64/platform_common.c
index 17ccb28..9e7d526 100644
--- a/plat/renesas/common/aarch64/platform_common.c
+++ b/plat/renesas/common/aarch64/platform_common.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,13 +30,19 @@
const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
__attribute__ ((__section__(".ro"))) = VERSION_OF_RENESAS;
+#if (IMAGE_BL2) && (RCAR_BL2_DCACHE != 1)
+#define RCAR_DCACHE MT_NON_CACHEABLE
+#else
+#define RCAR_DCACHE MT_MEMORY
+#endif
+
#define MAP_SHARED_RAM MAP_REGION_FLAT(RCAR_SHARED_MEM_BASE, \
RCAR_SHARED_MEM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define MAP_FLASH0 MAP_REGION_FLAT(FLASH0_BASE, \
FLASH0_SIZE, \
- MT_MEMORY | MT_RO | MT_SECURE)
+ RCAR_DCACHE | MT_RO | MT_SECURE)
#define MAP_DRAM1_NS MAP_REGION_FLAT(DRAM1_NS_BASE, \
DRAM1_NS_SIZE, \
@@ -68,7 +74,7 @@
#if IMAGE_BL2
#define MAP_DRAM0 MAP_REGION_FLAT(DRAM1_BASE, \
DRAM1_SIZE, \
- MT_MEMORY | MT_RW | MT_SECURE)
+ RCAR_DCACHE | MT_RW | MT_SECURE)
#define MAP_REG0 MAP_REGION_FLAT(DEVICE_RCAR_BASE, \
DEVICE_RCAR_SIZE, \
@@ -76,7 +82,7 @@
#define MAP_RAM0 MAP_REGION_FLAT(RCAR_SYSRAM_BASE, \
RCAR_SYSRAM_SIZE, \
- MT_MEMORY | MT_RW | MT_SECURE)
+ RCAR_DCACHE | MT_RW | MT_SECURE)
#define MAP_REG1 MAP_REGION_FLAT(REG1_BASE, \
REG1_SIZE, \
@@ -84,7 +90,7 @@
#define MAP_ROM MAP_REGION_FLAT(ROM0_BASE, \
ROM0_SIZE, \
- MT_MEMORY | MT_RO | MT_SECURE)
+ RCAR_DCACHE | MT_RO | MT_SECURE)
#define MAP_REG2 MAP_REGION_FLAT(REG2_BASE, \
REG2_SIZE, \
@@ -92,7 +98,7 @@
#define MAP_DRAM1 MAP_REGION_FLAT(DRAM_40BIT_BASE, \
DRAM_40BIT_SIZE, \
- MT_MEMORY | MT_RW | MT_SECURE)
+ RCAR_DCACHE | MT_RW | MT_SECURE)
#endif
#ifdef BL32_BASE
@@ -152,9 +158,9 @@
unsigned long coh_limit)
{
mmap_add_region(total_base, total_base, total_size,
- MT_MEMORY | MT_RW | MT_SECURE);
+ RCAR_DCACHE | MT_RW | MT_SECURE);
mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
- MT_MEMORY | MT_RO | MT_SECURE);
+ RCAR_DCACHE | MT_RO | MT_SECURE);
mmap_add_region(coh_start, coh_start, coh_limit - coh_start,
MT_DEVICE | MT_RW | MT_SECURE);
mmap_add(rcar_mmap);
@@ -169,9 +175,9 @@
unsigned long ro_limit)
{
mmap_add_region(total_base, total_base, total_size,
- MT_MEMORY | MT_RW | MT_SECURE);
+ RCAR_DCACHE | MT_RW | MT_SECURE);
mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
- MT_MEMORY | MT_RO | MT_SECURE);
+ RCAR_DCACHE | MT_RO | MT_SECURE);
mmap_add(rcar_mmap);
init_xlat_tables();
diff --git a/plat/renesas/common/include/rcar_version.h b/plat/renesas/common/include/rcar_version.h
index 5a0ca31..777ec6a 100644
--- a/plat/renesas/common/include/rcar_version.h
+++ b/plat/renesas/common/include/rcar_version.h
@@ -9,7 +9,7 @@
#include <arch_helpers.h>
-#define VERSION_OF_RENESAS "3.0.3"
+#define VERSION_OF_RENESAS "4.0.0"
#define VERSION_OF_RENESAS_MAXLEN 128
extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN];
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index cf77da2..41031d6 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -48,10 +48,8 @@
#include "rcar_version.h"
#include "rom_api.h"
-#if RCAR_BL2_DCACHE == 1
/*
- * Following symbols are only used during plat_arch_setup() only
- * when RCAR_BL2_DCACHE is enabled.
+ * Following symbols are only used during plat_arch_setup()
*/
static const uint64_t BL2_RO_BASE = BL_CODE_BASE;
static const uint64_t BL2_RO_LIMIT = BL_CODE_END;
@@ -61,8 +59,6 @@
static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END;
#endif
-#endif
-
extern void plat_rcar_gic_driver_init(void);
extern void plat_rcar_gic_init(void);
extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info);
@@ -372,10 +368,16 @@
rcar_swdt_release();
bl2_system_cpg_init();
-#if RCAR_BL2_DCACHE == 1
/* Disable data cache (clean and invalidate) */
disable_mmu_el3();
+#if RCAR_BL2_DCACHE == 1
+ dcsw_op_all(DCCISW);
#endif
+ tlbialle3();
+ disable_mmu_icache_el3();
+ plat_invalidate_icache();
+ dsbsy();
+ isb();
}
static uint32_t is_ddr_backup_mode(void)
@@ -1274,8 +1276,6 @@
void bl2_el3_plat_arch_setup(void)
{
-#if RCAR_BL2_DCACHE == 1
- NOTICE("BL2: D-Cache enable\n");
rcar_configure_mmu_el3(BL2_BASE,
BL2_END - BL2_BASE,
BL2_RO_BASE, BL2_RO_LIMIT
@@ -1283,7 +1283,6 @@
, BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT
#endif
);
-#endif
}
void bl2_el3_plat_prepare_exit(void)
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 670d499..c95590d 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -6,6 +6,8 @@
include plat/renesas/common/common.mk
+ENABLE_STACK_PROTECTOR := strong
+
ifndef LSI
$(error "Error: Unknown LSI. Please use LSI=<LSI name> to specify the LSI")
else
@@ -333,6 +335,10 @@
$(ZLIB_SOURCES)
endif
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+BL_COMMON_SOURCES += plat/renesas/rcar/rcar_stack_protector.c
+endif
+
ifeq (${RCAR_GEN3_ULCB},1)
BL31_SOURCES += drivers/renesas/rcar/cpld/ulcb_cpld.c
endif
diff --git a/plat/renesas/rcar/rcar_stack_protector.c b/plat/renesas/rcar/rcar_stack_protector.c
new file mode 100644
index 0000000..ecceef4
--- /dev/null
+++ b/plat/renesas/rcar/rcar_stack_protector.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021-2023, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t)0xDFF5FC8A720E205EULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ u_register_t cnt;
+ u_register_t seed;
+ u_register_t mul;
+ u_register_t ret;
+ uintptr_t val1 = (uintptr_t)__builtin_return_address(0U);
+ uintptr_t val2 = (uintptr_t)__builtin_frame_address(0U);
+
+ cnt = read_cntpct_el0();
+ seed = (cnt ^ RANDOM_CANARY_VALUE) & ULONG_MAX;
+ ret = seed;
+
+ if ((ULONG_MAX/val1) > seed) {
+ mul = (u_register_t)(val1 * seed);
+ if ((mul < ULONG_MAX) &&
+ ((ULONG_MAX - (u_register_t)mul) > val2)) {
+ ret = mul + val2;
+ }
+ }
+
+ return ret;
+}
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index e334f22..66b9310 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,9 @@
#define JEDEC_ST_BKID U(0x0)
#define JEDEC_ST_MFID U(0x20)
+#define STM32MP_CHIP_SEC_CLOSED U(0x34D9CCC5)
+#define STM32MP_CHIP_SEC_OPEN U(0xA764D182)
+
/* FWU configuration (max supported value is 15) */
#define FWU_MAX_TRIAL_REBOOT U(3)
@@ -23,8 +26,8 @@
uint16_t stm32mp_get_boot_itf_selected(void);
bool stm32mp_is_single_core(void);
-bool stm32mp_is_closed_device(void);
bool stm32mp_is_auth_supported(void);
+uint32_t stm32mp_check_closed_device(void);
/* Return the base address of the DDR controller */
uintptr_t stm32mp_ddrctrl_base(void);
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index 2163aaf..a1d1c49 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.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
*/
@@ -168,9 +168,9 @@
assert(otp_val != NULL);
#if defined(IMAGE_BL2)
- ret = bsec_shadow_read_otp(otp_val, otp_idx);
-#elif defined(IMAGE_BL32)
- ret = bsec_read_otp(otp_val, otp_idx);
+ ret = stm32_otp_shadow_read(otp_val, otp_idx);
+#elif defined(IMAGE_BL31) || defined(IMAGE_BL32)
+ ret = stm32_otp_read(otp_val, otp_idx);
#else
#error "Not supported"
#endif
diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
index e282115..7223022 100644
--- a/plat/st/common/stm32mp_crypto_lib.c
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,6 @@
#include <common/debug.h>
#include <drivers/auth/crypto_mod.h>
#include <drivers/io/io_storage.h>
-#include <drivers/st/bsec.h>
#include <drivers/st/stm32_hash.h>
#include <drivers/st/stm32_pka.h>
#include <drivers/st/stm32_rng.h>
@@ -58,7 +57,8 @@
panic();
}
- if (stm32mp_is_closed_device() || stm32mp_is_auth_supported()) {
+ if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) ||
+ stm32mp_is_auth_supported()) {
#if STM32MP_CRYPTO_ROM_LIB
boot_context = (boot_api_context_t *)stm32mp_get_boot_ctx_address();
auth_ops.verify_signature = boot_context->bootrom_ecdsa_verify_signature;
@@ -322,7 +322,8 @@
size_t bignum_len = sizeof(sig) / 2U;
unsigned int seq_num = 0U;
- if (!stm32mp_is_closed_device() && !stm32mp_is_auth_supported()) {
+ if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) &&
+ !stm32mp_is_auth_supported()) {
return CRYPTO_SUCCESS;
}
diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c
index 6d89290..d40fc55 100644
--- a/plat/st/common/stm32mp_trusted_boot.c
+++ b/plat/st/common/stm32mp_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -67,14 +67,14 @@
* Check if key hash values in OTP are 0 or 0xFFFFFFFFF
* programmed : Invalid Key
*/
- if (!stm32mp_is_closed_device() && !valid) {
+ if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) && !valid) {
if ((tmp != 0U) && (tmp != 0xFFFFFFFFU) && (tmp != first)) {
valid = true;
}
}
}
- if (!stm32mp_is_closed_device() && !valid) {
+ if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) && !valid) {
return 0;
}
@@ -163,7 +163,7 @@
*key_ptr = &root_pk_hash;
*flags = ROTPK_IS_HASH;
- if ((res == 0) && !stm32mp_is_closed_device()) {
+ if ((res == 0) && (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN)) {
*flags |= ROTPK_NOT_DEPLOYED;
}
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index eeabd09..321b8c5 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_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
*/
@@ -318,7 +318,7 @@
skip_console_init:
#if !TRUSTED_BOARD_BOOT
- if (stm32mp_is_closed_device()) {
+ if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
/* Closed chip mandates authentication */
ERROR("Secure chip: TRUSTED_BOARD_BOOT must be enabled\n");
panic();
@@ -347,7 +347,7 @@
stm32_iwdg_refresh();
if (bsec_read_debug_conf() != 0U) {
- if (stm32mp_is_closed_device()) {
+ if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
#if DEBUG
WARN("\n%s", debug_msg);
#else
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 4a52255..f6e5a8f 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.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
*/
@@ -32,4 +32,31 @@
void stm32mp1_deconfigure_uart_pins(void);
void stm32mp1_init_scmi_server(void);
+
+/* Wrappers for OTP / BSEC functions */
+static inline uint32_t stm32_otp_read(uint32_t *val, uint32_t otp)
+{
+ return bsec_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_shadow_read(uint32_t *val, uint32_t otp)
+{
+ return bsec_shadow_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_write(uint32_t val, uint32_t otp)
+{
+ return bsec_write_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_set_sr_lock(uint32_t otp)
+{
+ return bsec_set_sr_lock(otp);
+}
+
+static inline uint32_t stm32_otp_read_sw_lock(uint32_t otp, bool *value)
+{
+ return bsec_read_sw_lock(otp, value);
+}
+
#endif /* STM32MP1_PRIVATE_H */
diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c
index 1fb44b4..7cc0013 100644
--- a/plat/st/stm32mp1/services/bsec_svc.c
+++ b/plat/st/stm32mp1/services/bsec_svc.c
@@ -1,15 +1,15 @@
/*
- * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <platform_def.h>
#include <common/debug.h>
#include <drivers/st/bsec.h>
#include <drivers/st/bsec2_reg.h>
+#include <platform_def.h>
#include <stm32mp1_smc.h>
#include "bsec_svc.h"
@@ -39,12 +39,7 @@
break;
}
- result = bsec_shadow_register(x2);
- if (result != BSEC_OK) {
- break;
- }
-
- result = bsec_read_otp(ret_otp_value, x2);
+ result = bsec_shadow_read_otp(ret_otp_value, x2);
if (result != BSEC_OK) {
break;
}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 6530957..8fc8c89 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.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
*/
@@ -426,24 +426,24 @@
#define OTP_MAX_SIZE (STM32MP1_OTP_MAX_ID + 1U)
/* OTP labels */
-#define CFG0_OTP "cfg0_otp"
+#define CFG0_OTP "cfg0-otp"
#define PART_NUMBER_OTP "part-number-otp"
#if STM32MP15
-#define PACKAGE_OTP "package_otp"
+#define PACKAGE_OTP "package-otp"
#endif
-#define HW2_OTP "hw2_otp"
+#define HW2_OTP "hw2-otp"
#if STM32MP13
-#define NAND_OTP "cfg9_otp"
-#define NAND2_OTP "cfg10_otp"
+#define NAND_OTP "cfg9-otp"
+#define NAND2_OTP "cfg10-otp"
#endif
#if STM32MP15
-#define NAND_OTP "nand_otp"
+#define NAND_OTP "nand-otp"
#endif
-#define MONOTONIC_OTP "monotonic_otp"
-#define UID_OTP "uid_otp"
-#define PKH_OTP "pkh_otp"
-#define ENCKEY_OTP "enckey_otp"
-#define BOARD_ID_OTP "board_id"
+#define MONOTONIC_OTP "monotonic-otp"
+#define UID_OTP "uid-otp"
+#define PKH_OTP "pkh-otp"
+#define ENCKEY_OTP "oem-enc-key"
+#define BOARD_ID_OTP "board-id"
/* OTP mask */
/* CFG0 */
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index ea35055..0e69513 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.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
*/
@@ -531,12 +531,12 @@
}
/* Return true when device is in closed state */
-bool stm32mp_is_closed_device(void)
+uint32_t stm32mp_check_closed_device(void)
{
uint32_t value;
if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
- return true;
+ return STM32MP_CHIP_SEC_CLOSED;
}
#if STM32MP13
@@ -544,17 +544,22 @@
switch (value) {
case CFG0_OPEN_DEVICE:
- return false;
+ return STM32MP_CHIP_SEC_OPEN;
case CFG0_CLOSED_DEVICE:
case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
case CFG0_CLOSED_DEVICE_NO_JTAG:
- return true;
+ return STM32MP_CHIP_SEC_CLOSED;
default:
panic();
}
#endif
#if STM32MP15
- return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
+ if ((value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE) {
+ return STM32MP_CHIP_SEC_CLOSED;
+ } else {
+ return STM32MP_CHIP_SEC_OPEN;
+ }
+
#endif
}
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 0805756..5f05f63 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -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
*/
@@ -7,6 +7,8 @@
#include <cdefs.h>
#include <stdint.h>
+#include <plat/common/platform.h>
+
#include <stm32mp_common.h>
void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
diff --git a/plat/st/stm32mp2/include/stm32mp2_private.h b/plat/st/stm32mp2/include/stm32mp2_private.h
new file mode 100644
index 0000000..e1403d2
--- /dev/null
+++ b/plat/st/stm32mp2/include/stm32mp2_private.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_PRIVATE_H
+#define STM32MP2_PRIVATE_H
+
+/* Wrappers for OTP / BSEC functions */
+static inline uint32_t stm32_otp_probe(void)
+{
+ return bsec_probe();
+}
+
+static inline uint32_t stm32_otp_read(uint32_t *val, uint32_t otp)
+{
+ return bsec_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_shadow_read(uint32_t *val, uint32_t otp)
+{
+ return bsec_shadow_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_write(uint32_t val, uint32_t otp)
+{
+ return bsec_write_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_set_sr_lock(uint32_t otp)
+{
+ return bsec_set_sr_lock(otp);
+}
+
+static inline uint32_t stm32_otp_read_sw_lock(uint32_t otp, bool *value)
+{
+ return bsec_read_sw_lock(otp, value);
+}
+
+static inline bool stm32_otp_is_closed_device(void)
+{
+ return bsec_mode_is_closed_device();
+}
+
+#endif /* STM32MP2_PRIVATE_H */
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 66514fc..ee105de 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -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
*/
@@ -18,6 +18,7 @@
#ifndef __ASSEMBLER__
#include <boot_api.h>
+#include <stm32mp2_private.h>
#include <stm32mp_common.h>
#include <stm32mp_dt.h>
#include <stm32mp_shared_resources.h>
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index 23efa31..8db732c 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -28,6 +28,8 @@
CRASH_REPORTING := 1
+NS_TIMER_SWITCH := 0
+
# Split out RO data into a non-executable section
SEPARATE_CODE_AND_RODATA := 1
diff --git a/plat/xilinx/common/include/plat_common.h b/plat/xilinx/common/include/plat_common.h
index 676baa2..2958868 100644
--- a/plat/xilinx/common/include/plat_common.h
+++ b/plat/xilinx/common/include/plat_common.h
@@ -14,4 +14,16 @@
(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
})
+/*******************************************************************************
+ * interrupt handling related constants
+ ******************************************************************************/
+#define ARM_IRQ_SEC_SGI_0 8U
+#define ARM_IRQ_SEC_SGI_1 9U
+#define ARM_IRQ_SEC_SGI_2 10U
+#define ARM_IRQ_SEC_SGI_3 11U
+#define ARM_IRQ_SEC_SGI_4 12U
+#define ARM_IRQ_SEC_SGI_5 13U
+#define ARM_IRQ_SEC_SGI_6 14U
+#define ARM_IRQ_SEC_SGI_7 15U
+
#endif /* PLAT_COMMON_H */
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index 9cdb0ba..c1872d0 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -18,6 +18,7 @@
/* State arguments of the self suspend */
#define PM_STATE_CPU_IDLE 0x0U
+#define PM_STATE_CPU_OFF 0x1U
#define PM_STATE_SUSPEND_TO_RAM 0xFU
#define MAX_LATENCY (~0U)
diff --git a/plat/xilinx/common/include/pm_svc_main.h b/plat/xilinx/common/include/pm_svc_main.h
index 4cf7727..67fbeae 100644
--- a/plat/xilinx/common/include/pm_svc_main.h
+++ b/plat/xilinx/common/include/pm_svc_main.h
@@ -10,6 +10,8 @@
#include <pm_common.h>
+extern bool pwrdwn_req_received;
+
/******************************************************************************/
/**
* SECURE_REDUNDANT_CALL() - Adds redundancy to the function call. This is to
@@ -30,6 +32,7 @@
status_tmp = function(__VA_ARGS__); \
}
+void request_cpu_pwrdwn(void);
int32_t pm_setup(void);
uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
uint64_t x4, const void *cookie, void *handle,
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index ffc39bb..36ea8ed 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -50,7 +50,7 @@
{
uint32_t reg_num, device_id;
uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = {0U};
- uint32_t isenabler1 = PLAT_GICD_BASE_VALUE + GICD_ISENABLER + 4U;
+ uint32_t isenabler1 = PLAT_ARM_GICD_BASE + GICD_ISENABLER + 4U;
zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set));
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 1e5808c..f9917a0 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -17,6 +17,8 @@
#include <common/runtime_svc.h>
#include <drivers/arm/gicv3.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <plat_private.h>
@@ -31,23 +33,65 @@
#define INVALID_SGI 0xFFU
#define PM_INIT_SUSPEND_CB (30U)
#define PM_NOTIFY_CB (32U)
+#define EVENT_CPU_PWRDWN (4U)
+/* 1 sec of wait timeout for secondary core down */
+#define PWRDWN_WAIT_TIMEOUT (1000U)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r_el1, S3_0_C12_C11_6)
/* pm_up = true - UP, pm_up = false - DOWN */
static bool pm_up;
static uint32_t sgi = (uint32_t)INVALID_SGI;
+bool pwrdwn_req_received;
static void notify_os(void)
{
- int32_t cpu;
- uint32_t reg;
+ plat_ic_raise_ns_sgi(sgi, read_mpidr_el1());
+}
+
+static uint64_t cpu_pwrdwn_req_handler(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+{
+ uint32_t cpu_id = plat_my_core_pos();
+
+ VERBOSE("Powering down CPU %d\n", cpu_id);
- cpu = plat_my_core_pos() + 1U;
+ /* Deactivate CPU power down SGI */
+ plat_ic_end_of_interrupt(CPU_PWR_DOWN_REQ_INTR);
- reg = (cpu | (sgi << XSCUGIC_SGIR_EL1_INITID_SHIFT));
- write_icc_asgi1r_el1(reg);
+ return psci_cpu_off();
}
+/**
+ * raise_pwr_down_interrupt() - Callback function to raise SGI.
+ * @mpidr: MPIDR for the target CPU.
+ *
+ * Raise SGI interrupt to trigger the CPU power down sequence on all the
+ * online secondary cores.
+ */
+static void raise_pwr_down_interrupt(u_register_t mpidr)
+{
+ plat_ic_raise_el3_sgi(CPU_PWR_DOWN_REQ_INTR, mpidr);
+}
+
+void request_cpu_pwrdwn(void)
+{
+ enum pm_ret_status ret;
+
+ VERBOSE("CPU power down request received\n");
+
+ /* Send powerdown request to online secondary core(s) */
+ ret = psci_stop_other_cores(PWRDWN_WAIT_TIMEOUT, raise_pwr_down_interrupt);
+ if (ret != PSCI_E_SUCCESS) {
+ ERROR("Failed to powerdown secondary core(s)\n");
+ }
+
+ /* Clear IPI IRQ */
+ pm_ipi_irq_clear(primary_proc);
+
+ /* Deactivate IPI IRQ */
+ plat_ic_end_of_interrupt(PLAT_VERSAL_IPI_IRQ);
+}
+
static uint64_t ipi_fiq_handler(uint32_t id, uint32_t flags, void *handle,
void *cookie)
{
@@ -56,6 +100,7 @@
VERBOSE("Received IPI FIQ from firmware\n");
+ console_flush();
(void)plat_ic_acknowledge_interrupt();
ret = pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
@@ -65,8 +110,22 @@
switch (payload[0]) {
case PM_INIT_SUSPEND_CB:
+ if (sgi != INVALID_SGI) {
+ notify_os();
+ }
+ break;
case PM_NOTIFY_CB:
if (sgi != INVALID_SGI) {
+ if (payload[2] == EVENT_CPU_PWRDWN) {
+ if (pwrdwn_req_received) {
+ pwrdwn_req_received = false;
+ request_cpu_pwrdwn();
+ (void)psci_cpu_off();
+ break;
+ } else {
+ pwrdwn_req_received = true;
+ }
+ }
notify_os();
}
break;
@@ -139,6 +198,12 @@
pm_ipi_init(primary_proc);
pm_up = true;
+ /* register SGI handler for CPU power down request */
+ ret = request_intr_type_el3(CPU_PWR_DOWN_REQ_INTR, cpu_pwrdwn_req_handler);
+ if (ret != 0) {
+ WARN("BL31: registering SGI interrupt failed\n");
+ }
+
/*
* Enable IPI IRQ
* assume the rich OS is OK to handle callback IRQs now.
diff --git a/plat/xilinx/versal/include/plat_macros.S b/plat/xilinx/versal/include/plat_macros.S
index 41193a5..38f47f6 100644
--- a/plat/xilinx/versal/include/plat_macros.S
+++ b/plat/xilinx/versal/include/plat_macros.S
@@ -103,8 +103,8 @@
* ---------------------------------------------
*/
.macro plat_crash_print_regs
- mov_imm x17, PLAT_GICD_BASE_VALUE
- mov_imm x16, PLAT_GICR_BASE_VALUE
+ mov_imm x17, PLAT_ARM_GICD_BASE
+ mov_imm x16, PLAT_ARM_GICR_BASE
versal_print_gic_regs
.endm
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 286a706..8cf8de0 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -9,6 +9,7 @@
#define PLATFORM_DEF_H
#include <arch.h>
+#include <plat_common.h>
#include "versal_def.h"
/*******************************************************************************
@@ -74,8 +75,17 @@
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
+
+#if (BL31_BASE >= (1ULL << 32U))
+/* Address range in High DDR and HBM memory range */
+#define PLAT_ADDR_SPACE_SHIFT U(42)
+#else
+/* Address range in OCM and Low DDR memory range */
+#define PLAT_ADDR_SPACE_SHIFT U(32)
+#endif
+
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << PLAT_ADDR_SPACE_SHIFT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << PLAT_ADDR_SPACE_SHIFT)
#define XILINX_OF_BOARD_DTB_MAX_SIZE U(0x200000)
@@ -103,8 +113,8 @@
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
-#define PLAT_GICD_BASE_VALUE U(0xF9000000)
-#define PLAT_GICR_BASE_VALUE U(0xF9080000)
+#define PLAT_ARM_GICD_BASE U(0xF9000000)
+#define PLAT_ARM_GICR_BASE U(0xF9080000)
/*
* Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -122,6 +132,8 @@
#define PLAT_VERSAL_G0_IRQ_PROPS(grp) \
INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(CPU_PWR_DOWN_REQ_INTR, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE)
#define IRQ_MAX 142U
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 56d98f7..45b1f1c 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -14,10 +14,13 @@
#include <plat/common/platform.h>
#include <plat_arm.h>
+#include "drivers/delay_timer.h"
#include <plat_private.h>
#include "pm_api_sys.h"
#include "pm_client.h"
#include <pm_common.h>
+#include "pm_ipi.h"
+#include "pm_svc_main.h"
static uintptr_t versal_sec_entry;
@@ -145,9 +148,31 @@
*/
static void __dead2 versal_system_reset(void)
{
- /* Send the system reset request to the PMC */
- (void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
- pm_get_shutdown_scope(), SECURE_FLAG);
+ uint32_t ret, timeout = 10000U;
+
+ request_cpu_pwrdwn();
+
+ /*
+ * Send the system reset request to the firmware if power down request
+ * is not received from firmware.
+ */
+ if (!pwrdwn_req_received) {
+ (void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
+ pm_get_shutdown_scope(), SECURE_FLAG);
+
+ /*
+ * Wait for system shutdown request completed and idle callback
+ * not received.
+ */
+ do {
+ ret = ipi_mb_enquire_status(primary_proc->ipi->local_ipi_id,
+ primary_proc->ipi->remote_ipi_id);
+ udelay(100);
+ timeout--;
+ } while ((ret != IPI_MB_STATUS_RECV_PENDING) && (timeout > 0U));
+ }
+
+ (void)psci_cpu_off();
while (1) {
wfi();
@@ -161,6 +186,7 @@
*/
static void versal_pwr_domain_off(const psci_power_state_t *target_state)
{
+ uint32_t ret, fw_api_version, version[PAYLOAD_ARG_CNT] = {0U};
uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
@@ -180,8 +206,17 @@
* invoking CPU_on function, during which resume address will
* be set.
*/
- (void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
- SECURE_FLAG);
+ ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version[0], SECURE_FLAG);
+ if (ret == PM_RET_SUCCESS) {
+ fw_api_version = version[0] & 0xFFFFU;
+ if (fw_api_version >= 3U) {
+ (void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
+ SECURE_FLAG);
+ } else {
+ (void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
+ SECURE_FLAG);
+ }
+ }
}
/**
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 35d6bc7..2f07996 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -11,6 +11,8 @@
PL011_GENERIC_UART := 1
IPI_CRC_CHECK := 0
HARDEN_SLS_ALL := 0
+CPU_PWRDWN_SGI ?= 6
+$(eval $(call add_define_val,CPU_PWR_DOWN_REQ_INTR,ARM_IRQ_SEC_SGI_${CPU_PWRDWN_SGI}))
# A72 Erratum for SoC
ERRATA_A72_859971 := 1
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index b30254d..4441d3e 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -17,7 +17,6 @@
#include "pm_svc_main.h"
/* SMC function IDs for SiP Service queries */
-#define VERSAL_SIP_SVC_CALL_COUNT U(0x8200ff00)
#define VERSAL_SIP_SVC_UID U(0x8200ff01)
#define VERSAL_SIP_SVC_VERSION U(0x8200ff03)
@@ -100,10 +99,6 @@
/* Let PM SMC handler deal with PM-related requests */
switch (smc_fid) {
- case VERSAL_SIP_SVC_CALL_COUNT:
- /* PM functions + default functions */
- SMC_RET1(handle, 2);
-
case VERSAL_SIP_SVC_UID:
SMC_UUID_RET(handle, versal_sip_uuid);
diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c
index 197d047..1750d35 100644
--- a/plat/xilinx/versal/versal_gicv3.c
+++ b/plat/xilinx/versal/versal_gicv3.c
@@ -62,8 +62,8 @@
}
static const gicv3_driver_data_t versal_gic_data __unused = {
- .gicd_base = PLAT_GICD_BASE_VALUE,
- .gicr_base = PLAT_GICR_BASE_VALUE,
+ .gicd_base = PLAT_ARM_GICD_BASE,
+ .gicr_base = PLAT_ARM_GICR_BASE,
.interrupt_props = versal_interrupt_props,
.interrupt_props_num = ARRAY_SIZE(versal_interrupt_props),
.rdistif_num = PLATFORM_CORE_COUNT,
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
index dab8717..1ae879f 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
+++ b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
@@ -12,6 +12,7 @@
#include <platform_def.h>
+ .globl plat_arm_calc_core_pos
.globl plat_secondary_cold_boot_setup
.globl plat_is_my_cpu_primary
.globl platform_mem_init
@@ -58,6 +59,16 @@
b plat_core_pos_by_mpidr
endfunc plat_my_core_pos
+ /* -----------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ * This function uses the plat_core_pos_by_mpidr()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_arm_calc_core_pos
+ b plat_core_pos_by_mpidr
+endfunc plat_arm_calc_core_pos
+
/* ---------------------------------------------------------------------
* We don't need to carry out any memory initialization on Versal NET
* platform. The Secure RAM is accessible straight away.
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 283fee3..614d6d2 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -216,8 +216,8 @@
prepare_dtb();
/* Initialize the gic cpu and distributor interfaces */
- plat_versal_net_gic_driver_init();
- plat_versal_net_gic_init();
+ plat_arm_gic_driver_init();
+ plat_arm_gic_init();
}
void bl31_plat_runtime_setup(void)
diff --git a/plat/xilinx/versal_net/include/plat_macros.S b/plat/xilinx/versal_net/include/plat_macros.S
index db7e42b..57f8336 100644
--- a/plat/xilinx/versal_net/include/plat_macros.S
+++ b/plat/xilinx/versal_net/include/plat_macros.S
@@ -109,8 +109,8 @@
* Uncomment it when versions are stable
*/
/*
- mov_imm x17, PLAT_GICD_BASE_VALUE
- mov_imm x16, PLAT_GICR_BASE_VALUE
+ mov_imm x17, PLAT_ARM_GICD_BASE
+ mov_imm x16, PLAT_ARM_GICR_BASE
versal_net_print_gic_regs
*/
.endm
diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h
index 872b6ee..8cb7deb 100644
--- a/plat/xilinx/versal_net/include/platform_def.h
+++ b/plat/xilinx/versal_net/include/platform_def.h
@@ -10,6 +10,7 @@
#define PLATFORM_DEF_H
#include <arch.h>
+#include <plat_common.h>
#include "versal_net_def.h"
/*******************************************************************************
@@ -107,8 +108,8 @@
#define CACHE_WRITEBACK_SHIFT U(6)
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
-#define PLAT_GICD_BASE_VALUE U(0xE2000000)
-#define PLAT_GICR_BASE_VALUE U(0xE2060000)
+#define PLAT_ARM_GICD_BASE U(0xE2000000)
+#define PLAT_ARM_GICR_BASE U(0xE2060000)
/*
* Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -118,13 +119,15 @@
#define PLAT_VERSAL_NET_IPI_IRQ 89
#define PLAT_VERSAL_IPI_IRQ PLAT_VERSAL_NET_IPI_IRQ
-#define PLAT_VERSAL_NET_G1S_IRQ_PROPS(grp) \
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
INTR_PROP_DESC(VERSAL_NET_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL)
-#define PLAT_VERSAL_NET_G0_IRQ_PROPS(grp) \
+#define PLAT_ARM_G0_IRQ_PROPS(grp) \
INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(CPU_PWR_DOWN_REQ_INTR, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE)
#define IRQ_MAX 200U
diff --git a/plat/xilinx/versal_net/plat_psci.c b/plat/xilinx/versal_net/plat_psci.c
index 6e556cd..fcb32b9 100644
--- a/plat/xilinx/versal_net/plat_psci.c
+++ b/plat/xilinx/versal_net/plat_psci.c
@@ -108,8 +108,8 @@
static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
- plat_versal_net_gic_pcpu_init();
- plat_versal_net_gic_cpuif_enable();
+ plat_arm_gic_pcpu_init();
+ plat_arm_gic_cpuif_enable();
}
static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 87e25bc..94cb7f5 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -14,10 +14,12 @@
#include <plat/common/platform.h>
#include <plat_arm.h>
+#include <drivers/delay_timer.h>
#include <plat_private.h>
#include "pm_api_sys.h"
#include "pm_client.h"
#include <pm_common.h>
+#include "pm_ipi.h"
#include "pm_svc_main.h"
#include "versal_net_def.h"
@@ -57,6 +59,7 @@
*/
static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
{
+ uint32_t ret, fw_api_version, version[PAYLOAD_ARG_CNT] = {0U};
uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
@@ -66,7 +69,7 @@
}
/* Prevent interrupts from spuriously waking up this cpu */
- plat_versal_net_gic_cpuif_disable();
+ plat_arm_gic_cpuif_disable();
/*
* Send request to PMC to power down the appropriate APU CPU
@@ -76,8 +79,17 @@
* invoking CPU_on function, during which resume address will
* be set.
*/
- pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
- SECURE_FLAG);
+ ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version[0], SECURE_FLAG);
+ if (ret == PM_RET_SUCCESS) {
+ fw_api_version = version[0] & 0xFFFFU;
+ if (fw_api_version >= 3U) {
+ (void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
+ SECURE_FLAG);
+ } else {
+ (void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
+ SECURE_FLAG);
+ }
+ }
}
/**
@@ -88,9 +100,31 @@
*/
static void __dead2 versal_net_system_reset(void)
{
- /* Send the system reset request to the PMC */
- pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
- pm_get_shutdown_scope(), SECURE_FLAG);
+ uint32_t ret, timeout = 10000U;
+
+ request_cpu_pwrdwn();
+
+ /*
+ * Send the system reset request to the firmware if power down request
+ * is not received from firmware.
+ */
+ if (!pwrdwn_req_received) {
+ (void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
+ pm_get_shutdown_scope(), SECURE_FLAG);
+
+ /*
+ * Wait for system shutdown request completed and idle callback
+ * not received.
+ */
+ do {
+ ret = ipi_mb_enquire_status(primary_proc->ipi->local_ipi_id,
+ primary_proc->ipi->remote_ipi_id);
+ udelay(100);
+ timeout--;
+ } while ((ret != IPI_MB_STATUS_RECV_PENDING) && (timeout > 0U));
+ }
+
+ (void)psci_cpu_off();
while (1) {
wfi();
@@ -114,10 +148,10 @@
__func__, i, target_state->pwr_domain_state[i]);
}
- plat_versal_net_gic_cpuif_disable();
+ plat_arm_gic_cpuif_disable();
if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
- plat_versal_net_gic_save();
+ plat_arm_gic_save();
}
state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
@@ -135,10 +169,10 @@
(void)target_state;
/* Enable the gic cpu interface */
- plat_versal_net_gic_pcpu_init();
+ plat_arm_gic_pcpu_init();
/* Program the gic per-cpu distributor or re-distributor interface */
- plat_versal_net_gic_cpuif_enable();
+ plat_arm_gic_cpuif_enable();
}
/**
@@ -163,10 +197,10 @@
/* APU was turned off, so restore GIC context */
if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
- plat_versal_net_gic_resume();
+ plat_arm_gic_resume();
}
- plat_versal_net_gic_cpuif_enable();
+ plat_arm_gic_cpuif_enable();
}
/**
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index ad1ee2b..da91abc 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -21,6 +21,8 @@
GIC_ENABLE_V4_EXTN := 0
GICV3_SUPPORT_GIC600 := 1
TFA_NO_PM := 0
+CPU_PWRDWN_SGI ?= 6
+$(eval $(call add_define_val,CPU_PWR_DOWN_REQ_INTR,ARM_IRQ_SEC_SGI_${CPU_PWRDWN_SGI}))
override CTX_INCLUDE_AARCH32_REGS := 0
@@ -121,6 +123,7 @@
${PLAT_PATH}/bl31_versal_net_setup.c \
common/fdt_fixup.c \
common/fdt_wrappers.c \
+ plat/arm/common/arm_gicv3.c \
${LIBFDT_SRCS} \
${PLAT_PATH}/sip_svc_setup.c \
- ${PLAT_PATH}/versal_net_gicv3.c
+ ${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index 0c27dec..80d5a53 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -20,7 +20,6 @@
#include "pm_svc_main.h"
/* SMC function IDs for SiP Service queries */
-#define VERSAL_NET_SIP_SVC_CALL_COUNT (0x8200ff00U)
#define VERSAL_NET_SIP_SVC_UID (0x8200ff01U)
#define VERSAL_NET_SIP_SVC_VERSION (0x8200ff03U)
@@ -88,10 +87,6 @@
/* Let PM SMC handler deal with PM-related requests */
switch (smc_fid) {
- case VERSAL_NET_SIP_SVC_CALL_COUNT:
- /* PM functions + default functions */
- SMC_RET1(handle, 2);
-
case VERSAL_NET_SIP_SVC_UID:
SMC_UUID_RET(handle, versal_net_sip_uuid);
diff --git a/plat/xilinx/versal_net/versal_net_gicv3.c b/plat/xilinx/versal_net/versal_net_gicv3.c
deleted file mode 100644
index 2fdef12..0000000
--- a/plat/xilinx/versal_net/versal_net_gicv3.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/debug.h>
-#include <common/interrupt_props.h>
-#include <drivers/arm/gicv3.h>
-#include <lib/utils.h>
-#include <plat/common/platform.h>
-
-#include <plat_private.h>
-#include <platform_def.h>
-
-/******************************************************************************
- * The following functions are defined as weak to allow a platform to override
- * the way the GICv3 driver is initialised and used.
- *****************************************************************************/
-#pragma weak plat_versal_net_gic_driver_init
-#pragma weak plat_versal_net_gic_init
-#pragma weak plat_versal_net_gic_cpuif_enable
-#pragma weak plat_versal_net_gic_cpuif_disable
-#pragma weak plat_versal_net_gic_pcpu_init
-#pragma weak plat_versal_net_gic_redistif_on
-#pragma weak plat_versal_net_gic_redistif_off
-
-/* The GICv3 driver only needs to be initialized in EL3 */
-static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
-
-static const interrupt_prop_t versal_net_interrupt_props[] = {
- PLAT_VERSAL_NET_G1S_IRQ_PROPS(INTR_GROUP1S),
- PLAT_VERSAL_NET_G0_IRQ_PROPS(INTR_GROUP0)
-};
-
-/*
- * We save and restore the GICv3 context on system suspend. Allocate the
- * data in the designated EL3 Secure carve-out memory.
- */
-static gicv3_redist_ctx_t rdist_ctx __section(".versal_net_el3_tzc_dram");
-static gicv3_dist_ctx_t dist_ctx __section(".versal_net_el3_tzc_dram");
-
-/*
- * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
- * to core position.
- *
- * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
- * values read from GICR_TYPER don't have an MT field. To reuse the same
- * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
- * that read from GICR_TYPER.
- *
- * Assumptions:
- *
- * - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
- * - No CPUs implemented in the system use affinity level 3.
- */
-static uint32_t versal_net_gicv3_mpidr_hash(u_register_t mpidr)
-{
- mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
- return plat_core_pos_by_mpidr(mpidr);
-}
-
-static const gicv3_driver_data_t versal_net_gic_data __unused = {
- .gicd_base = PLAT_GICD_BASE_VALUE,
- .gicr_base = PLAT_GICR_BASE_VALUE,
- .interrupt_props = versal_net_interrupt_props,
- .interrupt_props_num = ARRAY_SIZE(versal_net_interrupt_props),
- .rdistif_num = PLATFORM_CORE_COUNT,
- .rdistif_base_addrs = rdistif_base_addrs,
- .mpidr_to_core_pos = versal_net_gicv3_mpidr_hash
-};
-
-void __init plat_versal_net_gic_driver_init(void)
-{
- /*
- * The GICv3 driver is initialized in EL3 and does not need
- * to be initialized again in SEL1. This is because the S-EL1
- * can use GIC system registers to manage interrupts and does
- * not need GIC interface base addresses to be configured.
- */
-#if IMAGE_BL31
- gicv3_driver_init(&versal_net_gic_data);
-#endif
-}
-
-/******************************************************************************
- * Versal NET common helper to initialize the GIC. Only invoked by BL31
- *****************************************************************************/
-void __init plat_versal_net_gic_init(void)
-{
- gicv3_distif_init();
- gicv3_rdistif_init(plat_my_core_pos());
- gicv3_cpuif_enable(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helper to enable the GIC CPU interface
- *****************************************************************************/
-void plat_versal_net_gic_cpuif_enable(void)
-{
- gicv3_cpuif_enable(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helper to disable the GIC CPU interface
- *****************************************************************************/
-void plat_versal_net_gic_cpuif_disable(void)
-{
- gicv3_cpuif_disable(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helper to initialize the per-cpu redistributor interface in
- * GICv3
- *****************************************************************************/
-void plat_versal_net_gic_pcpu_init(void)
-{
- gicv3_rdistif_init(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helpers to power GIC redistributor interface
- *****************************************************************************/
-void plat_versal_net_gic_redistif_on(void)
-{
- gicv3_rdistif_on(plat_my_core_pos());
-}
-
-void plat_versal_net_gic_redistif_off(void)
-{
- gicv3_rdistif_off(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helper to save & restore the GICv3 on resume from system
- * suspend
- *****************************************************************************/
-void plat_versal_net_gic_save(void)
-{
- /*
- * If an ITS is available, save its context before
- * the Redistributor using:
- * gicv3_its_save_disable(gits_base, &its_ctx[i])
- * Additionnaly, an implementation-defined sequence may
- * be required to save the whole ITS state.
- */
-
- /*
- * Save the GIC Redistributors and ITS contexts before the
- * Distributor context. As we only handle SYSTEM SUSPEND API,
- * we only need to save the context of the CPU that is issuing
- * the SYSTEM SUSPEND call, i.e. the current CPU.
- */
- gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
-
- /* Save the GIC Distributor context */
- gicv3_distif_save(&dist_ctx);
-
- /*
- * From here, all the components of the GIC can be safely powered down
- * as long as there is an alternate way to handle wakeup interrupt
- * sources.
- */
-}
-
-void plat_versal_net_gic_resume(void)
-{
- /* Restore the GIC Distributor context */
- gicv3_distif_init_restore(&dist_ctx);
-
- /*
- * Restore the GIC Redistributor and ITS contexts after the
- * Distributor context. As we only handle SYSTEM SUSPEND API,
- * we only need to restore the context of the CPU that issued
- * the SYSTEM SUSPEND call.
- */
- gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
-
- /*
- * If an ITS is available, restore its context after
- * the Redistributor using:
- * gicv3_its_restore(gits_base, &its_ctx[i])
- * An implementation-defined sequence may be required to
- * restore the whole ITS state. The ITS must also be
- * re-enabled after this sequence has been executed.
- */
-}
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 6a8555e..f5990ca 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -18,7 +18,6 @@
#include "zynqmp_pm_svc_main.h"
/* SMC function IDs for SiP Service queries */
-#define ZYNQMP_SIP_SVC_CALL_COUNT U(0x8200ff00)
#define ZYNQMP_SIP_SVC_UID U(0x8200ff01)
#define ZYNQMP_SIP_SVC_VERSION U(0x8200ff03)
@@ -100,10 +99,6 @@
}
switch (smc_fid) {
- case ZYNQMP_SIP_SVC_CALL_COUNT:
- /* PM functions + default functions */
- SMC_RET1(handle, PM_API_MAX + 2);
-
case ZYNQMP_SIP_SVC_UID:
SMC_UUID_RET(handle, zynqmp_sip_uuid);
diff --git a/services/spd/opteed/opteed_common.c b/services/spd/opteed/opteed_common.c
index 9aa19c5..8a769fb 100644
--- a/services/spd/opteed/opteed_common.c
+++ b/services/spd/opteed/opteed_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,9 +20,9 @@
* initialize OPTEE context and entry point info for OPTEE.
******************************************************************************/
void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
- uint32_t rw, uint64_t pc,
- uint64_t pageable_part, uint64_t mem_limit,
- uint64_t dt_addr, optee_context_t *optee_ctx)
+ uint32_t rw, uint64_t pc, uint64_t arg0,
+ uint64_t arg1, uint64_t arg2, uint64_t arg3,
+ optee_context_t *optee_ctx)
{
uint32_t ep_attr;
@@ -54,9 +54,10 @@
DAIF_IRQ_BIT |
DAIF_ABT_BIT);
zeromem(&optee_entry_point->args, sizeof(optee_entry_point->args));
- optee_entry_point->args.arg0 = pageable_part;
- optee_entry_point->args.arg1 = mem_limit;
- optee_entry_point->args.arg2 = dt_addr;
+ optee_entry_point->args.arg0 = arg0;
+ optee_entry_point->args.arg1 = arg1;
+ optee_entry_point->args.arg2 = arg2;
+ optee_entry_point->args.arg3 = arg3;
}
/*******************************************************************************
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 4d055db..ab9896e 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,6 +27,7 @@
#include <lib/coreboot.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/optee_utils.h>
+#include <lib/transfer_list.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#if OPTEE_ALLOW_SMC_LOAD
#include <libfdt.h>
@@ -37,6 +38,10 @@
#include "opteed_private.h"
#include "teesmc_opteed.h"
+#if OPTEE_ALLOW_SMC_LOAD
+static struct transfer_list_header *bl31_tl;
+#endif
+
/*******************************************************************************
* Address of the entrypoint vector table in OPTEE. It is
* initialised once on the primary core after a cold boot.
@@ -123,9 +128,13 @@
#else
entry_point_info_t *optee_ep_info;
uint32_t linear_id;
- uint64_t opteed_pageable_part;
- uint64_t opteed_mem_limit;
- uint64_t dt_addr;
+ uint64_t arg0;
+ uint64_t arg1;
+ uint64_t arg2;
+ uint64_t arg3;
+ struct transfer_list_header *tl = NULL;
+ struct transfer_list_entry *te = NULL;
+ void *dt = NULL;
linear_id = plat_my_core_pos();
@@ -150,17 +159,39 @@
if (!optee_ep_info->pc)
return 1;
- opteed_rw = optee_ep_info->args.arg0;
- opteed_pageable_part = optee_ep_info->args.arg1;
- opteed_mem_limit = optee_ep_info->args.arg2;
- dt_addr = optee_ep_info->args.arg3;
+ if (TRANSFER_LIST &&
+ optee_ep_info->args.arg1 == (TRANSFER_LIST_SIGNATURE |
+ REGISTER_CONVENTION_VERSION_MASK)) {
+ tl = (void *)optee_ep_info->args.arg3;
+ if (transfer_list_check_header(tl) == TL_OPS_NON) {
+ return 1;
+ }
- opteed_init_optee_ep_state(optee_ep_info,
- opteed_rw,
- optee_ep_info->pc,
- opteed_pageable_part,
- opteed_mem_limit,
- dt_addr,
+ opteed_rw = GET_RW(optee_ep_info->spsr);
+ te = transfer_list_find(tl, TL_TAG_FDT);
+ dt = transfer_list_entry_data(te);
+
+ if (opteed_rw == OPTEE_AARCH64) {
+ arg0 = (uint64_t)dt;
+ arg2 = 0;
+ } else {
+ arg2 = (uint64_t)dt;
+ arg0 = 0;
+ }
+
+ arg1 = optee_ep_info->args.arg1;
+ arg3 = optee_ep_info->args.arg3;
+ } else {
+ /* Default handoff arguments */
+ opteed_rw = optee_ep_info->args.arg0;
+ arg0 = optee_ep_info->args.arg1; /* opteed_pageable_part */
+ arg1 = optee_ep_info->args.arg2; /* opteed_mem_limit */
+ arg2 = optee_ep_info->args.arg3; /* dt_addr */
+ arg3 = 0;
+ }
+
+ opteed_init_optee_ep_state(optee_ep_info, opteed_rw, optee_ep_info->pc,
+ arg0, arg1, arg2, arg3,
&opteed_sp_context[linear_id]);
/*
@@ -302,6 +333,26 @@
return fdt_finish(fdt_buf);
}
+static int32_t create_smc_tl(const void *fdt, uint32_t fdt_sz)
+{
+#if TRANSFER_LIST
+ bl31_tl = transfer_list_init((void *)(uintptr_t)FW_HANDOFF_BASE,
+ FW_HANDOFF_SIZE);
+ if (!bl31_tl) {
+ ERROR("Failed to initialize Transfer List at 0x%lx\n",
+ (unsigned long)FW_HANDOFF_BASE);
+ return -1;
+ }
+
+ if (!transfer_list_add(bl31_tl, TL_TAG_FDT, fdt_sz, fdt)) {
+ return -1;
+ }
+ return 0;
+#else
+ return -1;
+#endif
+}
+
/*******************************************************************************
* This function is responsible for handling the SMC that loads the OP-TEE
* binary image via a non-secure SMC call. It takes the size and physical
@@ -326,6 +377,10 @@
entry_point_info_t optee_ep_info;
uint32_t linear_id = plat_my_core_pos();
uint64_t dt_addr = 0;
+ uint64_t arg0 = 0;
+ uint64_t arg1 = 0;
+ uint64_t arg2 = 0;
+ uint64_t arg3 = 0;
mapped_data_pa = page_align(data_pa, DOWN);
mapped_data_va = mapped_data_pa;
@@ -394,12 +449,36 @@
dt_addr = (uint64_t)fdt_buf;
flush_dcache_range(dt_addr, OPTEED_FDT_SIZE);
+ if (TRANSFER_LIST &&
+ !create_smc_tl((void *)dt_addr, OPTEED_FDT_SIZE)) {
+ struct transfer_list_entry *te = NULL;
+ void *dt = NULL;
+
+ te = transfer_list_find(bl31_tl, TL_TAG_FDT);
+ dt = transfer_list_entry_data(te);
+
+ if (opteed_rw == OPTEE_AARCH64) {
+ arg0 = (uint64_t)dt;
+ arg2 = 0;
+ } else {
+ arg2 = (uint64_t)dt;
+ arg0 = 0;
+ }
+ arg1 = TRANSFER_LIST_SIGNATURE |
+ REGISTER_CONVENTION_VERSION_MASK;
+ arg3 = (uint64_t)bl31_tl;
+ } else {
+ /* Default handoff arguments */
+ arg2 = dt_addr;
+ }
+
opteed_init_optee_ep_state(&optee_ep_info,
opteed_rw,
image_pa,
- 0,
- 0,
- dt_addr,
+ arg0,
+ arg1,
+ arg2,
+ arg3,
&opteed_sp_context[linear_id]);
if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
rc = -EFAULT;
diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c
index fa724a1..c949823 100644
--- a/services/spd/opteed/opteed_pm.c
+++ b/services/spd/opteed/opteed_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -113,7 +113,7 @@
opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
(uint64_t)&optee_vector_table->cpu_on_entry,
- 0, 0, 0, optee_ctx);
+ 0, 0, 0, 0, optee_ctx);
/* Initialise this cpu's secure context */
cm_init_my_context(&optee_on_entrypoint);
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index c8fbc22..c484516 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -148,11 +148,8 @@
uint64_t opteed_synchronous_sp_entry(optee_context_t *optee_ctx);
void __dead2 opteed_synchronous_sp_exit(optee_context_t *optee_ctx, uint64_t ret);
void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
- uint32_t rw,
- uint64_t pc,
- uint64_t pageable_part,
- uint64_t mem_limit,
- uint64_t dt_addr,
+ uint32_t rw, uint64_t pc, uint64_t arg0,
+ uint64_t arg1, uint64_t arg2, uint64_t arg3,
optee_context_t *optee_ctx);
void opteed_cpu_on_finish_handler(u_register_t unused);
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index 537cb5c..f1342ad 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -237,12 +237,13 @@
[3] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638},
[4] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749},
[5] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411},
- [6] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \
+ [6] = {2683027, 0x01, 0x02, ERRATA_A78C_2683027},
+ [7] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \
ERRATA_NON_ARM_INTERCONNECT},
- [7] = {2743232, 0x01, 0x02, ERRATA_A78C_2743232},
- [8] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
- [9] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
- [10 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+ [8] = {2743232, 0x01, 0x02, ERRATA_A78C_2743232},
+ [9] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
+ [10] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
+ [11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A78C_H_INC */
@@ -446,12 +447,14 @@
.cpu_partnumber = CORTEX_X3_MIDR,
.cpu_errata_list = {
[0] = {2070301, 0x00, 0x12, ERRATA_X3_2070301},
- [1] = {2313909, 0x00, 0x10, ERRATA_X3_2313909},
- [2] = {2615812, 0x00, 0x11, ERRATA_X3_2615812},
- [3] = {2742421, 0x00, 0x11, ERRATA_X3_2742421},
- [4] = {2743088, 0x00, 0x11, ERRATA_X3_2743088},
- [5] = {2779509, 0x00, 0x11, ERRATA_X3_2779509},
- [6 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+ [1] = {2266875, 0x00, 0x10, ERRATA_X3_2266875},
+ [2] = {2302506, 0x00, 0x11, ERRATA_X3_2302506},
+ [3] = {2313909, 0x00, 0x10, ERRATA_X3_2313909},
+ [4] = {2615812, 0x00, 0x11, ERRATA_X3_2615812},
+ [5] = {2742421, 0x00, 0x11, ERRATA_X3_2742421},
+ [6] = {2743088, 0x00, 0x11, ERRATA_X3_2743088},
+ [7] = {2779509, 0x00, 0x11, ERRATA_X3_2779509},
+ [8 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_X3_H_INC */
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 3bdf4a2..72bc33f 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -295,7 +295,7 @@
}
/* If MTE is implemented in the client el set the TCO bit */
- if (get_armv8_5_mte_support() >= MTE_IMPLEMENTED_ELX) {
+ if (is_feat_mte_supported()) {
sdei_spsr |= SPSR_TCO_BIT_AARCH64;
}
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 1d0bd00..5d19868 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -1151,6 +1151,25 @@
}
break; /* Not reached */
+ case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
+ if (!secure_origin) {
+ /* Validate source endpoint is non-secure for non-secure caller. */
+ if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) {
+ return spmd_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+ }
+ /* FFA_MSG_SEND_DIRECT_REQ2 not used for framework messages. */
+ if (secure_origin && spmd_is_spmc_message(x1)) {
+ return spmd_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
+ } else {
+ /* Forward direct message to the other world */
+ return spmd_smc_forward(smc_fid, secure_origin,
+ x1, x2, x3, x4, cookie,
+ handle, flags);
+ }
+ break; /* Not reached */
+
case FFA_MSG_SEND_DIRECT_RESP_SMC32:
case FFA_MSG_SEND_DIRECT_RESP_SMC64:
if (secure_origin && (spmd_is_spmc_message(x1) ||
@@ -1163,7 +1182,12 @@
handle, flags);
}
break; /* Not reached */
-
+ case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
+ /* Forward direct message to the other world */
+ return spmd_smc_forward(smc_fid, secure_origin,
+ x1, x2, x3, x4, cookie,
+ handle, flags);
+ break; /* Not reached */
case FFA_RX_RELEASE:
case FFA_RXTX_MAP_SMC32:
case FFA_RXTX_MAP_SMC64:
diff --git a/plat/arm/board/juno/fip/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/arm/board/juno/plat_def_uuid_config.c
similarity index 100%
rename from plat/arm/board/juno/fip/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/arm/board/juno/plat_def_uuid_config.c
diff --git a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
index fef2116..5549b0d 100644
--- a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
@@ -11,6 +11,6 @@
ifeq (${ETHOSN_NPU_TZMP1},1)
HOSTCCFLAGS += -DETHOSN_NPU_TZMP1
endif
-INCLUDE_PATHS += -I./ -I${PLAT_DIR}fip -I../../include/
-OBJECTS += ${PLAT_DIR}fip/plat_def_uuid_config.o
+INCLUDE_PATHS += -I./ -I../../plat/arm/board/juno/fip -I../../include
+OBJECTS += plat_fiptool/arm/board/juno/plat_def_uuid_config.o
endif
diff --git a/tools/marvell/doimage/doimage.c b/tools/marvell/doimage/doimage.c
index 513f33f..1f0985c 100644
--- a/tools/marvell/doimage/doimage.c
+++ b/tools/marvell/doimage/doimage.c
@@ -18,6 +18,7 @@
#include <libconfig.h> /* for parsing config file */
/* mbedTLS stuff */
+#include <mbedtls/version.h>
#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ENTROPY_C) && \
defined(MBEDTLS_SHA256_C) && \
defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO) && \
@@ -28,7 +29,6 @@
#include <mbedtls/md.h>
#include <mbedtls/pk.h>
#include <mbedtls/sha256.h>
-#include <mbedtls/version.h>
#include <mbedtls/x509.h>
#else
#error "Bad mbedTLS configuration!"
diff --git a/tools/memory/memory/memmap.py b/tools/memory/memory/memmap.py
index 99149b5..34f5069 100755
--- a/tools/memory/memory/memmap.py
+++ b/tools/memory/memory/memmap.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
#
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -99,7 +99,7 @@
if symbols:
expr = (
- r"(.*)(TEXT|BSS|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF"
+ r"(.*)(TEXT|BSS|RO|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF|RELA"
r"|R.M)(.*)(START|UNALIGNED|END)__$"
)
printer.print_symbol_table(
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 06fa520..1edb77d 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -137,7 +137,7 @@
with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
load_address_lines = [l for l in pm_f if 'load-address' in l]
- if len(load_address_lines) is not 1:
+ if len(load_address_lines) != 1:
return None
load_address_parsed = re.search("(0x[0-9a-f]+)", load_address_lines[0])