diff options
115 files changed, 3407 insertions, 587 deletions
@@ -121,6 +121,10 @@ else ifeq (${BRANCH_PROTECTION},3) # Extend the signing to include leaf functions BP_OPTION := pac-ret+leaf ENABLE_PAUTH := 1 +else ifeq (${BRANCH_PROTECTION},4) + # Turn on branch target identification mechanism + BP_OPTION := bti + ENABLE_BTI := 1 else $(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION}) endif diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst new file mode 100644 index 000000000..cc69d79b4 --- /dev/null +++ b/docs/components/cot-binding.rst @@ -0,0 +1,287 @@ +Chain of trust bindings +======================= + +The device tree allows to describes the chain of trust with the help of +certificates and images nodes, which in turn contains number of sub-nodes +(i.e. certificate and image) mentioning properties for every certificate +and image respectively. +Also, this binding allows to describe OID of non-volatile counters, memory +mapped address and size of non-volatile counter register. + +Convention used in this document +-------------------------------- + +This document follows the conventions described in the Device-tree +Specification + +certificates, certificate and extension node bindings definition +---------------------------------------------------------------- + +- Certificates node + Description: Container of certificate nodes. + + PROPERTIES + + - compatible: + Usage: required + + Value type: <string> + + Definition: must be "arm, certificate-descriptors" + +- Certificate node + Description: Describes certificate properties which are used + during the authentication process. + + PROPERTIES + + - root-certificate + Usage: Required for the certificate with no parent. + In other words, Certificates which are validated + using root of trust public key. + + Value type: <boolean> + + - image-id + Usage: Required for every certificate with unique id. + + Value type: <u32> + + - parent + Usage: It refers to their parent image, which typically contains + information to authenticate the certificate. + This property is required for all non-root certificates. + + This property is not required for root-certificates + as it is validated using root of trust public key + provided by platform. + + Value type: <phandle> + + - signing-key + Usage: This property is used to refer extension node present in + parent certificate 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. + + Value type: <phandle> + + - antirollback-counter + Usage: This property is used by all certificates which are protected + against rollback attacks using a non-volatile counter and it + is optional property. + + This property is used to refer trusted or non-trusted + non-volatile counter node. + + Value type: <phandle> + + SUBNODES + + - extensions node + Description: This is sub-node of certificate node. + Describes OIDs present in the certificate which will + be used during authentication process to extract + hash/public key information from this certificate. + OIDs in extension node are represented using number of + sub-nodes which contains 'oid' as property + + PROPERTIES + + - oid + Usage: This property provides the Object ID of an extension + provided in the certificate. + + Value type: <string> + +Example: + +.. code:: c + + certificates { + compatible = "arm, certificate-descriptors” + + trusted-key-cert: trusted-key-cert { + root-certificate; + image-id = <TRUSTED_KEY_CERT_ID>; + antirollback-counter = <&trusted_nv_counter>; + extensions { + trusted-world-pk: trusted-world-pk { + oid = TRUSTED_WORLD_PK_OID; + }; + non-trusted-world-pk: non-trusted-world-pk { + oid = NON_TRUSTED_WORLD_PK_OID; + }; + }; + }; + + scp_fw_key_cert: scp_fw_key_cert { + image-id = <SCP_FW_KEY_CERT_ID>; + parent = <&trusted-key-cert>; + signing-key = <&trusted_world_pk>; + antirollback-counter = <&trusted_nv_counter>; + extensions { + scp_fw_content_pk: scp_fw_content_pk { + oid = SCP_FW_CONTENT_CERT_PK_OID; + }; + }; + }; + + . + . + . + + next-cert { + + }; + }; + +Images and image node bindings definition +----------------------------------------- + +- Images node + Description: Container of image nodes + + PROPERTIES + + - compatible: + Usage: required + + Value type: <string> + + Definition: must be "arm, image-descriptors" + +- Image node + Description: Describes image properties which will be used during + authentication process. + + PROPERTIES + + - image-id + Usage: Required for every image with unique id. + + Value type: <u32> + + - parent + Usage: Required for every image to provide a reference to + it's parent image, which contains the necessary information + to authenticate it. + + Value type: <phandle> + + - hash + Usage: Required for all images which are validated using + hash method. This property is used to refer extension + node present in parent certificate and it is required + property for all images. + + Value type: <phandle> + + Note: Currently, all images are validated using "hash" + method. In future, there may be multiple methods can + be used to validate the image. + +Example: + +.. code:: c + + images { + compatible = "arm, imgage-descriptors"; + + scp_bl2_image { + image-id = <SCP_BL2_IMAGE_ID>; + parent = <&scp_fw_content_cert>; + hash = <&scp_fw_hash>; + }; + + . + . + . + + next-img { + }; + }; + +non-volatile counter node binding definition +-------------------------------------------- + +- non-volatile counters node + Description: Contains properties for non-volatile counters. + + PROPERTIES + + - compatible: + Usage: required + + Value type: <string> + + Definition: must be "arm, non-volatile-counter" + + - #address-cells + Usage: required + + Value type: <u32> + + Definition: Must be set according to address size + of non-volatile counter register + + - #size-cells + Usage: required + + Value type: <u32> + + Definition: must be set to 0 + + SUBNODE + - counters node + Description: Contains various non-volatile counters present in the platform. + + PROPERTIES + + - reg + Usage: Register base address of non-volatile counter and it is required + property. + + Value type: <u32> + + - oid + Usage: This property provides the Object ID of non-volatile counter + provided in the certificate and it is required property. + + Value type: <string> + +Example: +Below is non-volatile counters example for ARM platform + +.. code:: c + + non-volatile-counters { + compatible = "arm, non-volatile-counter"; + #address-cells = <1>; + #size-cells = <0>; + + counters { + trusted-nv-counter: trusted_nv_counter { + reg = <TFW_NVCTR_BASE>; + oid = TRUSTED_FW_NVCOUNTER_OID; + }; + non_trusted_nv_counter: non_trusted_nv_counter { + reg = <NTFW_CTR_BASE>; + oid = NON_TRUSTED_FW_NVCOUNTER_OID; + + }; + }; + }; + +Future update to chain of trust binding +--------------------------------------- + +This binding document need to be revisited to generalise some terminologies +like Object IDs, extensions etc which are currently specific to X.509 +certificates. + +*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst index 0da56ec3b..902063356 100644 --- a/docs/components/fconf/index.rst +++ b/docs/components/fconf/index.rst @@ -49,8 +49,10 @@ Hence each ``populate()`` function must be registered with a specific configuration properties which is usually a device tree file. Example: + - FW_CONFIG: properties related to base address, maximum size and image id + of other DTBs etc. - TB_FW: properties related to trusted firmware such as IO policies, - base address of other DTBs, mbedtls heap info etc. + mbedtls heap info etc. - HW_CONFIG: properties related to hardware configuration of the SoC such as topology, GIC controller, PSCI hooks, CPU ID etc. @@ -88,9 +90,10 @@ explain how the properties are described for a specific backend. Refer to the Loading the property device tree ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``fconf_load_config()`` must be called to load the device tree containing -the properties' values. This must be done after the io layer is initialized, as -the |DTB| is stored on an external device (FIP). +The ``fconf_load_config(image_id)`` must be called to load fw_config and +tb_fw_config devices tree containing the properties' values. This must be done +after the io layer is initialized, as the |DTB| is stored on an external +device (FIP). .. uml:: ../../resources/diagrams/plantuml/fconf_bl1_load_config.puml diff --git a/docs/components/index.rst b/docs/components/index.rst index c5f6264e1..18b1e38bb 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -19,3 +19,4 @@ Components secure-partition-manager-design psa-ffa-manifest-binding xlat-tables-lib-v2-design + cot-binding diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 591f2f886..6b6c63933 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -227,6 +227,17 @@ For Cortex-A76, the following errata build flags are defined : - ``ERRATA_A76_1275112``: This applies errata 1275112 workaround to Cortex-A76 CPU. This needs to be enabled only for revision <= r3p0 of the CPU. +- ``ERRATA_A76_1791580``: This applies errata 1791580 workaround to Cortex-A76 + CPU. This needs to be enabled only for revision <= r4p0 of the CPU. + +- ``ERRATA_A76_1800710``: This applies errata 1800710 workaround to Cortex-A76 + CPU. This needs to be enabled only for revision <= r4p0 of the CPU. + +For Cortex-A77, the following errata build flags are defined : + +- ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77 + CPU. This needs to be enabled only for revision <= r1p1 of the CPU. + For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78 diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index b336b38e7..891a9a29b 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -83,6 +83,10 @@ Each of the Boot Loader stages may be dynamically configured if required by the platform. The Boot Loader stage may optionally specify a firmware configuration file and/or hardware configuration file as listed below: +- FW_CONFIG - The firmware configuration file. Holds properties shared across + all BLx images. + An example is the "dtb-registry" node, which contains the information about + the other device tree configurations (load-address, size, image_id). - HW_CONFIG - The hardware configuration file. Can be shared by all Boot Loader stages and also by the Normal World Rich OS. - TB_FW_CONFIG - Trusted Boot Firmware configuration file. Shared between BL1 @@ -109,8 +113,8 @@ convention: the generic hardware configuration is passed the next available argument. For example, - - If TB_FW_CONFIG is loaded by BL1, then its address is passed in ``arg0`` - to BL2. + - FW_CONFIG is loaded by BL1, then its address is passed in ``arg0`` to BL2. + - TB_FW_CONFIG address is retrieved by BL2 from FW_CONFIG device tree. - If HW_CONFIG is loaded by BL1, then its address is passed in ``arg2`` to BL2. Note, ``arg1`` is already used for meminfo_t. - If SOC_FW_CONFIG is loaded by BL2, then its address is passed in ``arg1`` @@ -1732,7 +1736,7 @@ CONFIG section in memory layouts shown below contains: ``bl2_mem_params_descs`` contains parameters passed from BL2 to next the BL image during boot. -``fw_configs`` includes soc_fw_config, tos_fw_config and tb_fw_config. +``fw_configs`` includes soc_fw_config, tos_fw_config, tb_fw_config and fw_config. **FVP with TSP in Trusted SRAM with firmware configs :** (These diagrams only cover the AArch64 case) @@ -1757,7 +1761,7 @@ BL image during boot. | | <<<<<<<<<<<<< | BL31 PROGBITS | | | <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL32 | - 0x04002000 +----------+ +----------------+ + 0x04003000 +----------+ +----------------+ | CONFIG | 0x04001000 +----------+ | Shared | @@ -1794,7 +1798,7 @@ BL image during boot. |--------------| <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL31 PROGBITS | | | +----------------+ - +--------------+ + 0x04003000 +--------------+ | CONFIG | 0x04001000 +--------------+ | Shared | @@ -1828,7 +1832,7 @@ BL image during boot. |----------| <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL31 PROGBITS | | | +----------------+ - 0x04002000 +----------+ + 0x04003000 +----------+ | CONFIG | 0x04001000 +----------+ | Shared | diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index f207886fb..81903e140 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -88,6 +88,7 @@ Common build options - 1: Enables all types of branch protection features - 2: Return address signing to its standard level - 3: Extend the signing to include leaf functions +- 4: Turn on branch target identification mechanism The table below summarizes ``BRANCH_PROTECTION`` values, GCC compilation options and resulting PAuth/BTI features. @@ -103,6 +104,8 @@ Common build options +-------+--------------+-------+-----+ | 3 | pac-ret+leaf | Y | N | +-------+--------------+-------+-----+ + | 4 | bti | N | Y | + +-------+--------------+-------+-----+ This option defaults to 0 and this is an experimental feature. Note that Pointer Authentication is enabled for Non-secure world diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index b7a93e40a..45c27ade0 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1424,7 +1424,7 @@ are platform specific. On Arm standard platforms, the arguments received are : - arg0 - Points to load address of HW_CONFIG if present + arg0 - Points to load address of FW_CONFIG arg1 - ``meminfo`` structure populated by BL1. The platform copies the contents of ``meminfo`` as it may be subsequently overwritten by BL2. @@ -1736,6 +1736,10 @@ In Arm standard platforms, the arguments received are : which is list of executable images following BL31, arg1 - Points to load address of SOC_FW_CONFIG if present + except in case of Arm FVP platform. + + In case of Arm FVP platform, Points to load address + of FW_CONFIG. arg2 - Points to load address of HW_CONFIG if present diff --git a/docs/process/security-reporting.asc b/docs/process/security-reporting.asc deleted file mode 100644 index 8c41f7bf6..000000000 --- a/docs/process/security-reporting.asc +++ /dev/null @@ -1,45 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGP Desktop 10.2.0 (Build 2317) - -mQENBFey/QMBCACyxJaLsMYU794ZfzLdY172tHXRJfP0X3b34HU35G7kYl1zNiYc -/NoygtQdtDv/aW1B2A/YTNhGge+gX4BWAREd5CYDbdPEoMWC395/qbnmMmez7YNY -PEJ9Iq9e5AayAWwZTL1zgKwdvE+WTwWok/nMbsifJSEdhdrOIHNqRcZgplUUyZ2R -sDqFtSbACO3xj4Psk8KJ23Ax7UZgULouZOJaHOnyq8F9V/U7zWvX4Odf96XaC1Em -cUTsG0kQfa7Y4Hqqjzowq366I4k2o2LAtuLPWNCvq5jjEceLs2+qV4cNLgyL2dzO -wtUL6EdkrGfkxsPHpsVKXig4wjeX9ehCSqRlABEBAAG0PVRydXN0ZWQgRmlybXdh -cmUgU2VjdXJpdHkgPHRydXN0ZWQtZmlybXdhcmUtc2VjdXJpdHlAYXJtLmNvbT6J -AYwEEAECAHYFAley/SEwFIAAAAAAIAAHcHJlZmVycmVkLWVtYWlsLWVuY29kaW5n -QHBncC5jb21wZ3BtaW1lCAsJCAcDAgEKAhkBGRhsZGFwOi8va2V5c2VydmVyLnBn -cC5jb20FGwMAAAAFFgADAgEFHgEAAAAGFQgJCgMCAAoJEDq378tFoN/QFJsH/0ly -H91LYYzKIQrbolQw7Rp47lgzH88uN1rInYpW2GaTbjwPffAhYJ4VsN8RaiFskD9m -DjMg4vY8p0jPTCUX1Acq20Wq0Ybv3HcrtjUp4ie0+rLUi3043yJyKFMWkJC2Kr+p -SobnxSrAie4HDFUgSaPoh9Qf1zXEzOavdgcziMiyS5iVUf6NXYZ9z82OTZ6TdPKS -u+L5zOHTdrV3+hD54w00Xa+EIE7u4v0to6Uwm977508hyGuvpOVq+u7+S3qJQvnY -+JheStbgLsm6CyoRjyrlTE01ujAD6hI6Ef9yMgEljOBEy4phKAJ67SCRLEOiCp5U -YHFCULwhzIyg2y3WmZSJASIEEAECAAwFAlezAnwFAwASdQAACgkQlxC4m8pXrXzd -GAf/T8YEICI9qQt2vnCtCbBvVaTc2sAphVZ51kZVDqCDPB7znDtJYRBpi/9IPELt -mYwIElMx2mqmahVaeUghmbzmcLZe8QHUi8GanO1mh+ook6uyjRojSIq6VUVV5uUf -tuscfhpilOvUclqMqYEIgXfl08YwS40Kmmj0qokwad0co0zGQ8GEhlgMi2yvJfiG -fPS0Xcn1J0980E/VgJQCAKwZvukrbb32WVwuhgepqs/4/62PZNxglcErioFt6P0A -ik4t9Hr0uErqCeEKiYtmEw5e9ioRdX7CV+tJgIk907Tpv6E0iDFRJHmJBvmsz82O -stOazS3wZ5Xck7asTqkvoyo9Z7kBDQRXsv0DAQgAsmL1UUIWyoNmYJWixSPDmclP -0ul3T1FCOsIlWTeVeshnHByYdgZOfce78ETCUoq8G7qvYm4GRrEDpqVbxqTxJioP -4Li05WDdNCKzSoqWd8ADA48gYnnJEu2NhA7ZkEC6u3+Mdbmd3M0J6nsAWeE0BV1p -F5zI600sJuoH2QNWB7Kv5N3GCFE4IgCIH8MwDo4Y4FTZtygx4GjEtSExiOIz+bpX -2+GkFCQGpIyLHLP4FmQmrsNzsIdEyFuG0IdoVuQ2PtNLiw+Wkm7CXWgRmFx/dtPN -eVnOFWdbTtjBWVv/Z6zbANos2knfc75KR4FCQ6pWRvVeJuMuMopUDkfFDMtR8QAR -AQABiQJBBBgBAgErBQJXsv0EBRsMAAAAwF0gBBkBCAAGBQJXsv0DAAoJENaB8ph8 -s9hu/nsH/Rx696ZR+1vZi5qCTUwo6s0Qa15x4OuyJEM85VgMLVY7/MZpp1Y8If6u -A5BynQpy4QIPxIRsRx6twduW9/gb8UVhpMRPyuJ+5sSv0/KeUqkPbKSUGro2zGlR -sjqPrchi6uafWZqOR/y/DNkEvkgZZaP+f9xs2qWKuoF08yTioo76QoroA4DVuVAT -MkDFe9d3natAmfmjO4kvxuthg3y7R+sdXrCHpYYJZdbiR6gyj7e8whlSLwHQT3lz -7QBL/CvVvL/dmhu5pk8fsksbehepMQTkCJ6GGEamOPEhwh7IvlzhEt97U4uzjuMd -BPjqOCes+4QTmn/+lMTySG0kXxnHOEUACgkQOrfvy0Wg39D8Jgf/Uf3epkMOJ9xm -N1l5vW8tQQ6RR055YQxQ9P6JMyCQGEJmGOcvrasCho69wMQDy4AYVtJaZd25LH/3 -LX/lcyDOP4C9VYXM+IxlcaRmjBKqWx9UzQeeioIkfmjMpJFU846ZP1dacge0lPx8 -p6ocPbM0rkv0xuF/dwkDQd4BPSmv4/3/UM8FRoYo8Q7SHkDR98wJ8FCm6k9wRtWC -K/jzmBswY2TewAHom3jLzTM0FZ/n5Sini3EGAI2EvnQrxWRpeE7ZOkHKqLHEOaHl -zeST4U/cUgxhwgnhbGJ7zmrFsHpYnnZYM3mIKfQ3/EhksZ68TF9IB1tfUiQTij4r -9jWa0ybRdQ== -=nZZb ------END PGP PUBLIC KEY BLOCK----- diff --git a/docs/process/security.rst b/docs/process/security.rst index c3935daa1..516eb98d7 100644 --- a/docs/process/security.rst +++ b/docs/process/security.rst @@ -20,40 +20,13 @@ Found a Security Issue? Although we try to keep TF-A secure, we can only do so with the help of the community of developers and security researchers. -If you think you have found a security vulnerability, please **do not** report it -in the `issue tracker`_. Instead send an email to -trusted-firmware-security@arm.com - -Please include: - -* Trusted Firmware-A version (or commit) affected - -* A description of the concern or vulnerability - -* Details on how to replicate the vulnerability, including: - - - Configuration details - - - Proof of concept exploit code - - - Any additional software or tools required - -We recommend using :download:`this PGP/GPG key <./security-reporting.asc>` for -encrypting the information. This key is also available at -http://keyserver.pgp.com and LDAP port 389 of the same server. - -The fingerprint for this key is: - -:: - - 1309 2C19 22B4 8E87 F17B FE5C 3AB7 EFCB 45A0 DFD0 - -If you would like replies to be encrypted, please provide your public key. - -Please give us the time to respond to you and fix the vulnerability before going -public. We do our best to respond and fix any issues quickly. We also need to -ensure providers of products that use TF-A have a chance to consider the -implications of the vulnerability and its remedy. +If you think you have found a security vulnerability, please **do not** report +it in the `issue tracker`_. Instead, please follow the `TrustedFirmware.org +security incident process`_. One of the goals of this process is to ensure +providers of products that use TF-A have a chance to consider the implications +of the vulnerability and its remedy before it is made public. As such, please +follow the disclosure plan outlined in the process. We do our best to respond +and fix any issues quickly. Afterwards, we encourage you to write-up your findings about the TF-A source code. @@ -61,8 +34,8 @@ code. Attribution ----------- -We will name and thank you in the :ref:`Change Log & Release Notes` distributed with the source -code and in any published security advisory. +We will name and thank you in the :ref:`Change Log & Release Notes` distributed +with the source code and in any published security advisory. Security Advisories ------------------- @@ -96,7 +69,6 @@ Security Advisories +-----------+------------------------------------------------------------------+ .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/ -.. _this PGP/GPG key: security-reporting.asc .. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)` .. |TFV-2| replace:: :ref:`Advisory TFV-2 (CVE-2017-7564)` @@ -107,6 +79,8 @@ Security Advisories .. |TFV-7| replace:: :ref:`Advisory TFV-7 (CVE-2018-3639)` .. |TFV-8| replace:: :ref:`Advisory TFV-8 (CVE-2018-19440)` +.. _TrustedFirmware.org security incident process: https://developer.trustedfirmware.org/w/collaboration/security_center/ + -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml index e613eefd0..e513ed4c3 100644 --- a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml +++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml @@ -13,6 +13,7 @@ end box box "platform common code" participant plat_bl1_common + participant fconf_dyn_cfg_getter participant fconf end box @@ -20,12 +21,17 @@ bl1_main -> fvp_bl1_setup : bl1_platform_setup() fvp_bl1_setup -> arm_bl1_setup : arm_bl1_platform_setup() arm_bl1_setup -> arm_io_storage : plat_arm_io_setup() note over arm_io_storage : register and setup fip -arm_bl1_setup -> fconf : fconf_load_config() +arm_bl1_setup -> fconf : set_fw_config_info(fw_config_base, max_size) +note over fconf + set fw_config information + (address, size, image_id) + in global dtb_infos array. +end note activate fconf - note over fconf - create and populate an - image_desc_t for FW_CONFIG - end note + arm_bl1_setup -> fconf : fconf_load_config(FW_CONFIG_ID) + fconf -> fconf : FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID) + fconf -> fconf_dyn_cfg_getter: dyn_cfg_dtb_info_getter(FW_CONFIG_ID) + fconf_dyn_cfg_getter -> fconf: fw_config_info fconf -> bl_common : load_auth_image(FW_CONFIG_ID, &image_info) activate bl_common note over bl_common @@ -33,18 +39,38 @@ activate fconf with info from plat_io_policy end note bl_common -> arm_io_storage - arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, tb_fw_cfg) - note over fconf: use staticaly defined policies in bl1 + arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, FW_CONFIG_ID) + note over fconf: use statically defined policies in bl1 + fconf <- bl_common : image_info + deactivate bl_common + note over fconf : get fw_config_dtb from image_info + arm_bl1_setup -> fconf: FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID) + fconf -> fconf_dyn_cfg_getter: dyn_cfg_dtb_info_getter(FW_CONFIG_ID) + fconf_dyn_cfg_getter -> arm_bl1_setup: fw_config_info + arm_bl1_setup -> fconf_dyn_cfg_getter: populate_dtb_registry(uintptr_t dtb) + arm_bl1_setup -> fconf: fconf_load_config(TB_FW_CONFIG_ID) + fconf -> fconf : FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID) + fconf -> fconf_dyn_cfg_getter: dyn_cfg_dtb_info_getter(TB_FW_CONFIG_ID) + fconf_dyn_cfg_getter -> fconf: tb_fw_config_info + fconf -> bl_common : load_auth_image(TB_FW_CONFIG_ID, &image_info) + activate bl_common + note over bl_common + load and auth image from fip + with info from plat_io_policy + end note + bl_common -> arm_io_storage + arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, TB_FW_CONFIG_ID) + note over fconf: use statically defined policies in bl1 fconf <- bl_common : image_info deactivate bl_common note over fconf : get tb_fw_config_dtb from image_info - fconf -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID) - fconf <- plat_bl1_common : BL2_IMAGE_DESC - note over fconf - set ep_info.args.arg0 of BL2_IMAGE_DESC - to FW_CONFIG base address + fconf -> arm_bl1_setup + arm_bl1_setup -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID) + arm_bl1_setup <- plat_bl1_common : BL2_IMAGE_DESC + note over arm_bl1_setup + set ep_info.args.arg0 of BL2_IMAGE_DESC + to FW_CONFIG base address end note -arm_bl1_setup <- fconf deactivate fconf == load & auth, prepare and jump to BL2 == diff --git a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml index 881f25343..c536ee090 100644 --- a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml +++ b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml @@ -8,6 +8,7 @@ end box box "platform common code" participant fconf participant fconf_tbbr_getter +participant fconf_dyn_cfg_getter end box box "arm platform code" #LightBlue @@ -25,10 +26,17 @@ note over arm_bl2_setup end note arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t fw_config, mem_layout) activate arm_bl2_setup - arm_bl2_setup -> fconf: fconf_polulate("TB_FW", fw_config) + arm_bl2_setup -> fconf: fconf_populate("FW_CONFIG", fw_config) activate fconf + fconf -> fconf_dyn_cfg_getter: populate_dtb_registry(uintptr_t dtb) + note over fconf_dyn_cfg_getter: read dtb_registry properties from dtb + fconf_dyn_cfg_getter -> arm_bl2_setup + arm_bl2_setup -> fconf: FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID) + fconf -> fconf_dyn_cfg_getter: dyn_cfg_dtb_info_getter(TB_FW_CONFIG_ID) + fconf_dyn_cfg_getter -> arm_bl2_setup: tb_fw_config_info + arm_bl2_setup -> fconf: fconf_populate("TB_FW_CONFIG", tb_fw_config) fconf -> fconf_tbbr_getter: fconf_populate_tbbr_dyn_config(uintptr_t dtb) - note over fconf_tbbr_getter: read tbbr propeties from dtb + note over fconf_tbbr_getter: read tbbr properties from dtb fconf -> arm_fconf_io: fconf_populate_arm_io_policies(uintptr_t dtb) note over arm_fconf_io: read arm io propeties from dtb deactivate fconf diff --git a/drivers/arm/css/scp/css_bom_bootloader.c b/drivers/arm/css/scp/css_bom_bootloader.c index 1fc1270ba..74121b487 100644 --- a/drivers/arm/css/scp/css_bom_bootloader.c +++ b/drivers/arm/css/scp/css_bom_bootloader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -51,13 +51,13 @@ typedef struct { * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 * usually resides except when ARM_BL31_IN_DRAM is * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into shared RAM and - * the tb_fw_config. + * the fw_config. */ CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); -CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); -CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); +CASSERT(SCP_BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); +CASSERT(SCP_BL2U_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); static void scp_boot_message_start(void) { diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index c5bced00d..4b21b920a 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -247,6 +247,15 @@ void gicv2_end_of_interrupt(unsigned int id) assert(driver_data != NULL); assert(driver_data->gicc_base != 0U); + /* + * Ensure the write to peripheral registers are *complete* before the write + * to GIC_EOIR. + * + * Note: The completion gurantee depends on various factors of system design + * and the barrier is the best core can do by which execution of further + * instructions waits till the barrier is alive. + */ + dsbishst(); gicc_write_EOIR(driver_data->gicc_base, id); } diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c index f28ddaa91..31e5d65f4 100644 --- a/drivers/auth/dualroot/cot.c +++ b/drivers/auth/dualroot/cot.c @@ -16,6 +16,7 @@ * Allocate static buffers to store the authentication parameters extracted from * the certificates. */ +static unsigned char fw_config_hash_buf[HASH_DER_LEN]; static unsigned char tb_fw_hash_buf[HASH_DER_LEN]; static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char hw_config_hash_buf[HASH_DER_LEN]; @@ -58,6 +59,8 @@ static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); +static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FW_CONFIG_HASH_OID); #ifdef IMAGE_BL1 static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID); @@ -165,6 +168,13 @@ static const auth_img_desc_t trusted_boot_fw_cert = { .ptr = (void *)hw_config_hash_buf, .len = (unsigned int)HASH_DER_LEN } + }, + [3] = { + .type_desc = &fw_config_hash, + .data = { + .ptr = (void *)fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } } } }; @@ -218,6 +228,22 @@ static const auth_img_desc_t tb_fw_config = { } } }; + +static const auth_img_desc_t fw_config = { + .img_id = FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &fw_config_hash + } + } + } +}; + #endif /* IMAGE_BL1 */ #ifdef IMAGE_BL2 @@ -860,6 +886,7 @@ static const auth_img_desc_t * const cot_desc[] = { [BL2_IMAGE_ID] = &bl2_image, [HW_CONFIG_ID] = &hw_config, [TB_FW_CONFIG_ID] = &tb_fw_config, + [FW_CONFIG_ID] = &fw_config, [FWU_CERT_ID] = &fwu_cert, [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, [BL2U_IMAGE_ID] = &bl2u_image, diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c index f3bb37674..e4c92213a 100644 --- a/drivers/auth/tbbr/tbbr_cot_bl1.c +++ b/drivers/auth/tbbr/tbbr_cot_bl1.c @@ -150,6 +150,21 @@ static const auth_img_desc_t tb_fw_config = { } }; +static const auth_img_desc_t fw_config = { + .img_id = FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &fw_config_hash + } + } + } +}; + /* * TBBR Chain of trust definition */ @@ -158,6 +173,7 @@ static const auth_img_desc_t * const cot_desc[] = { [BL2_IMAGE_ID] = &bl2_image, [HW_CONFIG_ID] = &hw_config, [TB_FW_CONFIG_ID] = &tb_fw_config, + [FW_CONFIG_ID] = &fw_config, [FWU_CERT_ID] = &fwu_cert, [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, [BL2U_IMAGE_ID] = &bl2u_image, diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c index 0a4b75e00..ff3f22de1 100644 --- a/drivers/auth/tbbr/tbbr_cot_common.c +++ b/drivers/auth/tbbr/tbbr_cot_common.c @@ -23,9 +23,10 @@ * established, we can reuse some of the buffers on different stages */ +static unsigned char fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char hw_config_hash_buf[HASH_DER_LEN]; unsigned char tb_fw_hash_buf[HASH_DER_LEN]; -unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; -unsigned char hw_config_hash_buf[HASH_DER_LEN]; unsigned char scp_fw_hash_buf[HASH_DER_LEN]; unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; @@ -48,7 +49,9 @@ auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID); auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); -auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( +auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FW_CONFIG_HASH_OID); +static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); /* trusted_boot_fw_cert */ @@ -95,6 +98,13 @@ const auth_img_desc_t trusted_boot_fw_cert = { .ptr = (void *)hw_config_hash_buf, .len = (unsigned int)HASH_DER_LEN } + }, + [3] = { + .type_desc = &fw_config_hash, + .data = { + .ptr = (void *)fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } } } }; diff --git a/drivers/st/scmi-msg/base.c b/drivers/st/scmi-msg/base.c new file mode 100644 index 000000000..e44bc529d --- /dev/null +++ b/drivers/st/scmi-msg/base.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include <assert.h> +#include <string.h> + +#include <drivers/st/scmi-msg.h> +#include <drivers/st/scmi.h> +#include <lib/utils.h> +#include <lib/utils_def.h> + +#include "common.h" + +static bool message_id_is_supported(unsigned int message_id); + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_BASE, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + size_t protocol_count = plat_scmi_protocol_count(); + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* Null agent count since agent discovery is not supported */ + .attributes = SCMI_BASE_PROTOCOL_ATTRIBUTES(protocol_count, 0U), + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_vendor(struct scmi_msg *msg) +{ + const char *name = plat_scmi_vendor_name(); + struct scmi_base_discover_vendor_p2a return_values = { + .status = SCMI_SUCCESS, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + COPY_NAME_IDENTIFIER(return_values.vendor_identifier, name); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_sub_vendor(struct scmi_msg *msg) +{ + const char *name = plat_scmi_sub_vendor_name(); + struct scmi_base_discover_sub_vendor_p2a return_values = { + .status = SCMI_SUCCESS, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + COPY_NAME_IDENTIFIER(return_values.sub_vendor_identifier, name); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_implementation_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_IMPL_VERSION, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static unsigned int count_protocols_in_list(const uint8_t *protocol_list) +{ + unsigned int count = 0U; + + if (protocol_list != NULL) { + while (protocol_list[count] != 0U) { + count++; + } + } + + return count; +} + +#define MAX_PROTOCOL_IN_LIST 8U + +static void discover_list_protocols(struct scmi_msg *msg) +{ + const struct scmi_base_discover_list_protocols_a2p *a2p = NULL; + struct scmi_base_discover_list_protocols_p2a p2a = { + .status = SCMI_SUCCESS, + }; + uint8_t outargs[sizeof(p2a) + MAX_PROTOCOL_IN_LIST] = { 0U }; + const uint8_t *list = NULL; + unsigned int count = 0U; + + if (msg->in_size != sizeof(*a2p)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + assert(msg->out_size > sizeof(outargs)); + + a2p = (void *)msg->in; + + list = plat_scmi_protocol_list(msg->agent_id); + count = count_protocols_in_list(list); + if (count > a2p->skip) { + count = MIN(count - a2p->skip, MAX_PROTOCOL_IN_LIST); + } else { + count = 0U; + } + + p2a.num_protocols = count; + + memcpy(outargs, &p2a, sizeof(p2a)); + memcpy(outargs + sizeof(p2a), list + a2p->skip, count); + + scmi_write_response(msg, outargs, sizeof(outargs)); +} + +static const scmi_msg_handler_t scmi_base_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_BASE_DISCOVER_VENDOR] = discover_vendor, + [SCMI_BASE_DISCOVER_SUB_VENDOR] = discover_sub_vendor, + [SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION] = + discover_implementation_version, + [SCMI_BASE_DISCOVER_LIST_PROTOCOLS] = discover_list_protocols, +}; + +static bool message_id_is_supported(unsigned int message_id) +{ + return (message_id < ARRAY_SIZE(scmi_base_handler_table)) && + (scmi_base_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg) +{ + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= ARRAY_SIZE(scmi_base_handler_table)) { + VERBOSE("Base handle not found %u\n", msg->message_id); + return NULL; + } + + return scmi_base_handler_table[message_id]; +} diff --git a/drivers/st/scmi-msg/base.h b/drivers/st/scmi-msg/base.h new file mode 100644 index 000000000..c4a9c64a4 --- /dev/null +++ b/drivers/st/scmi-msg/base.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ + +#ifndef SCMI_MSG_BASE_H +#define SCMI_MSG_BASE_H + +#include <stdint.h> + +#define SCMI_PROTOCOL_VERSION_BASE 0x20000U + +#define SCMI_DEFAULT_STRING_LENGTH 16U + +enum scmi_base_message_id { + SCMI_BASE_DISCOVER_VENDOR = 0x003, + SCMI_BASE_DISCOVER_SUB_VENDOR = 0x004, + SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION = 0x005, + SCMI_BASE_DISCOVER_LIST_PROTOCOLS = 0x006, + SCMI_BASE_DISCOVER_AGENT = 0x007, + SCMI_BASE_NOTIFY_ERRORS = 0x008, +}; + +/* + * PROTOCOL_ATTRIBUTES + */ + +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS 0 +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS 8 + +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK 0xFFU +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK 0xFF00U + +#define SCMI_BASE_PROTOCOL_ATTRIBUTES(NUM_PROTOCOLS, NUM_AGENTS) \ + ((((NUM_PROTOCOLS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS) & \ + SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK) | \ + (((NUM_AGENTS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS) & \ + SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK)) + +/* + * BASE_DISCOVER_VENDOR + */ +struct scmi_base_discover_vendor_p2a { + int32_t status; + char vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; +}; + +/* + * BASE_DISCOVER_SUB_VENDOR + */ +struct scmi_base_discover_sub_vendor_p2a { + int32_t status; + char sub_vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; +}; + +/* + * BASE_DISCOVER_IMPLEMENTATION_VERSION + * No special structure right now, see protocol_version. + */ + +/* + * BASE_DISCOVER_LIST_PROTOCOLS + */ +struct scmi_base_discover_list_protocols_a2p { + uint32_t skip; +}; + +struct scmi_base_discover_list_protocols_p2a { + int32_t status; + uint32_t num_protocols; + uint32_t protocols[]; +}; + +#endif /* SCMI_MSG_BASE_H */ diff --git a/drivers/st/scmi-msg/clock.c b/drivers/st/scmi-msg/clock.c new file mode 100644 index 000000000..319557cd0 --- /dev/null +++ b/drivers/st/scmi-msg/clock.c @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include <cdefs.h> +#include <string.h> + +#include <drivers/st/scmi-msg.h> +#include <drivers/st/scmi.h> +#include <lib/utils_def.h> + +#include "common.h" + +#pragma weak plat_scmi_clock_count +#pragma weak plat_scmi_clock_get_name +#pragma weak plat_scmi_clock_rates_array +#pragma weak plat_scmi_clock_rates_by_step +#pragma weak plat_scmi_clock_get_rate +#pragma weak plat_scmi_clock_set_rate +#pragma weak plat_scmi_clock_get_state +#pragma weak plat_scmi_clock_set_state + +static bool message_id_is_supported(unsigned int message_id); + +size_t plat_scmi_clock_count(unsigned int agent_id __unused) +{ + return 0U; +} + +const char *plat_scmi_clock_get_name(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return NULL; +} + +int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long *rates __unused, + size_t *nb_elts __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long *steps __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +unsigned long plat_scmi_clock_get_rate(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return 0U; +} + +int32_t plat_scmi_clock_set_rate(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long rate __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_get_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_set_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + bool enable_not_disable __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_CLOCK, + }; + + if (msg->in_size != 0) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + size_t agent_count = plat_scmi_clock_count(msg->agent_id); + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = SCMI_CLOCK_PROTOCOL_ATTRIBUTES(1U, agent_count), + }; + + if (msg->in_size != 0) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_attributes(struct scmi_msg *msg) +{ + const struct scmi_clock_attributes_a2p *in_args = (void *)msg->in; + struct scmi_clock_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + }; + const char *name = NULL; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + + name = plat_scmi_clock_get_name(msg->agent_id, clock_id); + if (name == NULL) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + COPY_NAME_IDENTIFIER(return_values.clock_name, name); + + return_values.attributes = plat_scmi_clock_get_state(msg->agent_id, + clock_id); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_rate_get(struct scmi_msg *msg) +{ + const struct scmi_clock_rate_get_a2p *in_args = (void *)msg->in; + unsigned long rate = 0U; + struct scmi_clock_rate_get_p2a return_values = { + .status = SCMI_SUCCESS, + }; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + rate = plat_scmi_clock_get_rate(msg->agent_id, clock_id); + + return_values.rate[0] = (uint32_t)rate; + return_values.rate[1] = (uint32_t)((uint64_t)rate >> 32); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_rate_set(struct scmi_msg *msg) +{ + const struct scmi_clock_rate_set_a2p *in_args = (void *)msg->in; + unsigned long rate = 0U; + int32_t status = 0; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + rate = (unsigned long)(((uint64_t)in_args->rate[1] << 32) | + in_args->rate[0]); + + status = plat_scmi_clock_set_rate(msg->agent_id, clock_id, rate); + + scmi_status_response(msg, status); +} + +static void scmi_clock_config_set(struct scmi_msg *msg) +{ + const struct scmi_clock_config_set_a2p *in_args = (void *)msg->in; + int32_t status = SCMI_GENERIC_ERROR; + bool enable = false; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + enable = in_args->attributes & SCMI_CLOCK_CONFIG_SET_ENABLE_MASK; + + status = plat_scmi_clock_set_state(msg->agent_id, clock_id, enable); + + scmi_status_response(msg, status); +} + +#define RATES_ARRAY_SIZE_MAX (SCMI_PLAYLOAD_MAX - \ + sizeof(struct scmi_clock_describe_rates_p2a)) + +#define SCMI_RATES_BY_ARRAY(_nb_rates, _rem_rates) \ + SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS((_nb_rates), \ + SCMI_CLOCK_RATE_FORMAT_LIST, \ + (_rem_rates)) +#define SCMI_RATES_BY_STEP \ + SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(3U, \ + SCMI_CLOCK_RATE_FORMAT_RANGE, \ + 0U) + +#define RATE_DESC_SIZE sizeof(struct scmi_clock_rate) + +static void write_rate_desc_array_in_buffer(char *dest, unsigned long *rates, + size_t nb_elt) +{ + uint32_t *out = (uint32_t *)(uintptr_t)dest; + size_t n; + + ASSERT_SYM_PTR_ALIGN(out); + + for (n = 0U; n < nb_elt; n++) { + out[2 * n] = (uint32_t)rates[n]; + out[2 * n + 1] = (uint32_t)((uint64_t)rates[n] >> 32); + } +} + +static void scmi_clock_describe_rates(struct scmi_msg *msg) +{ + const struct scmi_clock_describe_rates_a2p *in_args = (void *)msg->in; + struct scmi_clock_describe_rates_p2a p2a = { + .status = SCMI_SUCCESS, + }; + size_t nb_rates; + int32_t status; + unsigned int clock_id; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + /* Platform may support array rate description */ + status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, NULL, + &nb_rates); + if (status == SCMI_SUCCESS) { + /* Currently 12 cells mex, so it's affordable for the stack */ + unsigned long plat_rates[RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE]; + size_t max_nb = RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE; + size_t ret_nb = MIN(nb_rates - in_args->rate_index, max_nb); + size_t rem_nb = nb_rates - in_args->rate_index - ret_nb; + + status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, + plat_rates, &ret_nb); + if (status == SCMI_SUCCESS) { + write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), + plat_rates, ret_nb); + + p2a.num_rates_flags = SCMI_RATES_BY_ARRAY(ret_nb, + rem_nb); + p2a.status = SCMI_SUCCESS; + + memcpy(msg->out, &p2a, sizeof(p2a)); + msg->out_size_out = sizeof(p2a) + + ret_nb * RATE_DESC_SIZE; + } + } else if (status == SCMI_NOT_SUPPORTED) { + unsigned long triplet[3] = { 0U, 0U, 0U }; + + /* Platform may support min§max/step triplet description */ + status = plat_scmi_clock_rates_by_step(msg->agent_id, clock_id, + triplet); + if (status == SCMI_SUCCESS) { + write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), + triplet, 3U); + + p2a.num_rates_flags = SCMI_RATES_BY_STEP; + p2a.status = SCMI_SUCCESS; + + memcpy(msg->out, &p2a, sizeof(p2a)); + msg->out_size_out = sizeof(p2a) + (3U * RATE_DESC_SIZE); + } + } else { + /* Fallthrough generic exit sequence below with error status */ + } + + if (status != SCMI_SUCCESS) { + scmi_status_response(msg, status); + } else { + /* + * Message payload is already writen to msg->out, and + * msg->out_size_out updated. + */ + } +} + +static const scmi_msg_handler_t scmi_clock_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_CLOCK_ATTRIBUTES] = scmi_clock_attributes, + [SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates, + [SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set, + [SCMI_CLOCK_RATE_GET] = scmi_clock_rate_get, + [SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set, +}; + +static bool message_id_is_supported(size_t message_id) +{ + return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) && + (scmi_clock_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg) +{ + const size_t array_size = ARRAY_SIZE(scmi_clock_handler_table); + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= array_size) { + VERBOSE("Clock handle not found %u", msg->message_id); + return NULL; + } + + return scmi_clock_handler_table[message_id]; +} diff --git a/drivers/st/scmi-msg/clock.h b/drivers/st/scmi-msg/clock.h new file mode 100644 index 000000000..a637934ee --- /dev/null +++ b/drivers/st/scmi-msg/clock.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ + +#ifndef SCMI_MSG_CLOCK_H +#define SCMI_MSG_CLOCK_H + +#include <stdint.h> + +#include <lib/utils_def.h> + +#define SCMI_PROTOCOL_VERSION_CLOCK 0x20000U + +/* + * Identifiers of the SCMI Clock Management Protocol commands + */ +enum scmi_clock_command_id { + SCMI_CLOCK_ATTRIBUTES = 0x003, + SCMI_CLOCK_DESCRIBE_RATES = 0x004, + SCMI_CLOCK_RATE_SET = 0x005, + SCMI_CLOCK_RATE_GET = 0x006, + SCMI_CLOCK_CONFIG_SET = 0x007, +}; + +/* Protocol attributes */ +#define SCMI_CLOCK_CLOCK_COUNT_MASK GENMASK(15, 0) +#define SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK GENMASK(23, 16) + +#define SCMI_CLOCK_PROTOCOL_ATTRIBUTES(_max_pending, _clk_count) \ + ((((_max_pending) << 16) & SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK) | \ + (((_clk_count) & SCMI_CLOCK_CLOCK_COUNT_MASK))) + +struct scmi_clock_attributes_a2p { + uint32_t clock_id; +}; + +#define SCMI_CLOCK_NAME_LENGTH_MAX 16U + +struct scmi_clock_attributes_p2a { + int32_t status; + uint32_t attributes; + char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX]; +}; + +/* + * Clock Rate Get + */ + +struct scmi_clock_rate_get_a2p { + uint32_t clock_id; +}; + +struct scmi_clock_rate_get_p2a { + int32_t status; + uint32_t rate[2]; +}; + +/* + * Clock Rate Set + */ + +/* If set, set the new clock rate asynchronously */ +#define SCMI_CLOCK_RATE_SET_ASYNC_POS 0 +/* If set, do not send a delayed asynchronous response */ +#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS 1 +/* Round up, if set, otherwise round down */ +#define SCMI_CLOCK_RATE_SET_ROUND_UP_POS 2 +/* If set, the platform chooses the appropriate rounding mode */ +#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS 3 + +#define SCMI_CLOCK_RATE_SET_ASYNC_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ASYNC_POS) +#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_MASK \ + BIT(SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS) +#define SCMI_CLOCK_RATE_SET_ROUND_UP_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ROUND_UP_POS) +#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS) + +struct scmi_clock_rate_set_a2p { + uint32_t flags; + uint32_t clock_id; + uint32_t rate[2]; +}; + +struct scmi_clock_rate_set_p2a { + int32_t status; +}; + +/* + * Clock Config Set + */ + +#define SCMI_CLOCK_CONFIG_SET_ENABLE_POS 0 + +#define SCMI_CLOCK_CONFIG_SET_ENABLE_MASK \ + BIT(SCMI_CLOCK_CONFIG_SET_ENABLE_POS) + +struct scmi_clock_config_set_a2p { + uint32_t clock_id; + uint32_t attributes; +}; + +struct scmi_clock_config_set_p2a { + int32_t status; +}; + +/* + * Clock Describe Rates + */ + +#define SCMI_CLOCK_RATE_FORMAT_RANGE 1U +#define SCMI_CLOCK_RATE_FORMAT_LIST 0U + +#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK GENMASK_32(31, 16) +#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS 16 + +#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK BIT(12) +#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS 12 + +#define SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK GENMASK_32(11, 0) + +#define SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(_count, _fmt, _rem_rates) \ + ( \ + ((_count) & SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK) | \ + (((_rem_rates) << SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS) & \ + SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK) | \ + (((_fmt) << SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS) & \ + SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK) \ + ) + +struct scmi_clock_rate { + uint32_t low; + uint32_t high; +}; + +struct scmi_clock_describe_rates_a2p { + uint32_t clock_id; + uint32_t rate_index; +}; + +struct scmi_clock_describe_rates_p2a { + int32_t status; + uint32_t num_rates_flags; + struct scmi_clock_rate rates[]; +}; + +#endif /* SCMI_MSG_CLOCK_H */ diff --git a/drivers/st/scmi-msg/common.h b/drivers/st/scmi-msg/common.h new file mode 100644 index 000000000..ef5953b3d --- /dev/null +++ b/drivers/st/scmi-msg/common.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#ifndef SCMI_MSG_COMMON_H +#define SCMI_MSG_COMMON_H + +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#include "base.h" +#include "clock.h" +#include "reset_domain.h" + +#define SCMI_VERSION 0x20000U +#define SCMI_IMPL_VERSION 0U + +#define SCMI_PLAYLOAD_MAX 92U + +/* + * Copy name identifier in target buffer following the SCMI specification + * that state name identifier shall be a null terminated string. + */ +#define COPY_NAME_IDENTIFIER(_dst_array, _name) \ + do { \ + assert(strlen(_name) < sizeof(_dst_array)); \ + strlcpy((_dst_array), (_name), sizeof(_dst_array)); \ + } while (0) + +/* Common command identifiers shared by all procotols */ +enum scmi_common_message_id { + SCMI_PROTOCOL_VERSION = 0x000, + SCMI_PROTOCOL_ATTRIBUTES = 0x001, + SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x002 +}; + +/* Common platform-to-agent (p2a) PROTOCOL_VERSION structure */ +struct scmi_protocol_version_p2a { + int32_t status; + uint32_t version; +}; + +/* Generic platform-to-agent (p2a) PROTOCOL_ATTRIBUTES structure */ +struct scmi_protocol_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* Generic agent-to-platform (a2p) PROTOCOL_MESSAGE_ATTRIBUTES structure */ +struct scmi_protocol_message_attributes_a2p { + uint32_t message_id; +}; + +/* Generic platform-to-agent (p2a) PROTOCOL_MESSAGE_ATTRIBUTES structure */ +struct scmi_protocol_message_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* + * struct scmi_msg - SCMI message context + * + * @agent_id: SCMI agent ID, safely set from secure world + * @protocol_id: SCMI protocol ID for the related message, set by caller agent + * @message_id: SCMI message ID for the related message, set by caller agent + * @in: Address of the incoming message payload copied in secure memory + * @in_size: Byte length of the incoming message payload, set by caller agent + * @out: Address of of the output message payload message in non-secure memory + * @out_size: Byte length of the provisionned output buffer + * @out_size_out: Byte length of the output message payload + */ +struct scmi_msg { + unsigned int agent_id; + unsigned int protocol_id; + unsigned int message_id; + char *in; + size_t in_size; + char *out; + size_t out_size; + size_t out_size_out; +}; + +/* + * Type scmi_msg_handler_t is used by procotol drivers to safely find + * the handler function for the incoming message ID. + */ +typedef void (*scmi_msg_handler_t)(struct scmi_msg *msg); + +/* + * scmi_msg_get_base_handler - Return a handler for a base message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg); + +/* + * scmi_msg_get_clock_handler - Return a handler for a clock message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg); + +/* + * scmi_msg_get_rstd_handler - Return a handler for a reset domain message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg); + +/* + * Process Read, process and write response for input SCMI message + * + * @msg: SCMI message context + */ +void scmi_process_message(struct scmi_msg *msg); + +/* + * Write SCMI response payload to output message shared memory + * + * @msg: SCMI message context + * @payload: Output message payload + * @size: Byte size of output message payload + */ +void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size); + +/* + * Write status only SCMI response payload to output message shared memory + * + * @msg: SCMI message context + * @status: SCMI status value returned to caller + */ +void scmi_status_response(struct scmi_msg *msg, int32_t status); +#endif /* SCMI_MSG_COMMON_H */ diff --git a/drivers/st/scmi-msg/entry.c b/drivers/st/scmi-msg/entry.c new file mode 100644 index 000000000..eefcb3100 --- /dev/null +++ b/drivers/st/scmi-msg/entry.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ + +#include <assert.h> + +#include <drivers/st/scmi-msg.h> +#include <drivers/st/scmi.h> + +#include "common.h" + +void scmi_status_response(struct scmi_msg *msg, int32_t status) +{ + assert(msg->out && msg->out_size >= sizeof(int32_t)); + + memcpy(msg->out, &status, sizeof(int32_t)); + msg->out_size_out = sizeof(int32_t); +} + +void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size) +{ + /* + * Output payload shall be at least the size of the status + * Output buffer shall be at least be the size of the status + * Output paylaod shall fit in output buffer + */ + assert(payload && size >= sizeof(int32_t) && size <= msg->out_size && + msg->out && msg->out_size >= sizeof(int32_t)); + + memcpy(msg->out, payload, size); + msg->out_size_out = size; +} + +void scmi_process_message(struct scmi_msg *msg) +{ + scmi_msg_handler_t handler = NULL; + + switch (msg->protocol_id) { + case SCMI_PROTOCOL_ID_BASE: + handler = scmi_msg_get_base_handler(msg); + break; + case SCMI_PROTOCOL_ID_CLOCK: + handler = scmi_msg_get_clock_handler(msg); + break; + case SCMI_PROTOCOL_ID_RESET_DOMAIN: + handler = scmi_msg_get_rstd_handler(msg); + break; + default: + break; + } + + if (handler) { + handler(msg); + return; + } + + ERROR("Agent %u Protocol 0x%x Message 0x%x: not supported", + msg->agent_id, msg->protocol_id, msg->message_id); + + scmi_status_response(msg, SCMI_NOT_SUPPORTED); +} diff --git a/drivers/st/scmi-msg/reset_domain.c b/drivers/st/scmi-msg/reset_domain.c new file mode 100644 index 000000000..b4773029b --- /dev/null +++ b/drivers/st/scmi-msg/reset_domain.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include <cdefs.h> +#include <string.h> + +#include <drivers/st/scmi-msg.h> +#include <drivers/st/scmi.h> +#include <lib/utils.h> +#include <lib/utils_def.h> + +#include "common.h" + +static bool message_id_is_supported(unsigned int message_id); + +#pragma weak plat_scmi_rstd_count +#pragma weak plat_scmi_rstd_get_name +#pragma weak plat_scmi_rstd_autonomous +#pragma weak plat_scmi_rstd_set_state + +size_t plat_scmi_rstd_count(unsigned int agent_id __unused) +{ + return 0U; +} + +const char *plat_scmi_rstd_get_name(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return NULL; +} + +int32_t plat_scmi_rstd_autonomous(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned int state __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_rstd_set_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + bool assert_not_deassert __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_RESET_DOMAIN, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = plat_scmi_rstd_count(msg->agent_id), + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void reset_domain_attributes(struct scmi_msg *msg) +{ + struct scmi_reset_domain_attributes_a2p *in_args = (void *)msg->in; + struct scmi_reset_domain_attributes_p2a return_values; + const char *name = NULL; + unsigned int domain_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); + + if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + name = plat_scmi_rstd_get_name(msg->agent_id, domain_id); + if (name == NULL) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + zeromem(&return_values, sizeof(return_values)); + COPY_NAME_IDENTIFIER(return_values.name, name); + return_values.status = SCMI_SUCCESS; + return_values.flags = 0U; /* Async and Notif are not supported */ + return_values.latency = SCMI_RESET_DOMAIN_ATTR_UNK_LAT; + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void reset_request(struct scmi_msg *msg) +{ + struct scmi_reset_domain_request_a2p *in_args = (void *)msg->in; + struct scmi_reset_domain_request_p2a out_args = { + .status = SCMI_SUCCESS, + }; + unsigned int domain_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); + + if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + if ((in_args->flags & SCMI_RESET_DOMAIN_AUTO) != 0U) { + out_args.status = plat_scmi_rstd_autonomous(msg->agent_id, + domain_id, + in_args->reset_state); + } else if ((in_args->flags & SCMI_RESET_DOMAIN_EXPLICIT) != 0U) { + out_args.status = plat_scmi_rstd_set_state(msg->agent_id, + domain_id, true); + } else { + out_args.status = plat_scmi_rstd_set_state(msg->agent_id, + domain_id, false); + } + + if (out_args.status != SCMI_SUCCESS) { + scmi_status_response(msg, out_args.status); + } else { + scmi_write_response(msg, &out_args, sizeof(out_args)); + } +} + +static const scmi_msg_handler_t scmi_rstd_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_RESET_DOMAIN_ATTRIBUTES] = reset_domain_attributes, + [SCMI_RESET_DOMAIN_REQUEST] = reset_request, +}; + +static bool message_id_is_supported(unsigned int message_id) +{ + return (message_id < ARRAY_SIZE(scmi_rstd_handler_table)) && + (scmi_rstd_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg) +{ + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= ARRAY_SIZE(scmi_rstd_handler_table)) { + VERBOSE("Reset domain handle not found %u\n", msg->message_id); + return NULL; + } + + return scmi_rstd_handler_table[message_id]; +} diff --git a/drivers/st/scmi-msg/reset_domain.h b/drivers/st/scmi-msg/reset_domain.h new file mode 100644 index 000000000..47bee5e39 --- /dev/null +++ b/drivers/st/scmi-msg/reset_domain.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ +#ifndef SCMI_MSG_RESET_DOMAIN_H +#define SCMI_MSG_RESET_DOMAIN_H + +#include <stdbool.h> +#include <stdint.h> + +#include <lib/utils_def.h> + +#define SCMI_PROTOCOL_VERSION_RESET_DOMAIN 0x10000U + +#define SCMI_RESET_STATE_ARCH BIT(31) +#define SCMI_RESET_STATE_IMPL 0U + +/* + * Identifiers of the SCMI Reset Domain Management Protocol commands + */ +enum scmi_reset_domain_command_id { + SCMI_RESET_DOMAIN_ATTRIBUTES = 0x03, + SCMI_RESET_DOMAIN_REQUEST = 0x04, + SCMI_RESET_DOMAIN_NOTIFY = 0x05, +}; + +/* + * Identifiers of the SCMI Reset Domain Management Protocol responses + */ +enum scmi_reset_domain_response_id { + SCMI_RESET_ISSUED = 0x00, + SCMI_RESET_COMPLETE = 0x04, +}; + +/* + * PROTOCOL_ATTRIBUTES + */ + +#define SCMI_RESET_DOMAIN_COUNT_MASK GENMASK_32(15, 0) + +struct scmi_reset_domain_protocol_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* Value for scmi_reset_domain_attributes_p2a:flags */ +#define SCMI_RESET_DOMAIN_ATTR_ASYNC BIT(31) +#define SCMI_RESET_DOMAIN_ATTR_NOTIF BIT(30) + +/* Value for scmi_reset_domain_attributes_p2a:latency */ +#define SCMI_RESET_DOMAIN_ATTR_UNK_LAT 0x7fffffffU +#define SCMI_RESET_DOMAIN_ATTR_MAX_LAT 0x7ffffffeU + +/* Macro for scmi_reset_domain_attributes_p2a:name */ +#define SCMI_RESET_DOMAIN_ATTR_NAME_SZ 16U + +struct scmi_reset_domain_attributes_a2p { + uint32_t domain_id; +}; + +struct scmi_reset_domain_attributes_p2a { + int32_t status; + uint32_t flags; + uint32_t latency; + char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ]; +}; + +/* + * RESET + */ + +/* Values for scmi_reset_domain_request_a2p:flags */ +#define SCMI_RESET_DOMAIN_ASYNC BIT(2) +#define SCMI_RESET_DOMAIN_EXPLICIT BIT(1) +#define SCMI_RESET_DOMAIN_AUTO BIT(0) + +struct scmi_reset_domain_request_a2p { + uint32_t domain_id; + uint32_t flags; + uint32_t reset_state; +}; + +struct scmi_reset_domain_request_p2a { + int32_t status; +}; + +/* + * RESET_NOTIFY + */ + +/* Values for scmi_reset_notify_p2a:flags */ +#define SCMI_RESET_DOMAIN_DO_NOTIFY BIT(0) + +struct scmi_reset_domain_notify_a2p { + uint32_t domain_id; + uint32_t notify_enable; +}; + +struct scmi_reset_domain_notify_p2a { + int32_t status; +}; + +/* + * RESET_COMPLETE + */ + +struct scmi_reset_domain_complete_p2a { + int32_t status; + uint32_t domain_id; +}; + +/* + * RESET_ISSUED + */ + +struct scmi_reset_domain_issued_p2a { + uint32_t domain_id; + uint32_t reset_state; +}; + +#endif /* SCMI_MSG_RESET_DOMAIN_H */ diff --git a/drivers/st/scmi-msg/smt.c b/drivers/st/scmi-msg/smt.c new file mode 100644 index 000000000..2d5cd734f --- /dev/null +++ b/drivers/st/scmi-msg/smt.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#include <drivers/st/scmi-msg.h> +#include <drivers/st/scmi.h> +#include <lib/cassert.h> +#include <lib/mmio.h> +#include <lib/spinlock.h> +#include <lib/utils.h> +#include <plat/common/platform.h> + +#include "common.h" + +/* Legacy SMT/SCMI messages are 128 bytes at most including SMT header */ +#define SCMI_PLAYLOAD_MAX 92U +#define SCMI_PLAYLOAD_U32_MAX (SCMI_PLAYLOAD_MAX / sizeof(uint32_t)) + +/** + * struct smt_header - SMT formatted header for SMT base shared memory transfer + * + * @status: Bit flags, see SMT_STATUS_* + * @flags: Bit flags, see SMT_FLAG_* + * @length: Byte size of message payload (variable) + ::message_header (32bit) + * payload: SCMI message payload data + */ +struct smt_header { + uint32_t reserved0; + uint32_t status; + uint64_t reserved1; + uint32_t flags; + uint32_t length; /* message_header + payload */ + uint32_t message_header; + uint32_t payload[]; +}; + +CASSERT(SCMI_PLAYLOAD_MAX + sizeof(struct smt_header) <= SMT_BUF_SLOT_SIZE, + assert_scmi_message_max_length_fits_in_smt_buffer_slot); + +/* Flag set in smt_header::status when SMT does not contain pending message */ +#define SMT_STATUS_FREE BIT(0) +/* Flag set in smt_header::status when SMT reports an error */ +#define SMT_STATUS_ERROR BIT(1) + +/* Flag set in smt_header::flags when SMT uses interrupts */ +#define SMT_FLAG_INTR_ENABLED BIT(1) + +/* Bit fields packed in smt_header::message_header */ +#define SMT_MSG_ID_MASK GENMASK_32(7, 0) +#define SMT_HDR_MSG_ID(_hdr) ((_hdr) & SMT_MSG_ID_MASK) + +#define SMT_MSG_TYPE_MASK GENMASK_32(9, 8) +#define SMT_HDR_TYPE_ID(_hdr) (((_hdr) & SMT_MSG_TYPE_MASK) >> 8) + +#define SMT_MSG_PROT_ID_MASK GENMASK_32(17, 10) +#define SMT_HDR_PROT_ID(_hdr) (((_hdr) & SMT_MSG_PROT_ID_MASK) >> 10) + +/* + * Provision input message payload buffers for fastcall SMC context entries + * and for interrupt context execution entries. + */ +static uint32_t fast_smc_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; +static uint32_t interrupt_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; + +/* SMP protection on channel access */ +static struct spinlock smt_channels_lock; + +/* If channel is not busy, set busy and return true, otherwise return false */ +static bool channel_set_busy(struct scmi_msg_channel *chan) +{ + bool channel_is_busy; + + spin_lock(&smt_channels_lock); + + channel_is_busy = chan->busy; + + if (!channel_is_busy) { + chan->busy = true; + } + + spin_unlock(&smt_channels_lock); + + return !channel_is_busy; +} + +static void channel_release_busy(struct scmi_msg_channel *chan) +{ + chan->busy = false; +} + +static struct smt_header *channel_to_smt_hdr(struct scmi_msg_channel *chan) +{ + return (struct smt_header *)chan->shm_addr; +} + +/* + * Creates a SCMI message instance in secure memory and pushes it in the SCMI + * message drivers. Message structure contains SCMI protocol meta-data and + * references to input payload in secure memory and output message buffer + * in shared memory. + */ +static void scmi_proccess_smt(unsigned int agent_id, uint32_t *payload_buf) +{ + struct scmi_msg_channel *chan; + struct smt_header *smt_hdr; + size_t in_payload_size; + uint32_t smt_status; + struct scmi_msg msg; + bool error = true; + + chan = plat_scmi_get_channel(agent_id); + if (chan == NULL) { + return; + } + + smt_hdr = channel_to_smt_hdr(chan); + assert(smt_hdr); + + smt_status = __atomic_load_n(&smt_hdr->status, __ATOMIC_RELAXED); + + if (!channel_set_busy(chan)) { + VERBOSE("SCMI channel %u busy", agent_id); + goto out; + } + + in_payload_size = __atomic_load_n(&smt_hdr->length, __ATOMIC_RELAXED) - + sizeof(smt_hdr->message_header); + + if (in_payload_size > SCMI_PLAYLOAD_MAX) { + VERBOSE("SCMI payload too big %u", in_payload_size); + goto out; + } + + if ((smt_status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)) != 0U) { + VERBOSE("SCMI channel bad status 0x%x", + smt_hdr->status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)); + goto out; + } + + /* Fill message */ + zeromem(&msg, sizeof(msg)); + msg.in = (char *)payload_buf; + msg.in_size = in_payload_size; + msg.out = (char *)smt_hdr->payload; + msg.out_size = chan->shm_size - sizeof(*smt_hdr); + + assert((msg.out != NULL) && (msg.out_size >= sizeof(int32_t))); + + /* Here the payload is copied in secure memory */ + memcpy(msg.in, smt_hdr->payload, in_payload_size); + + msg.protocol_id = SMT_HDR_PROT_ID(smt_hdr->message_header); + msg.message_id = SMT_HDR_MSG_ID(smt_hdr->message_header); + msg.agent_id = agent_id; + + scmi_process_message(&msg); + + /* Update message length with the length of the response message */ + smt_hdr->length = msg.out_size_out + sizeof(smt_hdr->message_header); + + channel_release_busy(chan); + error = false; + +out: + if (error) { + VERBOSE("SCMI error"); + smt_hdr->status |= SMT_STATUS_ERROR | SMT_STATUS_FREE; + } else { + smt_hdr->status |= SMT_STATUS_FREE; + } +} + +void scmi_smt_fastcall_smc_entry(unsigned int agent_id) +{ + scmi_proccess_smt(agent_id, + fast_smc_payload[plat_my_core_pos()]); +} + +void scmi_smt_interrupt_entry(unsigned int agent_id) +{ + scmi_proccess_smt(agent_id, + interrupt_payload[plat_my_core_pos()]); +} + +/* Init a SMT header for a shared memory buffer: state it a free/no-error */ +void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan) +{ + if (chan != NULL) { + struct smt_header *smt_header = channel_to_smt_hdr(chan); + + if (smt_header != NULL) { + memset(smt_header, 0, sizeof(*smt_header)); + smt_header->status = SMT_STATUS_FREE; + + return; + } + } + + panic(); +} diff --git a/include/drivers/arm/css/css_scp.h b/include/drivers/arm/css/css_scp.h index f3c08c52f..2b506eaaf 100644 --- a/include/drivers/arm/css/css_scp.h +++ b/include/drivers/arm/css/css_scp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -40,13 +40,13 @@ int css_scp_boot_ready(void); /* * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 * usually resides except when ARM_BL31_IN_DRAM is - * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into tb_fw_config. + * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into fw_config. */ CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); -CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); -CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); +CASSERT(SCP_BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); +CASSERT(SCP_BL2U_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); #endif #endif /* CSS_SCP_H */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index 77dc350dd..97b75b0da 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -332,6 +332,18 @@ static inline uint32_t gicv3_get_pending_interrupt_id_sel1(void) static inline void gicv3_end_of_interrupt_sel1(unsigned int id) { + /* + * Interrupt request deassertion from peripheral to GIC happens + * by clearing interrupt condition by a write to the peripheral + * register. It is desired that the write transfer is complete + * before the core tries to change GIC state from 'AP/Active' to + * a new state on seeing 'EOI write'. + * Since ICC interface writes are not ordered against Device + * memory writes, a barrier is required to ensure the ordering. + * The dsb will also ensure *completion* of previous writes with + * DEVICE nGnRnE attribute. + */ + dsbishst(); write_icc_eoir1_el1(id); } @@ -345,6 +357,18 @@ static inline uint32_t gicv3_acknowledge_interrupt(void) static inline void gicv3_end_of_interrupt(unsigned int id) { + /* + * Interrupt request deassertion from peripheral to GIC happens + * by clearing interrupt condition by a write to the peripheral + * register. It is desired that the write transfer is complete + * before the core tries to change GIC state from 'AP/Active' to + * a new state on seeing 'EOI write'. + * Since ICC interface writes are not ordered against Device + * memory writes, a barrier is required to ensure the ordering. + * The dsb will also ensure *completion* of previous writes with + * DEVICE nGnRnE attribute. + */ + dsbishst(); return write_icc_eoir0_el1(id); } diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h index 0ea5f6575..a51faee1a 100644 --- a/include/drivers/auth/tbbr_cot_common.h +++ b/include/drivers/auth/tbbr_cot_common.h @@ -10,8 +10,6 @@ #include <drivers/auth/auth_mod.h> extern unsigned char tb_fw_hash_buf[HASH_DER_LEN]; -extern unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; -extern unsigned char hw_config_hash_buf[HASH_DER_LEN]; extern unsigned char scp_fw_hash_buf[HASH_DER_LEN]; extern unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; @@ -23,7 +21,7 @@ extern auth_param_type_desc_t raw_data; extern auth_param_type_desc_t tb_fw_hash; extern auth_param_type_desc_t tb_fw_config_hash; -extern auth_param_type_desc_t hw_config_hash; +extern auth_param_type_desc_t fw_config_hash; extern const auth_img_desc_t trusted_boot_fw_cert; extern const auth_img_desc_t hw_config; diff --git a/include/drivers/brcm/scp.h b/include/drivers/brcm/scp.h index b7b5bad74..7806314fa 100644 --- a/include/drivers/brcm/scp.h +++ b/include/drivers/brcm/scp.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef SCP_H_ +#ifndef SCP_H #define SCP_H #include <stdint.h> diff --git a/include/drivers/st/scmi-msg.h b/include/drivers/st/scmi-msg.h new file mode 100644 index 000000000..a9a99cf52 --- /dev/null +++ b/include/drivers/st/scmi-msg.h @@ -0,0 +1,207 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ + +#ifndef SCMI_MSG_H +#define SCMI_MSG_H + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +/* Minimum size expected for SMT based shared memory message buffers */ +#define SMT_BUF_SLOT_SIZE 128U + +/* A channel abstract a communication path between agent and server */ +struct scmi_msg_channel; + +/* + * struct scmi_msg_channel - Shared memory buffer for a agent-to-server channel + * + * @shm_addr: Address of the shared memory for the SCMI channel + * @shm_size: Byte size of the shared memory for the SCMI channel + * @busy: True when channel is busy, flase when channel is free + * @agent_name: Agent name, SCMI protocol exposes 16 bytes max, or NULL + */ +struct scmi_msg_channel { + uintptr_t shm_addr; + size_t shm_size; + bool busy; + const char *agent_name; +}; + +/* + * Initialize SMT memory buffer, called by platform at init for each + * agent channel using the SMT header format. + * + * @chan: Pointer to the channel shared memory to be initialized + */ +void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan); + +/* + * Process SMT formatted message in a fastcall SMC execution context. + * Called by platform on SMC entry. When returning, output message is + * available in shared memory for agent to read the response. + * + * @agent_id: SCMI agent ID the SMT belongs to + */ +void scmi_smt_fastcall_smc_entry(unsigned int agent_id); + +/* + * Process SMT formatted message in a secure interrupt execution context. + * Called by platform interrupt handler. When returning, output message is + * available in shared memory for agent to read the response. + * + * @agent_id: SCMI agent ID the SMT belongs to + */ +void scmi_smt_interrupt_entry(unsigned int agent_id); + +/* Platform callback functions */ + +/* + * Return the SCMI channel related to an agent + * @agent_id: SCMI agent ID + * Return a pointer to channel on success, NULL otherwise + */ +struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id); + +/* + * Return how many SCMI protocols supported by the platform + * According to the SCMI specification, this function does not target + * a specific agent ID and shall return all platform known capabilities. + */ +size_t plat_scmi_protocol_count(void); + +/* + * Get the count and list of SCMI protocols (but base) supported for an agent + * + * @agent_id: SCMI agent ID + * Return a pointer to a null terminated array supported protocol IDs. + */ +const uint8_t *plat_scmi_protocol_list(unsigned int agent_id); + +/* Get the name of the SCMI vendor for the platform */ +const char *plat_scmi_vendor_name(void); + +/* Get the name of the SCMI sub-vendor for the platform */ +const char *plat_scmi_sub_vendor_name(void); + +/* Handlers for SCMI Clock protocol services */ + +/* + * Return number of clock controllers for an agent + * @agent_id: SCMI agent ID + * Return number of clock controllers + */ +size_t plat_scmi_clock_count(unsigned int agent_id); + +/* + * Get clock controller string ID (aka name) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return pointer to name or NULL + */ +const char *plat_scmi_clock_get_name(unsigned int agent_id, + unsigned int scmi_id); + +/* + * Get clock possible rate as an array of frequencies in Hertz. + * + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @rates: If NULL, function returns, else output rates array + * @nb_elts: Array size of @rates. + * Return an SCMI compliant error code + */ +int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, + unsigned long *rates, size_t *nb_elts); + +/* + * Get clock possible rate as range with regular steps in Hertz + * + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @min_max_step: 3 cell array for min, max and step rate data + * Return an SCMI compliant error code + */ +int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id, + unsigned int scmi_id, + unsigned long *min_max_step); + +/* + * Get clock rate in Hertz + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return clock rate or 0 if not supported + */ +unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, + unsigned int scmi_id); + +/* + * Set clock rate in Hertz + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @rate: Target clock frequency in Hertz + * Return a compliant SCMI error code + */ +int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id, + unsigned long rate); + +/* + * Get clock state (enabled or disabled) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code + */ +int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id); + +/* + * Get clock state (enabled or disabled) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @enable_not_disable: Enable clock if true, disable clock otherwise + * Return a compliant SCMI error code + */ +int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, + bool enable_not_disable); + +/* Handlers for SCMI Reset Domain protocol services */ + +/* + * Return number of reset domains for the agent + * @agent_id: SCMI agent ID + * Return number of reset domains + */ +size_t plat_scmi_rstd_count(unsigned int agent_id); + +/* + * Get reset domain string ID (aka name) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * Return pointer to name or NULL + */ +const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id); + +/* + * Perform a reset cycle on a target reset domain + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * @state: Target reset state (see SCMI specification, 0 means context loss) + * Return a compliant SCMI error code + */ +int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id, + unsigned int state); + +/* + * Assert or deassert target reset domain + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * @assert_not_deassert: Assert domain if true, otherwise deassert domain + * Return a compliant SCMI error code + */ +int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, + bool assert_not_deassert); + +#endif /* SCMI_MSG_H */ diff --git a/include/drivers/st/scmi.h b/include/drivers/st/scmi.h new file mode 100644 index 000000000..ac5dc3871 --- /dev/null +++ b/include/drivers/st/scmi.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + */ +#ifndef SCMI_MSG_SCMI_H +#define SCMI_MSG_SCMI_H + +#define SCMI_PROTOCOL_ID_BASE 0x10U +#define SCMI_PROTOCOL_ID_POWER_DOMAIN 0x11U +#define SCMI_PROTOCOL_ID_SYS_POWER 0x12U +#define SCMI_PROTOCOL_ID_PERF 0x13U +#define SCMI_PROTOCOL_ID_CLOCK 0x14U +#define SCMI_PROTOCOL_ID_SENSOR 0x15U +#define SCMI_PROTOCOL_ID_RESET_DOMAIN 0x16U + +/* SCMI error codes reported to agent through server-to-agent messages */ +#define SCMI_SUCCESS 0 +#define SCMI_NOT_SUPPORTED (-1) +#define SCMI_INVALID_PARAMETERS (-2) +#define SCMI_DENIED (-3) +#define SCMI_NOT_FOUND (-4) +#define SCMI_OUT_OF_RANGE (-5) +#define SCMI_BUSY (-6) +#define SCMI_COMMS_ERROR (-7) +#define SCMI_GENERIC_ERROR (-8) +#define SCMI_HARDWARE_ERROR (-9) +#define SCMI_PROTOCOL_ERROR (-10) + +#endif /* SCMI_MSG_SCMI_H */ diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h index a98c1b4f6..18f012513 100644 --- a/include/export/common/tbbr/tbbr_img_def_exp.h +++ b/include/export/common/tbbr/tbbr_img_def_exp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -88,7 +88,10 @@ /* Encrypted image identifier */ #define ENC_IMAGE_ID U(30) +/* FW_CONFIG */ +#define FW_CONFIG_ID U(31) + /* Max Images */ -#define MAX_IMAGE_IDS U(31) +#define MAX_IMAGE_IDS U(32) #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */ diff --git a/include/lib/cpus/aarch64/cortex_a76.h b/include/lib/cpus/aarch64/cortex_a76.h index 7dc7e068a..b522e8e11 100644 --- a/include/lib/cpus/aarch64/cortex_a76.h +++ b/include/lib/cpus/aarch64/cortex_a76.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,6 +20,7 @@ #define CORTEX_A76_CPUECTLR_EL1_WS_THR_L2 (ULL(3) << 24) #define CORTEX_A76_CPUECTLR_EL1_BIT_51 (ULL(1) << 51) +#define CORTEX_A76_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) /******************************************************************************* * CPU Auxiliary Control register specific definitions. @@ -32,6 +33,8 @@ #define CORTEX_A76_CPUACTLR2_EL1 S3_0_C15_C1_1 +#define CORTEX_A76_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2) + #define CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE (ULL(1) << 16) #define CORTEX_A76_CPUACTLR3_EL1 S3_0_C15_C1_2 diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h index 0467ef3bb..bbd647c60 100644 --- a/include/lib/cpus/aarch64/cortex_a77.h +++ b/include/lib/cpus/aarch64/cortex_a77.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ * CPU Extended Control register specific definitions. ******************************************************************************/ #define CORTEX_A77_CPUECTLR_EL1 S3_0_C15_C1_4 +#define CORTEX_A77_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) /******************************************************************************* * CPU Power Control register specific definitions. diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index 09d2b59aa..917e053bd 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -43,8 +43,8 @@ struct fconf_populator { int (*populate)(uintptr_t config); }; -/* Load firmware configuration dtb */ -void fconf_load_config(void); +/* This function supports to load tb_fw_config and fw_config dtb */ +int fconf_load_config(unsigned int image_id); /* Top level populate function * diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h index 0fda8c9b2..9816d6fe0 100644 --- a/include/lib/fconf/fconf_dyn_cfg_getter.h +++ b/include/lib/fconf/fconf_dyn_cfg_getter.h @@ -21,4 +21,7 @@ struct dyn_cfg_dtb_info_t { struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id); int fconf_populate_dtb_registry(uintptr_t config); +/* Set fw_config information in global DTB array */ +void set_fw_config_info(uintptr_t config_addr, uint32_t config_max_size); + #endif /* FCONF_DYN_CFG_GETTER_H */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 89f7c6146..5c11e5fe1 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -346,24 +346,24 @@ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) /* * Boot parameters passed from BL2 to BL31/BL32 are stored here */ -#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT #define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE + \ (PAGE_SIZE / 2U)) /* * Define limit of firmware configuration memory: - * ARM_TB_FW_CONFIG + ARM_BL2_MEM_DESC memory + * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory */ -#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) /******************************************************************************* * BL1 specific defines. @@ -461,7 +461,7 @@ * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding * the page reserved for fw_configs) to BL32 */ -# define BL32_BASE ARM_FW_CONFIG_LIMIT +# define BL32_BASE ARM_FW_CONFIGS_LIMIT # define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) # else /* Put BL32 below BL2 in the Trusted SRAM.*/ @@ -505,7 +505,7 @@ # define TSP_SEC_MEM_BASE ARM_BL_RAM_BASE # define TSP_SEC_MEM_SIZE ARM_BL_RAM_SIZE # define TSP_PROGBITS_LIMIT BL31_BASE -# define BL32_BASE ARM_FW_CONFIG_LIMIT +# define BL32_BASE ARM_FW_CONFIGS_LIMIT # define BL32_LIMIT BL31_BASE # elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID # define TSP_SEC_MEM_BASE PLAT_ARM_TRUSTED_DRAM_BASE diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 1b5979529..36255300e 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -190,7 +190,7 @@ void arm_bl1_platform_setup(void); void arm_bl1_plat_arch_setup(void); /* BL2 utility functions */ -void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, struct meminfo *mem_layout); +void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout); void arm_bl2_platform_setup(void); void arm_bl2_plat_arch_setup(void); uint32_t arm_get_spsr_for_bl32_entry(void); diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h index fe321750a..728507749 100644 --- a/include/services/ffa_svc.h +++ b/include/services/ffa_svc.h @@ -12,13 +12,13 @@ #include <tools_share/uuid.h> /* FFA error codes. */ -#define FFA_ERROR_NOT_SUPPORTED -1 +#define FFA_ERROR_NOT_SUPPORTED -1 #define FFA_ERROR_INVALID_PARAMETER -2 #define FFA_ERROR_NO_MEMORY -3 #define FFA_ERROR_BUSY -4 #define FFA_ERROR_INTERRUPTED -5 #define FFA_ERROR_DENIED -6 -#define FFA_ERROR_RETRY -7 +#define FFA_ERROR_RETRY -7 /* The macros below are used to identify FFA calls from the SMC function ID */ #define FFA_FNUM_MIN_VALUE U(0x60) @@ -30,13 +30,15 @@ /* FFA_VERSION helpers */ #define FFA_VERSION_MAJOR U(1) -#define FFA_VERSION_MAJOR_SHIFT 16 +#define FFA_VERSION_MAJOR_SHIFT 16 #define FFA_VERSION_MAJOR_MASK U(0x7FFF) #define FFA_VERSION_MINOR U(0) -#define FFA_VERSION_MINOR_SHIFT 0 +#define FFA_VERSION_MINOR_SHIFT 0 #define FFA_VERSION_MINOR_MASK U(0xFFFF) +#define FFA_VERSION_BIT31_MASK U(0x1u << 31) -#define MAKE_FFA_VERSION(major, minor) \ + +#define MAKE_FFA_VERSION(major, minor) \ ((((major) & FFA_VERSION_MAJOR_MASK) << FFA_VERSION_MAJOR_SHIFT) | \ (((minor) & FFA_VERSION_MINOR_MASK) << FFA_VERSION_MINOR_SHIFT)) #define FFA_VERSION_COMPILED MAKE_FFA_VERSION(FFA_VERSION_MAJOR, \ diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h index 75f3cc6a6..7342c0ced 100644 --- a/include/tools_share/firmware_image_package.h +++ b/include/tools_share/firmware_image_package.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -77,6 +77,8 @@ {{0x26, 0x25, 0x7c, 0x1a}, {0xdb, 0xc6}, {0x7f, 0x47}, 0x8d, 0x96, {0xc4, 0xc4, 0xb0, 0x24, 0x80, 0x21} } #define UUID_NT_FW_CONFIG \ {{0x28, 0xda, 0x98, 0x15}, {0x93, 0xe8}, {0x7e, 0x44}, 0xac, 0x66, {0x1a, 0xaf, 0x80, 0x15, 0x50, 0xf9} } +#define UUID_FW_CONFIG \ + {{0x58, 0x07, 0xe1, 0x6a}, {0x84, 0x59}, {0x47, 0xbe}, 0x8e, 0xd5, {0x64, 0x8e, 0x8d, 0xdd, 0xab, 0x0e} } typedef struct fip_toc_header { uint32_t name; diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h index 24a8f39ca..37d87d307 100644 --- a/include/tools_share/tbbr_oid.h +++ b/include/tools_share/tbbr_oid.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,6 +43,7 @@ #define TRUSTED_BOOT_FW_HASH_OID "1.3.6.1.4.1.4128.2100.201" #define TRUSTED_BOOT_FW_CONFIG_HASH_OID "1.3.6.1.4.1.4128.2100.202" #define HW_CONFIG_HASH_OID "1.3.6.1.4.1.4128.2100.203" +#define FW_CONFIG_HASH_OID "1.3.6.1.4.1.4128.2100.204" /* * Trusted Key Certificate diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index baefa4676..10011f754 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -392,6 +392,62 @@ func check_errata_1286807 #endif endfunc check_errata_1286807 + /* -------------------------------------------------- + * Errata workaround for Cortex A76 Errata #1791580. + * This applies to revisions <= r4p0 of Cortex A76. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a76_1791580_wa + /* Compare x0 against revision r4p0 */ + mov x17, x30 + bl check_errata_1791580 + cbz x0, 1f + mrs x1, CORTEX_A76_CPUACTLR2_EL1 + orr x1, x1, CORTEX_A76_CPUACTLR2_EL1_BIT_2 + msr CORTEX_A76_CPUACTLR2_EL1, x1 + isb +1: + ret x17 +endfunc errata_a76_1791580_wa + +func check_errata_1791580 + /* Applies to everything <=r4p0. */ + mov x1, #0x40 + b cpu_rev_var_ls +endfunc check_errata_1791580 + + /* -------------------------------------------------- + * Errata Workaround for Cortex A76 Errata #1800710. + * This applies to revision <= r4p0 of Cortex A76. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a76_1800710_wa + /* Compare x0 against revision <= r4p0 */ + mov x17, x30 + bl check_errata_1800710 + cbz x0, 1f + + /* Disable allocation of splintered pages in the L2 TLB */ + mrs x1, CORTEX_A76_CPUECTLR_EL1 + orr x1, x1, CORTEX_A76_CPUECTLR_EL1_BIT_53 + msr CORTEX_A76_CPUECTLR_EL1, x1 + isb +1: + ret x17 +endfunc errata_a76_1800710_wa + +func check_errata_1800710 + /* Applies to everything <= r4p0 */ + mov x1, #0x40 + b cpu_rev_var_ls +endfunc check_errata_1800710 + func check_errata_cve_2018_3639 #if WORKAROUND_CVE_2018_3639 mov x0, #ERRATA_APPLIES @@ -449,6 +505,16 @@ func cortex_a76_reset_func bl errata_a76_1262888_wa #endif +#if ERRATA_A76_1791580 + mov x0, x18 + bl errata_a76_1791580_wa +#endif + +#if ERRATA_A76_1800710 + mov x0, x18 + bl errata_a76_1800710_wa +#endif + #if WORKAROUND_CVE_2018_3639 /* If the PE implements SSBS, we don't need the dynamic workaround */ mrs x0, id_aa64pfr1_el1 @@ -529,6 +595,8 @@ func cortex_a76_errata_report report_errata ERRATA_A76_1262888, cortex_a76, 1262888 report_errata ERRATA_A76_1275112, cortex_a76, 1275112 report_errata ERRATA_A76_1286807, cortex_a76, 1286807 + report_errata ERRATA_A76_1791580, cortex_a76, 1791580 + report_errata ERRATA_A76_1800710, cortex_a76, 1800710 report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639 report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184 diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S index f3fd5e196..0c30460d4 100644 --- a/lib/cpus/aarch64/cortex_a77.S +++ b/lib/cpus/aarch64/cortex_a77.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,6 +21,53 @@ #error "Cortex-A77 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" #endif + /* -------------------------------------------------- + * Errata Workaround for Cortex A77 Errata #1800714. + * This applies to revision <= r1p1 of Cortex A77. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a77_1800714_wa + /* Compare x0 against revision <= r1p1 */ + mov x17, x30 + bl check_errata_1800714 + cbz x0, 1f + + /* Disable allocation of splintered pages in the L2 TLB */ + mrs x1, CORTEX_A77_CPUECTLR_EL1 + orr x1, x1, CORTEX_A77_CPUECTLR_EL1_BIT_53 + msr CORTEX_A77_CPUECTLR_EL1, x1 + isb +1: + ret x17 +endfunc errata_a77_1800714_wa + +func check_errata_1800714 + /* Applies to everything <= r1p1 */ + mov x1, #0x11 + b cpu_rev_var_ls +endfunc check_errata_1800714 + + /* ------------------------------------------------- + * The CPU Ops reset function for Cortex-A77. + * Shall clobber: x0-x19 + * ------------------------------------------------- + */ +func cortex_a77_reset_func + mov x19, x30 + bl cpu_get_rev_var + mov x18, x0 + +#if ERRATA_A77_1800714 + mov x0, x18 + bl errata_a77_1800714_wa +#endif + + ret x19 +endfunc cortex_a77_reset_func + /* --------------------------------------------- * HW will do the cache maintenance while powering down * --------------------------------------------- @@ -42,6 +89,18 @@ endfunc cortex_a77_core_pwr_dwn * Errata printing function for Cortex-A77. Must follow AAPCS. */ func cortex_a77_errata_report + stp x8, x30, [sp, #-16]! + + bl cpu_get_rev_var + mov x8, x0 + + /* + * Report all errata. The revision-variant information is passed to + * checking functions of each errata. + */ + report_errata ERRATA_A77_1800714, cortex_a77, 1800714 + + ldp x8, x30, [sp], #16 ret endfunc cortex_a77_errata_report #endif @@ -67,5 +126,5 @@ func cortex_a77_cpu_reg_dump endfunc cortex_a77_cpu_reg_dump declare_cpu_ops cortex_a77, CORTEX_A77_MIDR, \ - CPU_NO_RESET_FUNC, \ + cortex_a77_reset_func, \ cortex_a77_core_pwr_dwn diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 1bc082d82..e49437569 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -250,6 +250,18 @@ ERRATA_A76_1275112 ?=0 # only to revision <= r3p0 of the Cortex A76 cpu. ERRATA_A76_1286807 ?=0 +# Flag to apply erratum 1791580 workaround during reset. This erratum applies +# only to revision <= r4p0 of the Cortex A76 cpu. +ERRATA_A76_1791580 ?=0 + +# Flag to apply erratum 1800710 workaround during reset. This erratum applies +# only to revision <= r4p0 of the Cortex A76 cpu. +ERRATA_A76_1800710 ?=0 + +# Flag to apply erratum 1800714 workaround during reset. This erratum applies +# only to revision <= r1p1 of the Cortex A77 cpu. +ERRATA_A77_1800714 ?=0 + # Flag to apply erratum 1688305 workaround during reset. This erratum applies # to revisions r0p0 - r1p0 of the A78 cpu. ERRATA_A78_1688305 ?=0 @@ -487,6 +499,18 @@ $(eval $(call add_define,ERRATA_A76_1275112)) $(eval $(call assert_boolean,ERRATA_A76_1286807)) $(eval $(call add_define,ERRATA_A76_1286807)) +# Process ERRATA_A76_1791580 flag +$(eval $(call assert_boolean,ERRATA_A76_1791580)) +$(eval $(call add_define,ERRATA_A76_1791580)) + +# Process ERRATA_A76_1800710 flag +$(eval $(call assert_boolean,ERRATA_A76_1800710)) +$(eval $(call add_define,ERRATA_A76_1800710)) + +# Process ERRATA_A77_1800714 flag +$(eval $(call assert_boolean,ERRATA_A77_1800714)) +$(eval $(call add_define,ERRATA_A77_1800714)) + # Process ERRATA_A78_1688305 flag $(eval $(call assert_boolean,ERRATA_A78_1688305)) $(eval $(call add_define,ERRATA_A78_1688305)) diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c index 70ac3bc04..b0ee39a11 100644 --- a/lib/debugfs/devfip.c +++ b/lib/debugfs/devfip.c @@ -73,6 +73,7 @@ static const struct uuidnames uuidnames[] = { {"soc-fw.cfg", UUID_SOC_FW_CONFIG}, {"tos-fw.cfg", UUID_TOS_FW_CONFIG}, {"nt-fw.cfg", UUID_NT_FW_CONFIG}, + {"fw.cfg", UUID_FW_CONFIG}, {"rot-k.crt", UUID_ROT_KEY_CERT}, {"nt-k.crt", UUID_NON_TRUSTED_WORLD_KEY_CERT}, {"sip-sp.crt", UUID_SIP_SECURE_PARTITION_CONTENT_CERT} diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index a5ec14300..bc4fa8ea8 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -9,48 +9,43 @@ #include <common/debug.h> #include <common/fdt_wrappers.h> #include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> #include <libfdt.h> #include <plat/common/platform.h> #include <platform_def.h> -struct fconf_dtb_info_t fconf_dtb_info; - -void fconf_load_config(void) +int fconf_load_config(unsigned int image_id) { int err; - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ - image_info_t arm_tb_fw_info = { + const struct dyn_cfg_dtb_info_t *config_info; + + assert((image_id == FW_CONFIG_ID) || (image_id == TB_FW_CONFIG_ID)); + + image_info_t config_image_info = { .h.type = (uint8_t)PARAM_IMAGE_BINARY, .h.version = (uint8_t)VERSION_2, .h.size = (uint16_t)sizeof(image_info_t), - .h.attr = 0, - .image_base = ARM_TB_FW_CONFIG_BASE, - .image_max_size = (uint32_t) - (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE) + .h.attr = 0 }; - VERBOSE("FCONF: Loading FW_CONFIG\n"); - err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info); - if (err != 0) { - /* Return if FW_CONFIG is not loaded */ - VERBOSE("FW_CONFIG not loaded, continuing without it\n"); - return; - } + config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_id); + assert(config_info != NULL); - /* At this point we know that a DTB is indeed available */ - fconf_dtb_info.base_addr = arm_tb_fw_info.image_base; - fconf_dtb_info.size = (size_t)arm_tb_fw_info.image_size; + config_image_info.image_base = config_info->config_addr; + config_image_info.image_max_size = + (uint32_t)config_info->config_max_size; -#if !BL2_AT_EL3 - image_desc_t *desc; + VERBOSE("FCONF: Loading config with image ID: %d\n", image_id); + err = load_auth_image(image_id, &config_image_info); + if (err != 0) { + VERBOSE("Failed to load config %d\n", image_id); + return err; + } - /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ - desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(desc != NULL); - desc->ep_info.args.arg0 = arm_tb_fw_info.image_base; -#endif + INFO("FCONF: Config file with image ID:%d loaded at address = 0x%lx\n", + image_id, config_image_info.image_base); - INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base); + return 0; } void fconf_populate(const char *config_type, uintptr_t config) @@ -81,7 +76,4 @@ void fconf_populate(const char *config_type, uintptr_t config) } } } - - /* save local pointer to the config dtb */ - fconf_dtb_info.base_addr = config; } diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk index c087102d7..b01dc6fea 100644 --- a/lib/fconf/fconf.mk +++ b/lib/fconf/fconf.mk @@ -8,5 +8,5 @@ FCONF_SOURCES := lib/fconf/fconf.c FCONF_DYN_SOURCES := lib/fconf/fconf_dyn_cfg_getter.c -BL1_SOURCES += ${FCONF_SOURCES} +BL1_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 7b5bd6ec9..902c07d95 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -12,12 +12,27 @@ #include <lib/object_pool.h> #include <libfdt.h> -/* We currently use TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */ -#define MAX_DTB_INFO U(5) +/* We currently use FW, TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */ +#define MAX_DTB_INFO U(6) static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO]; static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos); +/* + * This function is used to alloc memory for fw config information from + * global pool and set fw configuration information. + * Specifically used by BL1 to set fw_config information in global array + */ +void set_fw_config_info(uintptr_t config_addr, uint32_t config_max_size) +{ + struct dyn_cfg_dtb_info_t *dtb_info; + + dtb_info = pool_alloc(&dtb_info_pool); + dtb_info->config_addr = config_addr; + dtb_info->config_max_size = config_max_size; + dtb_info->config_id = FW_CONFIG_ID; +} + struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id) { unsigned int index; @@ -48,6 +63,30 @@ int fconf_populate_dtb_registry(uintptr_t config) /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; + /* + * Compile time assert if FW_CONFIG_ID is 0 which is more + * unlikely as 0 is a valid image id for FIP as per the current + * code but still to avoid code breakage in case of unlikely + * event when image ids gets changed. + */ + CASSERT(FW_CONFIG_ID != 0, assert_invalid_fw_config_id); + + /* + * In case of BL1, fw_config dtb information is already + * populated in global dtb_infos array by 'set_fw_config_info' + * function, Below check is present to avoid re-population of + * fw_config information. + * + * Other BLs, satisfy below check and populate fw_config information + * in global dtb_infos array. + */ + if (dtb_infos[0].config_id == 0) { + dtb_info = pool_alloc(&dtb_info_pool); + dtb_info->config_addr = config; + dtb_info->config_max_size = fdt_totalsize(dtb); + dtb_info->config_id = FW_CONFIG_ID; + } + /* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */ const char *compatible_str = "fconf,dyn_cfg-dtb_registry"; node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); @@ -98,4 +137,4 @@ int fconf_populate_dtb_registry(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(TB_FW, dyn_cfg, fconf_populate_dtb_registry); +FCONF_REGISTER_POPULATOR(FW_CONFIG, dyn_cfg, fconf_populate_dtb_registry); diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts index b9d905388..b9ff8bff1 100644 --- a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts +++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained in this dtb */ tb_fw-config { - load-address = <0x0 0x2001010>; + load-address = <0x0 0x2001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -25,11 +24,4 @@ id = <HW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - }; }; diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts new file mode 100644 index 000000000..c66186f64 --- /dev/null +++ b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h index ab0ff5859..07453166a 100644 --- a/plat/arm/board/a5ds/include/platform_def.h +++ b/plat/arm/board/a5ds/include/platform_def.h @@ -188,11 +188,11 @@ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) /******************************************************************************* * BL1 specific defines. @@ -220,7 +220,7 @@ #define BL2_LIMIT BL1_RW_BASE /* Put BL32 below BL2 in NS DRAM.*/ -#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT #define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\ - PLAT_ARM_MAX_BL32_SIZE) diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index 3a4d5e56d..7693e46e1 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -72,10 +72,13 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb +FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ fdts/$(notdir ${FVP_HW_CONFIG_DTS}))) @@ -83,6 +86,7 @@ $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \ + plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \ ${FVP_HW_CONFIG_DTS} endif diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h index cc4dc3a59..7799cec00 100644 --- a/plat/arm/board/corstone700/include/platform_def.h +++ b/plat/arm/board/corstone700/include/platform_def.h @@ -83,11 +83,11 @@ #define ARM_CACHE_WRITEBACK_SHIFT 6 /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space for BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) /* * The max number of regions like RO(code), coherent and data required by diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c index 8172a6ebe..35a777b6f 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -14,6 +14,7 @@ struct gicv3_config_t gicv3_config; struct hw_topology_t soc_topology; struct uart_serial_config_t uart_serial_config; +struct cpu_timer_t cpu_timer; #define ILLEGAL_ADDR ULL(~0) @@ -260,9 +261,36 @@ int fconf_populate_uart_config(uintptr_t config) VERBOSE("FCONF: UART serial device clk frequency: %x\n", uart_serial_config.uart_clk); + + return 0; +} + +int fconf_populate_cpu_timer(uintptr_t config) +{ + int err, node; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* Find the node offset point to "arm,armv8-timer" compatible property, + * a per-core architected timer attached to a GIC to deliver its per-processor + * interrupts via PPIs */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,armv8-timer"); + if (node < 0) { + ERROR("FCONF: Unrecognized hardware configuration dtb (%d)\n", node); + return node; + } + + /* Locate the cell holding the clock-frequency, an optional field */ + err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency", &cpu_timer.clock_freq); + if (err < 0) { + WARN("FCONF failed to read clock-frequency property\n"); + } + return 0; } FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config); FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config); +FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer); diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 5f89284ee..09f2730d9 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -32,14 +31,14 @@ * is loaded at base of DRAM. */ soc_fw-config { - load-address = <0x0 0x04001000>; + load-address = <0x0 0x04001300>; max-size = <0x200>; id = <SOC_FW_CONFIG_ID>; }; tos_fw-config { - load-address = <0x0 0x04001200>; - max-size = <0x1000>; + load-address = <0x0 0x04001500>; + max-size = <0xB00>; id = <TOS_FW_CONFIG_ID>; }; @@ -49,83 +48,4 @@ id = <NT_FW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - -#if MEASURED_BOOT - /* BL2 image hash calculated by BL1 */ - bl2_hash_data = [ - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#if BL2_HASH_SIZE > 32 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#if BL2_HASH_SIZE > 48 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#endif /* > 48 */ -#endif /* > 32 */ - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]; -#endif /* MEASURED_BOOT */ - }; - - /* - * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in - * network order (big endian), UUID's mentioned in this file are are - * stored in machine order (little endian). - * This will be fixed in future. - */ -#if ARM_IO_IN_DTB - arm-io_policies { - fip-handles { - compatible = "arm,io-fip-handle"; - scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>; - bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>; - bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>; - bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>; - bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>; - bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>; - hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>; - soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>; - tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>; - nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>; - t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>; - scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>; - soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>; - tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>; - nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>; - scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>; - soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; - tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; - nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; - sp_content_cert_uuid = <0x44fd6d77 0x3b4c9786 0x3ec1eb91 0x6f2a5a02>; - }; - }; -#endif /* ARM_IO_IN_DTB */ - - secure-partitions { - compatible = "arm,sp"; - cactus-primary { - uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; - load-address = <0x7000000>; - }; - - cactus-secondary { - uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; - load-address = <0x7100000>; - }; - }; }; diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts new file mode 100644 index 000000000..9cffad310 --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + +#if MEASURED_BOOT + /* BL2 image hash calculated by BL1 */ + bl2_hash_data = [ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +#if BL2_HASH_SIZE > 32 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +#if BL2_HASH_SIZE > 48 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +#endif /* > 48 */ +#endif /* > 32 */ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]; +#endif /* MEASURED_BOOT */ + }; + + /* + * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in + * network order (big endian), UUID's mentioned in this file are are + * stored in machine order (little endian). + * This will be fixed in future. + */ +#if ARM_IO_IN_DTB + arm-io_policies { + fip-handles { + compatible = "arm,io-fip-handle"; + scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>; + bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>; + bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>; + bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>; + bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>; + bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>; + hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>; + soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>; + tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>; + nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>; + t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>; + scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>; + soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>; + tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>; + nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>; + scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>; + soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; + tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; + nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; + sp_content_cert_uuid = <0x44fd6d77 0x3b4c9786 0x3ec1eb91 0x6f2a5a02>; + }; + }; +#endif /* ARM_IO_IN_DTB */ + + secure-partitions { + compatible = "arm,sp"; + cactus-primary { + uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; + load-address = <0x7000000>; + }; + + cactus-secondary { + uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; + load-address = <0x7100000>; + }; + }; +}; diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 43b137481..d5618d99b 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -4,7 +4,13 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> + +#include <common/desc_image_load.h> #include <drivers/arm/sp804_delay_timer.h> +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> + #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> #include <platform_def.h> @@ -26,3 +32,40 @@ void bl2_platform_setup(void) /* Initialize System level generic or SP804 timer */ fvp_timer_init(); } + +/******************************************************************************* + * This function returns the list of executable images + ******************************************************************************/ +struct bl_params *plat_get_next_bl_params(void) +{ + struct bl_params *arm_bl_params; + + arm_bl_params = arm_get_next_bl_params(); + +#if __aarch64__ && !BL2_AT_EL3 + const struct dyn_cfg_dtb_info_t *fw_config_info; + bl_mem_params_node_t *param_node; + uintptr_t fw_config_base = 0U; + entry_point_info_t *ep_info; + + /* Get BL31 image node */ + param_node = get_bl_mem_params_node(BL31_IMAGE_ID); + assert(param_node != NULL); + + /* get fw_config load address */ + fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); + assert(fw_config_info != NULL); + + fw_config_base = fw_config_info->config_addr; + assert(fw_config_base != 0U); + + /* + * Get the entry point info of BL31 image and override + * arg1 of entry point info with fw_config base address + */ + ep_info = ¶m_node->ep_info; + ep_info->args.arg1 = (uint32_t)fw_config_base; +#endif /* __aarch64__ && !BL2_AT_EL3 */ + + return arm_bl_params; +} diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index dc7bfa2dc..f9ee4492f 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -7,18 +7,32 @@ #include <assert.h> #include <common/debug.h> #include <drivers/arm/smmu_v3.h> +#include <fconf_hw_config_getter.h> #include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> +#include <lib/mmio.h> #include <plat/arm/common/arm_config.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> #include "fvp_private.h" -uintptr_t hw_config_dtb; - void __init bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { +#if !RESET_TO_BL31 && !BL2_AT_EL3 + const struct dyn_cfg_dtb_info_t *soc_fw_config_info; + + INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1); + /* Fill the properties struct with the info from the config dtb */ + fconf_populate("FW_CONFIG", arg1); + + soc_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, SOC_FW_CONFIG_ID); + if (soc_fw_config_info != NULL) { + arg1 = soc_fw_config_info->config_addr; + } +#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */ + arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); /* Initialize the platform config for future decision making */ @@ -45,8 +59,6 @@ void __init bl31_early_platform_setup2(u_register_t arg0, /* On FVP RevC, initialize SMMUv3 */ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) smmuv3_init(PLAT_FVP_SMMUV3_BASE); - - hw_config_dtb = arg2; } void __init bl31_plat_arch_setup(void) @@ -59,9 +71,35 @@ void __init bl31_plat_arch_setup(void) * control is passed to BL31. */ #if !RESET_TO_BL31 && !BL2_AT_EL3 - assert(hw_config_dtb != 0U); + /* HW_CONFIG was also loaded by BL2 */ + const struct dyn_cfg_dtb_info_t *hw_config_info; + + hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID); + assert(hw_config_info != NULL); + + fconf_populate("HW_CONFIG", hw_config_info->config_addr); +#endif +} + +unsigned int plat_get_syscnt_freq2(void) +{ + unsigned int counter_base_frequency; - INFO("BL31 FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb); - fconf_populate("HW_CONFIG", hw_config_dtb); +#if !RESET_TO_BL31 && !BL2_AT_EL3 + /* Get the frequency through FCONF API for HW_CONFIG */ + counter_base_frequency = FCONF_GET_PROPERTY(hw_config, cpu_timer, clock_freq); + if (counter_base_frequency > 0U) { + return counter_base_frequency; + } #endif + + /* Read the frequency from Frequency modes table */ + counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF); + + /* The first entry of the frequency modes table must not be 0 */ + if (counter_base_frequency == 0U) { + panic(); + } + + return counter_base_frequency; } diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h index b53e00ae1..ca85f7a70 100644 --- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -11,10 +11,9 @@ /* Hardware Config related getter */ #define hw_config__gicv3_config_getter(prop) gicv3_config.prop - #define hw_config__topology_getter(prop) soc_topology.prop - #define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop +#define hw_config__cpu_timer_getter(prop) cpu_timer.prop struct gicv3_config_t { uint64_t gicd_base; @@ -33,12 +32,17 @@ struct uart_serial_config_t { uint32_t uart_clk; }; +struct cpu_timer_t { + uint32_t clock_freq; +}; + int fconf_populate_gicv3_config(uintptr_t config); int fconf_populate_topology(uintptr_t config); int fconf_populate_uart_config(uintptr_t config); +int fconf_populate_cpu_timer(uintptr_t config); extern struct gicv3_config_t gicv3_config; extern struct hw_topology_t soc_topology; extern struct uart_serial_config_t uart_serial_config; - +extern struct cpu_timer_t cpu_timer; #endif /* FCONF_HW_CONFIG_GETTER_H */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 62ede9ab8..7222c5519 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -133,7 +133,7 @@ * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3E000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000) #endif /* RESET_TO_BL31 */ #ifndef __aarch64__ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 7d670accc..c3b49bb58 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -217,6 +217,7 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31}),) BL31_SOURCES += common/fdt_wrappers.c \ lib/fconf/fconf.c \ + lib/fconf/fconf_dyn_cfg_getter.c \ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c ifeq (${SEC_INT_DESC_IN_FCONF},1) @@ -236,11 +237,13 @@ ifdef UNIX_MK FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ ${PLAT}_fw_config.dts \ + ${PLAT}_tb_fw_config.dts \ ${PLAT}_soc_fw_config.dts \ ${PLAT}_nt_fw_config.dts \ ) -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb @@ -260,6 +263,8 @@ FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) endif +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) # Add the SOC_FW_CONFIG to FIP and specify the same to certtool diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts index d4f98d940..6e5691bd9 100644 --- a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x80001010>; + load-address = <0x0 0x80001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -25,11 +24,4 @@ id = <HW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - }; }; diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts new file mode 100644 index 000000000..c66186f64 --- /dev/null +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h index 70a12ea53..3591b4d6d 100644 --- a/plat/arm/board/fvp_ve/include/platform_def.h +++ b/plat/arm/board/fvp_ve/include/platform_def.h @@ -169,11 +169,11 @@ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) /******************************************************************************* * BL1 specific defines. @@ -204,7 +204,7 @@ /* Put BL32 below BL2 in NS DRAM.*/ -#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT #define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\ - PLAT_ARM_MAX_BL32_SIZE) diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 9ada86bf1..62981c529 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -74,10 +74,14 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts +FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts \ + plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb +FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts index 60ca60daa..c0538f863 100644 --- a/plat/arm/board/juno/fdts/juno_fw_config.dts +++ b/plat/arm/board/juno/fdts/juno_fw_config.dts @@ -12,29 +12,10 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; }; - - tb_fw-config { - /* Platform Config */ - compatible = "arm,tb_fw"; - /* Disable authentication for development */ - disable_auth = <0x0>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts new file mode 100644 index 000000000..80cfa3ea1 --- /dev/null +++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 67802d487..91c3ae7e0 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -139,7 +139,7 @@ # define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif #else -# define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - JUNO_BL2_ROMLIB_OPTIMIZATION) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif /* @@ -148,7 +148,7 @@ * BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL31 -> BL2_BASE. * Hence the BL31 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE. */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3E000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000) #if JUNO_AARCH32_EL3_RUNTIME /* @@ -157,7 +157,7 @@ * BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL32 -> BL2_BASE. * Hence the BL32 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE. */ -#define PLAT_ARM_MAX_BL32_SIZE UL(0x3E000) +#define PLAT_ARM_MAX_BL32_SIZE UL(0x3D000) #endif /* @@ -254,7 +254,7 @@ * BL31 is loaded over the top. */ #define PLAT_CSS_MAX_SCP_BL2_SIZE \ - ((SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) + ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) #define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index a871e81ac..8ca7f6120 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -164,9 +164,14 @@ ifeq (${ALLOW_RO_XLAT_TABLES}, 1) endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts \ + plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts index b9265ad9e..9c9cefe87 100644 --- a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts +++ b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -25,23 +24,4 @@ id = <NT_FW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index 94a3928f8..bdf20ca3d 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -33,9 +33,13 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ plat/arm/common/arm_nor_psci_mem_protect.c # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts index b9265ad9e..9c9cefe87 100644 --- a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts +++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -25,23 +24,4 @@ id = <NT_FW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk index 36a00993a..1482c814f 100644 --- a/plat/arm/board/rddanielxlr/platform.mk +++ b/plat/arm/board/rddanielxlr/platform.mk @@ -36,9 +36,13 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDDANIELXLR_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts index 09b9867e3..69fb0d498 100644 --- a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -25,23 +24,4 @@ id = <NT_FW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts new file mode 100644 index 000000000..dba91e535 --- /dev/null +++ b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index 1a4dd17d1..e09afcad3 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -35,9 +35,13 @@ BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts index c9dee60d1..d3b7fba49 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts @@ -11,9 +11,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -24,24 +23,5 @@ id = <NT_FW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts new file mode 100644 index 000000000..257ef4a3f --- /dev/null +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index e43654292..3f0cc7f4a 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -41,9 +41,13 @@ endif BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts index 94d0e39a8..84fc1ad5f 100644 --- a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts +++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -25,23 +24,4 @@ id = <NT_FW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index d91f829ee..f5d547dd1 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -35,9 +35,14 @@ BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_fw_config.dts \ + ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts index c92c1d055..5d478e9a5 100644 --- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts +++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts @@ -12,30 +12,10 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 57edb923d..26bc25dec 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -9,9 +9,13 @@ include plat/arm/css/sgm/sgm-common.mk SGM775_BASE= plat/arm/board/sgm775 # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts \ + ${SGM775_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts index 8458e0889..381ce1fcb 100644 --- a/plat/arm/board/tc0/fdts/tc0_fw_config.dts +++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained in this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = <TB_FW_CONFIG_ID>; }; @@ -25,22 +24,4 @@ id = <HW_CONFIG_ID>; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts new file mode 100644 index 000000000..2fd25d9b4 --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 7f514cc67..0bf18e437 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -73,9 +73,13 @@ BL31_SOURCES += ${INTERCONNECT_SOURCES} \ plat/arm/common/arm_nor_psci_mem_protect.c # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${TC0_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${TC0_BASE}/fdts/${PLAT}_fw_config.dts \ + ${TC0_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index c2f49c211..6b630b980 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -12,6 +12,7 @@ #include <bl1/bl1.h> #include <common/bl_common.h> #include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> #include <lib/utils.h> #include <lib/xlat_tables/xlat_tables_compat.h> #include <plat/arm/common/plat_arm.h> @@ -142,11 +143,58 @@ void bl1_plat_arch_setup(void) */ void arm_bl1_platform_setup(void) { + const struct dyn_cfg_dtb_info_t *fw_config_info; + image_desc_t *desc; + uint32_t fw_config_max_size; + int err = -1; + /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - /* Load fw config */ - fconf_load_config(); + /* Check if we need FWU before further processing */ + err = plat_arm_bl1_fwu_needed(); + if (err) { + ERROR("Skip platform setup as FWU detected\n"); + return; + } + + /* Set global DTB info for fixed fw_config information */ + fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE; + set_fw_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size); + + /* Fill the device tree information struct with the info from the config dtb */ + err = fconf_load_config(FW_CONFIG_ID); + if (err < 0) { + ERROR("Loading of FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + + /* + * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing + * is successful then load TB_FW_CONFIG device tree. + */ + fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); + if (fw_config_info != NULL) { + err = fconf_populate_dtb_registry(fw_config_info->config_addr); + if (err < 0) { + ERROR("Parsing of FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + /* load TB_FW_CONFIG */ + err = fconf_load_config(TB_FW_CONFIG_ID); + if (err < 0) { + ERROR("Loading of TB_FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + } else { + ERROR("Invalid FW_CONFIG address\n"); + plat_error_handler(err); + } + + /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(desc != NULL); + desc->ep_info.args.arg0 = fw_config_info->config_addr; #if TRUSTED_BOARD_BOOT /* Share the Mbed TLS heap info with other images */ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 6c3f64fb6..e4a4f8724 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -15,6 +15,7 @@ #include <common/desc_image_load.h> #include <drivers/generic_delay_timer.h> #include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> #ifdef SPD_opteed #include <lib/optee_utils.h> #endif @@ -26,10 +27,10 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); /* - * Check that BL2_BASE is above ARM_TB_FW_CONFIG_LIMIT. This reserved page is + * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is * for `meminfo_t` data structure and fw_configs passed from BL1. */ -CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); +CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl2_early_platform_setup2 @@ -50,9 +51,10 @@ CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); * in x0. This memory layout is sitting at the base of the free trusted SRAM. * Copy it to a safe location before its reclaimed by later BL2 functionality. ******************************************************************************/ -void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, +void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout) { + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; /* Initialize the console to provide early debug support */ arm_console_boot_init(); @@ -60,8 +62,14 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, bl2_tzram_layout = *mem_layout; /* Fill the properties struct with the info from the config dtb */ - if (tb_fw_config != 0U) { - fconf_populate("TB_FW", tb_fw_config); + if (fw_config != 0U) { + fconf_populate("FW_CONFIG", fw_config); + } + + /* TB_FW_CONFIG was also loaded by BL1 */ + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + if (tb_fw_config_info != NULL) { + fconf_populate("TB_FW", tb_fw_config_info->config_addr); } /* Initialise the IO layer and register platform IO devices */ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 85535c11a..ded8f895e 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -28,10 +28,10 @@ static entry_point_info_t bl33_image_ep_info; #if !RESET_TO_BL31 /* - * Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page + * Check that BL31_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ -CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); +CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #endif /* Weak definitions may be overridden in specific ARM standard platform */ diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index ffa2a64d8..a28e0ccff 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -77,6 +77,7 @@ void arm_bl1_set_mbedtls_heap(void) { int err; uintptr_t tb_fw_cfg_dtb; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current @@ -91,8 +92,8 @@ void arm_bl1_set_mbedtls_heap(void) * the default heap's address and size. */ - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ - tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr); + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { /* As libfdt use void *, we can't avoid this cast */ @@ -130,9 +131,10 @@ void arm_bl1_set_bl2_hash(image_desc_t *image_desc) image_info_t image_info = image_desc->image_info; uintptr_t tb_fw_cfg_dtb; int err; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ - tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr); + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current @@ -170,8 +172,8 @@ void arm_bl1_set_bl2_hash(image_desc_t *image_desc) /* * BL2 utility function to initialize dynamic configuration specified by - * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if - * specified in TB_FW_CONFIG. + * FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if + * specified in FW_CONFIG. */ void arm_bl2_dyn_cfg_init(void) { diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 68cd9fb37..48cc4fee3 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -25,6 +25,7 @@ const io_block_spec_t fip_block_spec = { const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2}, [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG}, + [FW_CONFIG_ID] = {UUID_FW_CONFIG}, #if !ARM_IO_IN_DTB [SCP_BL2_IMAGE_ID] = {UUID_SCP_FIRMWARE_SCP_BL2}, [BL31_IMAGE_ID] = {UUID_EL3_RUNTIME_FIRMWARE_BL31}, @@ -73,6 +74,11 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID], open_fip }, + [FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[FW_CONFIG_ID], + open_fip + }, #if !ARM_IO_IN_DTB [SCP_BL2_IMAGE_ID] = { &fip_dev_handle, diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index 2904ad942..6100b7834 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -29,10 +29,10 @@ static entry_point_info_t bl33_image_ep_info; MT_MEMORY | MT_RW | MT_SECURE) /* - * Check that BL32_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page + * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ -CASSERT(BL32_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl32_base_overflows); +CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows); /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts index d48101842..e41654048 100644 --- a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts +++ b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 8be0b344f..2d8e6778f 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -138,7 +138,7 @@ * BL31 is loaded over the top. */ #define PLAT_CSS_MAX_SCP_BL2_SIZE \ - ((SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) + ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) #define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE diff --git a/plat/brcm/board/stingray/src/bl31_setup.c b/plat/brcm/board/stingray/src/bl31_setup.c index d94755184..a2a274dcd 100644 --- a/plat/brcm/board/stingray/src/bl31_setup.c +++ b/plat/brcm/board/stingray/src/bl31_setup.c @@ -923,7 +923,7 @@ void plat_bcm_bl31_early_platform_setup(void *from_bl2, scp_image_info.image_base = PRELOADED_SCP_BASE; scp_image_info.image_size = PRELOADED_SCP_SIZE; - bcm_bl2_plat_handle_scp_bl2(&scp_image_info); + plat_bcm_bl2_plat_handle_scp_bl2(&scp_image_info); #endif /* * In BL31, logs are saved to DDR and we have much larger space to diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 5555f5df3..4d69ccca3 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -280,57 +280,33 @@ static void tegra_clear_videomem(uintptr_t non_overlap_area_start, { int ret; + INFO("Cleaning previous Video Memory Carveout\n"); + /* * Map the NS memory first, clean it and then unmap it. */ ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ non_overlap_area_start, /* VA */ non_overlap_area_size, /* size */ - MT_NS | MT_RW | MT_EXECUTE_NEVER | - MT_NON_CACHEABLE); /* attrs */ + MT_DEVICE | MT_RW | MT_NS); /* attrs */ assert(ret == 0); - zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size); + zeromem((void *)non_overlap_area_start, non_overlap_area_size); flush_dcache_range(non_overlap_area_start, non_overlap_area_size); - (void)mmap_remove_dynamic_region(non_overlap_area_start, + ret = mmap_remove_dynamic_region(non_overlap_area_start, non_overlap_area_size); + assert(ret == 0); } -/* - * Program the Video Memory carveout region - * - * phys_base = physical base of aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) +static void tegra_clear_videomem_nonoverlap(uintptr_t phys_base, + unsigned long size_in_bytes) { uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20); uintptr_t vmem_end_new = phys_base + size_in_bytes; unsigned long long non_overlap_area_size; /* - * Setup the Memory controller to restrict CPU accesses to the Video - * Memory region - */ - INFO("Configuring Video Memory Carveout\n"); - - /* - * Configure Memory Controller directly for the first time. - */ - if (video_mem_base == 0U) - goto done; - - /* - * Lock the non overlapping memory being cleared so that other masters - * do not accidently write to it. The memory would be unlocked once - * the non overlapping region is cleared and the new memory - * settings take effect. - */ - tegra_lock_videomem_nonoverlap(video_mem_base, - video_mem_size_mb << 20); - - /* * Clear the old regions now being exposed. The following cases * can occur - * @@ -338,8 +314,6 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) * 2. clear old sub-region below new base * 3. clear old sub-region above new end */ - INFO("Cleaning previous Video Memory Carveout\n"); - if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) { tegra_clear_videomem(video_mem_base, video_mem_size_mb << 20U); @@ -353,26 +327,55 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) tegra_clear_videomem(vmem_end_new, non_overlap_area_size); } } +} + +/* + * Program the Video Memory carveout region + * + * phys_base = physical base of aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + /* + * Setup the Memory controller to restrict CPU accesses to the Video + * Memory region + */ + + INFO("Configuring Video Memory Carveout\n"); + + if (video_mem_base != 0U) { + /* + * Lock the non overlapping memory being cleared so that + * other masters do not accidently write to it. The memory + * would be unlocked once the non overlapping region is + * cleared and the new memory settings take effect. + */ + tegra_lock_videomem_nonoverlap(video_mem_base, + video_mem_size_mb << 20); + } -done: /* program the Videomem aperture */ tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32)); tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); - /* unlock the previous locked nonoverlapping aperture */ - tegra_unlock_videomem_nonoverlap(); - - /* store new values */ - video_mem_base = phys_base; - video_mem_size_mb = size_in_bytes >> 20; - /* * MCE propagates the VideoMem configuration values across the * CCPLEX. */ - mce_update_gsc_videomem(); + (void)mce_update_gsc_videomem(); + + /* Clear the non-overlapping memory */ + if (video_mem_base != 0U) { + tegra_clear_videomem_nonoverlap(phys_base, size_in_bytes); + tegra_unlock_videomem_nonoverlap(); + } + + /* store new values */ + video_mem_base = phys_base; + video_mem_size_mb = (uint64_t)size_in_bytes >> 20; } /* diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 269afb196..40713b2c7 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -367,7 +367,15 @@ void bl31_plat_arch_setup(void) int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) { uint64_t end = base + size_in_bytes - U(1); - int32_t ret = 0; + + /* + * Sanity check the input values + */ + if ((base == 0U) || (size_in_bytes == 0U)) { + ERROR("NS address 0x%llx (%lld bytes) is invalid\n", + base, size_in_bytes); + return -EINVAL; + } /* * Check if the NS DRAM address is valid @@ -376,7 +384,7 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) (end > TEGRA_DRAM_END)) { ERROR("NS address 0x%llx is out-of-bounds!\n", base); - ret = -EFAULT; + return -EFAULT; } /* @@ -385,9 +393,9 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) */ if ((base < (uint64_t)TZDRAM_END) && (end > tegra_bl31_phys_base)) { ERROR("NS address 0x%llx overlaps TZDRAM!\n", base); - ret = -ENOTSUP; + return -ENOTSUP; } /* valid NS address */ - return ret; + return 0; } diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index a86a31535..82dd60697 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -14,6 +14,12 @@ PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} COMMON_DIR := plat/nvidia/tegra/common +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk +TEGRA_GICv3_SOURCES := $(GICV3_SOURCES) \ + plat/common/plat_gicv3.c \ + ${COMMON_DIR}/tegra_gicv3.c + TEGRA_GICv2_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_main.c \ drivers/arm/gic/v2/gicv2_helpers.c \ diff --git a/plat/nvidia/tegra/common/tegra_gicv3.c b/plat/nvidia/tegra/common/tegra_gicv3.c new file mode 100644 index 000000000..cba2f9b95 --- /dev/null +++ b/plat/nvidia/tegra/common/tegra_gicv3.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/bl_common.h> +#include <drivers/arm/gicv3.h> +#include <lib/utils.h> + +#include <plat/common/platform.h> +#include <platform_def.h> +#include <tegra_private.h> +#include <tegra_def.h> + +/* The GICv3 driver only needs to be initialized in EL3 */ +static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static unsigned int plat_tegra_mpidr_to_core_pos(unsigned long mpidr) +{ + return (unsigned int)plat_core_pos_by_mpidr(mpidr); +} + +/****************************************************************************** + * Tegra common helper to setup the GICv3 driver data. + *****************************************************************************/ +void tegra_gic_setup(const interrupt_prop_t *interrupt_props, + unsigned int interrupt_props_num) +{ + /* + * Tegra GIC configuration settings + */ + static gicv3_driver_data_t tegra_gic_data; + + /* + * Register Tegra GICv3 driver + */ + tegra_gic_data.gicd_base = TEGRA_GICD_BASE; + tegra_gic_data.gicr_base = TEGRA_GICR_BASE; + tegra_gic_data.rdistif_num = PLATFORM_CORE_COUNT; + tegra_gic_data.rdistif_base_addrs = rdistif_base_addrs; + tegra_gic_data.mpidr_to_core_pos = plat_tegra_mpidr_to_core_pos; + tegra_gic_data.interrupt_props = interrupt_props; + tegra_gic_data.interrupt_props_num = interrupt_props_num; + gicv3_driver_init(&tegra_gic_data); + + /* initialize the GICD and GICR */ + tegra_gic_init(); +} + +/****************************************************************************** + * Tegra common helper to initialize the GICv3 only driver. + *****************************************************************************/ +void tegra_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +/****************************************************************************** + * Tegra common helper to disable the GICv3 CPU interface + *****************************************************************************/ +void tegra_gic_cpuif_deactivate(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +/****************************************************************************** + * Tegra common helper to initialize the per cpu distributor interface + * in GICv3 + *****************************************************************************/ +void tegra_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk index 180620e88..de54e0945 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk @@ -25,3 +25,6 @@ BL32_SOURCES += plat/common/plat_psci_common.c # stm32mp1 specific services BL32_SOURCES += plat/st/stm32mp1/services/bsec_svc.c \ plat/st/stm32mp1/services/stm32mp1_svc_setup.c + +# Arm Archtecture services +BL32_SOURCES += services/arm_arch_svc/arm_arch_svc_setup.c diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index e1799eda6..1f96239c8 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -77,7 +77,25 @@ entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) return next_image_info; } +CASSERT((STM32MP_SEC_SYSRAM_BASE == STM32MP_SYSRAM_BASE) && + ((STM32MP_SEC_SYSRAM_BASE + STM32MP_SEC_SYSRAM_SIZE) <= + (STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE)), + assert_secure_sysram_fits_at_begining_of_sysram); + +#ifdef STM32MP_NS_SYSRAM_BASE +CASSERT((STM32MP_NS_SYSRAM_BASE >= STM32MP_SEC_SYSRAM_BASE) && + ((STM32MP_NS_SYSRAM_BASE + STM32MP_NS_SYSRAM_SIZE) == + (STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE)), + assert_non_secure_sysram_fits_at_end_of_sysram); + +CASSERT((STM32MP_NS_SYSRAM_BASE & (PAGE_SIZE_4KB - U(1))) == 0U, + assert_non_secure_sysram_base_is_4kbyte_aligned); + +#define TZMA1_SECURE_RANGE \ + (((STM32MP_NS_SYSRAM_BASE - STM32MP_SYSRAM_BASE) >> FOUR_KB_SHIFT) - 1U) +#else #define TZMA1_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE +#endif /* STM32MP_NS_SYSRAM_BASE */ #define TZMA0_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE static void stm32mp1_etzpc_early_setup(void) diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 0a12b6e57..4fae2d70c 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -56,6 +56,15 @@ #define STM32MP_SYSRAM_BASE U(0x2FFC0000) #define STM32MP_SYSRAM_SIZE U(0x00040000) +#define STM32MP_NS_SYSRAM_SIZE PAGE_SIZE +#define STM32MP_NS_SYSRAM_BASE (STM32MP_SYSRAM_BASE + \ + STM32MP_SYSRAM_SIZE - \ + STM32MP_NS_SYSRAM_SIZE) + +#define STM32MP_SEC_SYSRAM_BASE STM32MP_SYSRAM_BASE +#define STM32MP_SEC_SYSRAM_SIZE (STM32MP_SYSRAM_SIZE - \ + STM32MP_NS_SYSRAM_SIZE) + /* DDR configuration */ #define STM32MP_DDR_BASE U(0xC0000000) #define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */ @@ -81,18 +90,18 @@ enum ddr_type { /* 256 Octets reserved for header */ #define STM32MP_HEADER_SIZE U(0x00000100) -#define STM32MP_BINARY_BASE (STM32MP_SYSRAM_BASE + \ +#define STM32MP_BINARY_BASE (STM32MP_SEC_SYSRAM_BASE + \ STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE) -#define STM32MP_BINARY_SIZE (STM32MP_SYSRAM_SIZE - \ +#define STM32MP_BINARY_SIZE (STM32MP_SEC_SYSRAM_SIZE - \ (STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE)) #ifdef AARCH32_SP_OPTEE #define STM32MP_BL32_SIZE U(0) -#define STM32MP_OPTEE_BASE STM32MP_SYSRAM_BASE +#define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE #define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \ STM32MP_OPTEE_BASE) @@ -104,8 +113,8 @@ enum ddr_type { #endif #endif -#define STM32MP_BL32_BASE (STM32MP_SYSRAM_BASE + \ - STM32MP_SYSRAM_SIZE - \ +#define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ + STM32MP_SEC_SYSRAM_SIZE - \ STM32MP_BL32_SIZE) #ifdef AARCH32_SP_OPTEE diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 779228d4a..fd60db282 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -30,12 +30,29 @@ BOARD_ID_REVISION_SHIFT) #define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK) -#define MAP_SRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ +#if defined(IMAGE_BL2) +#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ STM32MP_SYSRAM_SIZE, \ MT_MEMORY | \ MT_RW | \ MT_SECURE | \ MT_EXECUTE_NEVER) +#elif defined(IMAGE_BL32) +#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \ + STM32MP_SEC_SYSRAM_SIZE, \ + MT_MEMORY | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) + +/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */ +#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \ + STM32MP_NS_SYSRAM_SIZE, \ + MT_DEVICE | \ + MT_RW | \ + MT_NS | \ + MT_EXECUTE_NEVER) +#endif #define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \ STM32MP1_DEVICE1_SIZE, \ @@ -53,7 +70,7 @@ #if defined(IMAGE_BL2) static const mmap_region_t stm32mp1_mmap[] = { - MAP_SRAM, + MAP_SEC_SYSRAM, MAP_DEVICE1, MAP_DEVICE2, {0} @@ -61,7 +78,8 @@ static const mmap_region_t stm32mp1_mmap[] = { #endif #if defined(IMAGE_BL32) static const mmap_region_t stm32mp1_mmap[] = { - MAP_SRAM, + MAP_SEC_SYSRAM, + MAP_NS_SYSRAM, MAP_DEVICE1, MAP_DEVICE2, {0} diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index a818037cb..4c2b58df2 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -350,6 +350,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, spmd_spm_core_context_t *ctx = spmd_get_context(); bool secure_origin; int32_t ret; + uint32_t input_version; /* Determine which security state this SMC originated from */ secure_origin = is_caller_secure(flags); @@ -375,15 +376,24 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, break; /* not reached */ case FFA_VERSION: + input_version = (uint32_t)(0xFFFFFFFF & x1); /* - * TODO: This is an optimization that the version information - * provided by the SPM Core manifest is returned by the SPM - * dispatcher. It might be a better idea to simply forward this - * call to the SPM Core and wash our hands completely. + * If caller is secure and SPMC was initialized, + * return FFA_VERSION of SPMD. + * If caller is non secure and SPMC was initialized, + * return SPMC's version. + * Sanity check to "input_version". */ - ret = MAKE_FFA_VERSION(spmc_attrs.major_version, - spmc_attrs.minor_version); - SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_TARGET_INFO_MBZ, ret, + if ((input_version & FFA_VERSION_BIT31_MASK) || + (ctx->state == SPMC_STATE_RESET)) { + ret = FFA_ERROR_NOT_SUPPORTED; + } else if (!secure_origin) { + ret = MAKE_FFA_VERSION(spmc_attrs.major_version, spmc_attrs.minor_version); + } else { + ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR, FFA_VERSION_MINOR); + } + + SMC_RET8(handle, ret, FFA_TARGET_INFO_MBZ, FFA_TARGET_INFO_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ); break; /* not reached */ diff --git a/tools/cert_create/include/dualroot/cot.h b/tools/cert_create/include/dualroot/cot.h index 47e371fe1..1d959d465 100644 --- a/tools/cert_create/include/dualroot/cot.h +++ b/tools/cert_create/include/dualroot/cot.h @@ -32,6 +32,7 @@ enum { TRUSTED_BOOT_FW_HASH_EXT, TRUSTED_BOOT_FW_CONFIG_HASH_EXT, HW_CONFIG_HASH_EXT, + FW_CONFIG_HASH_EXT, TRUSTED_WORLD_PK_EXT, SCP_FW_CONTENT_CERT_PK_EXT, SCP_FW_HASH_EXT, diff --git a/tools/cert_create/include/tbbr/tbb_ext.h b/tools/cert_create/include/tbbr/tbb_ext.h index 7ac97a513..692b2d4d3 100644 --- a/tools/cert_create/include/tbbr/tbb_ext.h +++ b/tools/cert_create/include/tbbr/tbb_ext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,6 +15,7 @@ enum { TRUSTED_BOOT_FW_HASH_EXT, TRUSTED_BOOT_FW_CONFIG_HASH_EXT, HW_CONFIG_HASH_EXT, + FW_CONFIG_HASH_EXT, TRUSTED_WORLD_PK_EXT, NON_TRUSTED_WORLD_PK_EXT, SCP_FW_CONTENT_CERT_PK_EXT, diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c index 29658281c..a12ea21ff 100644 --- a/tools/cert_create/src/dualroot/cot.c +++ b/tools/cert_create/src/dualroot/cot.c @@ -30,9 +30,10 @@ static cert_t cot_certs[] = { TRUSTED_FW_NVCOUNTER_EXT, TRUSTED_BOOT_FW_HASH_EXT, TRUSTED_BOOT_FW_CONFIG_HASH_EXT, - HW_CONFIG_HASH_EXT + HW_CONFIG_HASH_EXT, + FW_CONFIG_HASH_EXT }, - .num_ext = 4 + .num_ext = 5 }, [TRUSTED_KEY_CERT] = { @@ -239,6 +240,17 @@ static ext_t cot_ext[] = { .optional = 1 }, + [FW_CONFIG_HASH_EXT] = { + .oid = FW_CONFIG_HASH_OID, + .opt = "fw-config", + .help_msg = "Firmware Config file", + .sn = "FirmwareConfigHash", + .ln = "Firmware Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [TRUSTED_WORLD_PK_EXT] = { .oid = TRUSTED_WORLD_PK_OID, .sn = "TrustedWorldPublicKey", diff --git a/tools/cert_create/src/tbbr/tbb_cert.c b/tools/cert_create/src/tbbr/tbb_cert.c index b614e2e49..f4fe63dc3 100644 --- a/tools/cert_create/src/tbbr/tbb_cert.c +++ b/tools/cert_create/src/tbbr/tbb_cert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,9 +28,10 @@ static cert_t tbb_certs[] = { TRUSTED_FW_NVCOUNTER_EXT, TRUSTED_BOOT_FW_HASH_EXT, TRUSTED_BOOT_FW_CONFIG_HASH_EXT, - HW_CONFIG_HASH_EXT + HW_CONFIG_HASH_EXT, + FW_CONFIG_HASH_EXT }, - .num_ext = 4 + .num_ext = 5 }, [TRUSTED_KEY_CERT] = { .id = TRUSTED_KEY_CERT, diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c index 0068d3b4a..60bafb4be 100644 --- a/tools/cert_create/src/tbbr/tbb_ext.c +++ b/tools/cert_create/src/tbbr/tbb_ext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -69,6 +69,16 @@ static ext_t tbb_ext[] = { .type = EXT_TYPE_HASH, .optional = 1 }, + [FW_CONFIG_HASH_EXT] = { + .oid = FW_CONFIG_HASH_OID, + .opt = "fw-config", + .help_msg = "Firmware Config file", + .sn = "FirmwareConfigHash", + .ln = "Firmware Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, [TRUSTED_WORLD_PK_EXT] = { .oid = TRUSTED_WORLD_PK_OID, .sn = "TrustedWorldPublicKey", diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c index 1c5ef5f59..bf721c1fa 100644 --- a/tools/fiptool/tbbr_config.c +++ b/tools/fiptool/tbbr_config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -69,6 +69,11 @@ toc_entry_t toc_entries[] = { }, /* Dynamic Configs */ { + .name = "FW_CONFIG", + .uuid = UUID_FW_CONFIG, + .cmdline_name = "fw-config" + }, + { .name = "HW_CONFIG", .uuid = UUID_HW_CONFIG, .cmdline_name = "hw-config" |