Merge changes from topic "errata" into integration
* changes:
fix(cpus): workaround for Cortex-A78C erratum 2683027
fix(cpus): workaround for Cortex-X3 erratum 2266875
fix(cpus): workaround for Cortex-X3 erratum 2302506
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
- then
- exit_code=1
- sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$ARM_RGX\)/\1-$(date +"%Y"), Arm/" $FILE
- user_warning
- 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
+ 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
+ # 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
+ fi
+
done <<< "$FILES"
if [ $exit_code -eq 1 ]
diff --git a/changelog.yaml b/changelog.yaml
index c5e157d..f67ad29 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -1369,6 +1369,9 @@
deprecated:
- cert_create
+ - title: Marvell Tools
+ scope: marvell-tools
+
- title: Dependencies
scope: deps
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/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,51 +533,27 @@
}
/*
- * 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)
+static 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)
-{
- 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);
-}
-
-/*
- * 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);
+ return mmio_read_32(BSEC_BASE + BSEC_IP_ID_OFF);
}
/*
@@ -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/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
+ * 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 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
- */
-#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/services/ffa_svc.h b/include/services/ffa_svc.h
index 9ed6a8b..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,10 @@
/* 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)
/* FFA SMC32 FIDs */
#define FFA_ERROR FFA_FID(SMC_32, FFA_FNUM_ERROR)
@@ -171,6 +175,7 @@
#define FFA_EL3_INTR_HANDLE FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
#define FFA_MEM_PERM_GET FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
#define FFA_MEM_PERM_SET FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
+#define FFA_CONSOLE_LOG_SMC32 FFA_FID(SMC_32, FFA_FNUM_CONSOLE_LOG)
/* FFA SMC64 FIDs */
#define FFA_ERROR_SMC64 FFA_FID(SMC_64, FFA_FNUM_ERROR)
@@ -191,6 +196,11 @@
FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
#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/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/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/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/aarch64/stm32mp2_helper.S b/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
index 66333ad..0df3e08 100644
--- a/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
+++ b/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
@@ -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
*/
@@ -14,6 +14,7 @@
.globl platform_mem_init
.globl plat_secondary_cold_boot_setup
.globl plat_is_my_cpu_primary
+ .globl plat_my_core_pos
.globl plat_crash_console_init
.globl plat_crash_console_flush
.globl plat_crash_console_putc
@@ -32,9 +33,14 @@
*/
func plat_secondary_cold_boot_setup
dsb sy
+1:
wfi
- /* This shouldn't be reached */
- b .
+ /*
+ * This shouldn't be reached, but when a debugger halts the
+ * secondary core it causes exit from wfi.
+ * Put back the core in wfi.
+ */
+ b 1b
endfunc plat_secondary_cold_boot_setup
/* ----------------------------------------------
@@ -50,6 +56,31 @@
ret
endfunc plat_is_my_cpu_primary
+ /* -----------------------------------------------------------
+ * unsigned int plat_stm32mp_get_core_pos(u_register_t mpidr)
+ * Helper function to calculate the core position.
+ * With this function: CorePos = (ClusterId * 4) +
+ * CoreId
+ * -----------------------------------------------------------
+ */
+func plat_stm32mp_get_core_pos
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #6
+ ret
+endfunc plat_stm32mp_get_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses the plat_stm32mp_get_core_pos()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b plat_stm32mp_get_core_pos
+endfunc plat_my_core_pos
+
/* ---------------------------------------------
* int plat_crash_console_init(void)
*
@@ -65,13 +96,13 @@
str x0, [x1]
1:
ldr x0, [x1]
- ands x2, x0, x2
+ tst x0, #DEBUG_UART_RST_BIT
beq 1b
- bic x2, x2, #DEBUG_UART_RST_BIT
- str x2, [x1]
+ bic x0, x0, #DEBUG_UART_RST_BIT
+ str x0, [x1]
2:
ldr x0, [x1]
- ands x2, x0, x2
+ tst x0, #DEBUG_UART_RST_BIT
bne 2b
/* Enable GPIOs for UART TX */
mov_imm x1, (RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
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,21 +33,63 @@
#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());
+}
- cpu = plat_my_core_pos() + 1U;
+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();
- reg = (cpu | (sgi << XSCUGIC_SGIR_EL1_INITID_SHIFT));
- write_icc_asgi1r_el1(reg);
+ VERBOSE("Powering down CPU %d\n", cpu_id);
+
+ /* Deactivate CPU power down SGI */
+ plat_ic_end_of_interrupt(CPU_PWR_DOWN_REQ_INTR);
+
+ 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,
@@ -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/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index 7978f08..9cfcd87 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -1,11 +1,12 @@
/*
- * 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
*/
#include <assert.h>
#include <errno.h>
+#include <stdio.h>
#include <arch_helpers.h>
#include <bl31/bl31.h>
@@ -1290,6 +1291,8 @@
case FFA_MSG_SEND_DIRECT_RESP_SMC64:
case FFA_MEM_RELINQUISH:
case FFA_MSG_WAIT:
+ case FFA_CONSOLE_LOG_SMC32:
+ case FFA_CONSOLE_LOG_SMC64:
if (!secure_origin) {
return spmc_ffa_error_return(handle,
@@ -1476,6 +1479,61 @@
SMC_RET1(handle, FFA_SUCCESS_SMC32);
}
+static uint64_t spmc_ffa_console_log(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ char *chars;
+ size_t chars_max;
+ size_t chars_count = x1;
+
+ /* Does not support request from Nwd. */
+ if (!secure_origin) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ assert(smc_fid == FFA_CONSOLE_LOG_SMC32 || smc_fid == FFA_CONSOLE_LOG_SMC64);
+ if (smc_fid == FFA_CONSOLE_LOG_SMC32) {
+ uint32_t registers[] = {
+ (uint32_t)x2,
+ (uint32_t)x3,
+ (uint32_t)x4,
+ (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X5),
+ (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X6),
+ (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X7),
+ };
+ chars_max = ARRAY_SIZE(registers) * sizeof(uint32_t);
+ chars = (char *)registers;
+ } else {
+ uint64_t registers[] = {
+ x2,
+ x3,
+ x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7),
+ };
+ chars_max = ARRAY_SIZE(registers) * sizeof(uint64_t);
+ chars = (char *)registers;
+ }
+
+ if ((chars_count == 0) || (chars_count > chars_max)) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ for (size_t i = 0; (i < chars_count) && (chars[i] != '\0'); i++) {
+ putchar(chars[i]);
+ }
+
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+}
+
/*
* Perform initial validation on the provided secondary entry point.
* For now ensure it does not lie within the BL31 Image or the SP's
@@ -2365,7 +2423,11 @@
case FFA_MEM_RECLAIM:
return spmc_ffa_mem_reclaim(smc_fid, secure_origin, x1, x2, x3,
- x4, cookie, handle, flags);
+ x4, cookie, handle, flags);
+ case FFA_CONSOLE_LOG_SMC32:
+ case FFA_CONSOLE_LOG_SMC64:
+ return spmc_ffa_console_log(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
case FFA_MEM_PERM_GET:
return ffa_mem_perm_get_handler(smc_fid, secure_origin, x1, x2,
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 066571e..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:
@@ -1279,6 +1303,12 @@
handle, flags);
break; /* Not reached */
#endif
+ case FFA_CONSOLE_LOG_SMC32:
+ case FFA_CONSOLE_LOG_SMC64:
+ /* This interface must not be forwarded to other worlds. */
+ return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+ break; /* not reached */
+
case FFA_EL3_INTR_HANDLE:
if (secure_origin) {
return spmd_handle_group0_intr_swd(handle);
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])