diff options
115 files changed, 3593 insertions, 1363 deletions
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index d9d7f84fdd..802dafcd87 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -64,6 +64,14 @@ Amlogic Meson S905X2 (G12A) platform port :F: drivers/amlogic/g12a :F: plat/amlogic/g12a/ +Amlogic Meson A113D (AXG) platform port +----------------------------------------- +:M: Carlo Caione <ccaione@baylibre.com> +:G: `carlocaione`_ +:F: docs/plat/meson-axg.rst +:F: drivers/amlogic/axg +:F: plat/amlogic/axg/ + Armv7-A architecture port ------------------------- :M: Etienne Carriere <etienne.carriere@linaro.org> diff --git a/docs/components/exception-handling.rst b/docs/components/exception-handling.rst index 3f386854f9..e330a62a46 100644 --- a/docs/components/exception-handling.rst +++ b/docs/components/exception-handling.rst @@ -467,7 +467,7 @@ SMCs from Non-secure world are synchronous exceptions, and are mechanisms for Non-secure world to request Secure services. They're broadly classified as *Fast* or *Yielding* (see `SMCCC`__). -.. __: `http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html` +.. __: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html - *Fast* SMCs are atomic from the caller's point of view. I.e., they return to the caller only when the Secure world has finished serving the request. @@ -621,6 +621,6 @@ The |EHF| has the following limitations: -------------- -*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.* .. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst index 2025243164..f5c8bc98c8 100644 --- a/docs/design/trusted-board-boot-build.rst +++ b/docs/design/trusted-board-boot-build.rst @@ -33,7 +33,7 @@ images with support for these features: - ``GENERATE_COT=1`` In the case of Arm platforms, the location of the ROTPK hash must also be - specified at build time. Two locations are currently supported (see + specified at build time. The following locations are currently supported (see ``ARM_ROTPK_LOCATION`` build option): - ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted @@ -41,17 +41,16 @@ images with support for these features: registers are read-only. On FVP Base and Cortex models, the registers are read-only, but the value can be specified using the command line option ``bp.trusted_key_storage.public_key`` when launching the model. - On both Juno and FVP models, the default value corresponds to an - ECDSA-SECP256R1 public key hash, whose private part is not currently - available. + On Juno board, the default value corresponds to an ECDSA-SECP256R1 public + key hash, whose private part is not currently available. - - ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded - in the Arm platform port. The private/public RSA key pair may be - found in ``plat/arm/board/common/rotpk``. + - ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in + plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin. Enforce generation + of the new hash if ROT_KEY is specified. - - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded - in the Arm platform port. The private/public ECDSA key pair may be - found in ``plat/arm/board/common/rotpk``. + - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in + plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin. Enforce generation + of the new hash if ROT_KEY is specified. Example of command line using RSA development keys: @@ -108,7 +107,7 @@ images with support for these features: -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* .. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git .. _mbed TLS Security Center: https://tls.mbed.org/security diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index fa83b4f54a..031836a81b 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -310,8 +310,8 @@ Common build options EL1 for handling. The default value of this option is ``0``, which means the Group 0 interrupts are assumed to be handled by Secure EL1. - .. __: `platform-interrupt-controller-API.rst` - .. __: `interrupt-framework-design.rst` + .. __: platform-interrupt-controller-API.rst + .. __: interrupt-framework-design.rst - ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to @@ -468,7 +468,8 @@ Common build options entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0. - ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this + file that contains the ROT private key in PEM format and enforces public key + hash generation. If ``SAVE_KEYS=1``, this file name will be used to save the key. - ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the @@ -657,4 +658,4 @@ commands can be used: -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index bb14717523..e8357b385e 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -2763,6 +2763,19 @@ build system. to ``no``. If any of the options ``EL3_PAYLOAD_BASE`` or ``PRELOADED_BL33_BASE`` are used, this flag will be set to ``no`` automatically. +Platform include paths +---------------------- + +Platforms are allowed to add more include paths to be passed to the compiler. +The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in +particular for the file ``platform_def.h``. + +Example: + +.. code:: c + + PLAT_INCLUDES += -Iinclude/plat/myplat/include + C Library --------- @@ -2844,7 +2857,7 @@ amount of open resources per driver. -------------- -*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index d24ad231d8..9622de65df 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -57,8 +57,7 @@ Arm Platform Build Options ``ARM_ROTPK_LOCATION`` are: - ``regs`` : return the ROTPK hash stored in the Trusted root-key storage - registers. The private key corresponding to this ROTPK hash is not - currently available. + registers. - ``devel_rsa`` : return a development public key hash embedded in the BL1 and BL2 binaries. This hash has been obtained from the RSA public key ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use @@ -70,6 +69,12 @@ Arm Platform Build Options use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as ``ROT_KEY`` when creating the certificates. +- ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``. Specifies the + location of the ROTPK hash. Not expected to be a build option. This defaults to + ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified algorithm. + Providing ``ROT_KEY`` enforces generation of the hash from the ``ROT_KEY`` and + overwrites the default hash file. + - ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options: - ``tsram`` : Trusted SRAM (default option when TBB is not enabled) @@ -109,6 +114,11 @@ Arm CSS Platform-Specific Build Options management operations and for SCP RAM Firmware transfer. If this option is set to 1, then SCMI/SDS drivers will be used. Default is 0. + - ``CSS_SGI_CHIP_COUNT``: Configures the number of chips on a SGI/RD platform + which supports multi-chip operation. If ``CSS_SGI_CHIP_COUNT`` is set to any + valid value greater than 1, the platform code performs required configuration + to support multi-chip operation. + -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/plat/meson-axg.rst b/docs/plat/meson-axg.rst new file mode 100644 index 0000000000..1e4b2c207b --- /dev/null +++ b/docs/plat/meson-axg.rst @@ -0,0 +1,27 @@ +Amlogic Meson A113D (AXG) +=========================== + +The Amlogic Meson A113D is a SoC with a quad core Arm Cortex-A53 running at +~1.2GHz. It also contains a Cortex-M3 used as SCP. + +This port is a minimal implementation of BL31 capable of booting mainline U-Boot +and Linux: + +- SCPI support. +- Basic PSCI support (CPU_ON, CPU_OFF, SYSTEM_RESET, SYSTEM_OFF). Note that CPU0 + can't be turned off, so there is a workaround to hide this from the caller. +- GICv2 driver set up. +- Basic SIP services (read efuse data, enable/disable JTAG). + +In order to build it: + +.. code:: shell + + CROSS_COMPILE=aarch64-none-elf- make DEBUG=1 PLAT=axg [SPD=opteed] + [AML_USE_ATOS=1 when using ATOS as BL32] + +This port has been tested on a A113D board. After building it, follow the +instructions in the `U-Boot repository`_, replacing the mentioned **bl31.img** +by the one built from this port. + +.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/s400/README diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst index cb8b892455..f7d53a97eb 100644 --- a/docs/process/coding-guidelines.rst +++ b/docs/process/coding-guidelines.rst @@ -1,232 +1,126 @@ -Coding Style & Guidelines -========================= +Coding Guidelines +================= -The following sections contain TF coding guidelines. They are continually -evolving and should not be considered "set in stone". Feel free to question them -and provide feedback. +This document provides some additional guidelines to consider when writing +|TF-A| code. These are not intended to be strictly-enforced rules like the +contents of the :ref:`Coding Style`. -Some of the guidelines may also apply to other codebases. +Automatic Editor Configuration +------------------------------ -.. note:: - The existing TF codebase does not necessarily comply with all the - below guidelines but the intent is for it to do so eventually. - -Checkpatch overrides --------------------- - -Some checkpatch warnings in the TF codebase are deliberately ignored. These -include: - -- ``**WARNING: line over 80 characters**``: Although the codebase should - generally conform to the 80 character limit this is overly restrictive in some - cases. - -- ``**WARNING: Use of volatile is usually wrong``: see - `Why the “volatile” type class should not be used`_ . Although this document - contains some very useful information, there are several legitimate uses of - the volatile keyword within the TF codebase. - -Headers and inclusion ---------------------- - -Header guards -^^^^^^^^^^^^^ - -For a header file called "some_driver.h" the style used by the Trusted Firmware -is: - -.. code:: c - - #ifndef SOME_DRIVER_H - #define SOME_DRIVER_H - - <header content> - - #endif /* SOME_DRIVER_H */ +Many of the rules given below (such as indentation size, use of tabs, and +newlines) can be set automatically using the `EditorConfig`_ configuration file +in the root of the repository: ``.editorconfig``. With a supported editor, the +rules set out in this file can be automatically applied when you are editing +files in the |TF-A| repository. -Include statement ordering -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -All header files that are included by a source file must use the following, -grouped ordering. This is to improve readability (by making it easier to quickly -read through the list of headers) and maintainability. - -#. *System* includes: Header files from the standard *C* library, such as - ``stddef.h`` and ``string.h``. - -#. *Project* includes: Header files under the ``include/`` directory within TF - are *project* includes. - -#. *Platform* includes: Header files relating to a single, specific platform, - and which are located under the ``plat/<platform_name>`` directory within TF, - are *platform* includes. - -Within each group, ``#include`` statements must be in alphabetical order, -taking both the file and directory names into account. - -Groups must be separated by a single blank line for clarity. - -The example below illustrates the ordering rules using some contrived header -file names; this type of name reuse should be otherwise avoided. - -.. code:: c - - #include <string.h> - - #include <a_dir/example/a_header.h> - #include <a_dir/example/b_header.h> - #include <a_dir/test/a_header.h> - #include <b_dir/example/a_header.h> - - #include "./a_header.h" - -Include statement variants -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Two variants of the ``#include`` directive are acceptable in the TF codebase. -Correct use of the two styles improves readability by suggesting the location -of the included header and reducing ambiguity in cases where generic and -platform-specific headers share a name. - -For header files that are in the same directory as the source file that is -including them, use the ``"..."`` variant. - -For header files that are **not** in the same directory as the source file that -is including them, use the ``<...>`` variant. - -Example (bl1_fwu.c): - -.. code:: c +Several editors include built-in support for EditorConfig files, and many others +support its functionality through plugins. - #include <assert.h> - #include <errno.h> - #include <string.h> +Use of the EditorConfig file is suggested but is not required. - #include "bl1_private.h" -Platform include paths -^^^^^^^^^^^^^^^^^^^^^^ - -Platforms are allowed to add more include paths to be passed to the compiler. -The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in -particular for the file ``platform_def.h``. - -Example: - -.. code:: c - - PLAT_INCLUDES += -Iinclude/plat/myplat/include +Automatic Compliance Checking +----------------------------- -Types and typedefs ------------------- +To assist with coding style compliance, the project Makefile contains two +targets which both utilise the `checkpatch.pl` script that ships with the Linux +source tree. The project also defines certain *checkpatch* options in the +``.checkpatch.conf`` file in the top-level directory. -Use of built-in *C* and *libc* data types -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. note:: + Checkpatch errors will gate upstream merging of pull requests. + Checkpatch warnings will not gate merging but should be reviewed and fixed if + possible. -The TF codebase should be kept as portable as possible, especially since both -64-bit and 32-bit platforms are supported. To help with this, the following data -type usage guidelines should be followed: +To check the entire source tree, you must first download copies of +``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available +in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH`` +environment variable to point to ``checkpatch.pl`` (with the other 2 files in +the same directory) and build the `checkcodebase` target: -- Where possible, use the built-in *C* data types for variable storage (for - example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99* - types. Most code is typically only concerned with the minimum size of the - data stored, which the built-in *C* types guarantee. - -- Avoid using the exact-size standard *C99* types in general (for example, - ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the - compiler from making optimizations. There are legitimate uses for them, - for example to represent data of a known structure. When using them in struct - definitions, consider how padding in the struct will work across architectures. - For example, extra padding may be introduced in AArch32 systems if a struct - member crosses a 32-bit boundary. +.. code:: shell -- Use ``int`` as the default integer type - it's likely to be the fastest on all - systems. Also this can be assumed to be 32-bit as a consequence of the - `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call - Standard for the Arm 64-bit Architecture`_ . + make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase -- Avoid use of ``short`` as this may end up being slower than ``int`` in some - systems. If a variable must be exactly 16-bit, use ``int16_t`` or - ``uint16_t``. +To just check the style on the files that differ between your local branch and +the remote master, use: -- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given - that `int` is 32-bit on Arm platforms, there is no use for it. For integers of - at least 64-bit, use ``long long``. +.. code:: shell -- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data. + make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch -- Use ``unsigned`` for integers that can never be negative (counts, - indices, sizes, etc). TF intends to comply with MISRA "essential type" coding - rules (10.X), where signed and unsigned types are considered different - essential types. Choosing the correct type will aid this. MISRA static - analysers will pick up any implicit signed/unsigned conversions that may lead - to unexpected behaviour. +If you wish to check your patch against something other than the remote master, +set the ``BASE_COMMIT`` variable to your desired branch. By default, +``BASE_COMMIT`` is set to ``origin/master``. -- For pointer types: +Ignored Checkpatch Warnings +^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - If an argument in a function declaration is pointing to a known type then - simply use a pointer to that type (for example: ``struct my_struct *``). +Some checkpatch warnings in the TF codebase are deliberately ignored. These +include: - - If a variable (including an argument in a function declaration) is pointing - to a general, memory-mapped address, an array of pointers or another - structure that is likely to require pointer arithmetic then use - ``uintptr_t``. This will reduce the amount of casting required in the code. - Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it - may work but is less portable. +- ``**WARNING: line over 80 characters**``: Although the codebase should + generally conform to the 80 character limit this is overly restrictive in some + cases. - - For other pointer arguments in a function declaration, use ``void *``. This - includes pointers to types that are abstracted away from the known API and - pointers to arbitrary data. This allows the calling function to pass a - pointer argument to the function without any explicit casting (the cast to - ``void *`` is implicit). The function implementation can then do the - appropriate casting to a specific type. +- ``**WARNING: Use of volatile is usually wrong``: see + `Why the “volatile” type class should not be used`_ . Although this document + contains some very useful information, there are several legimate uses of the + volatile keyword within the TF codebase. - - Use ``ptrdiff_t`` to compare the difference between 2 pointers. +Performance considerations +-------------------------- -- Use ``size_t`` when storing the ``sizeof()`` something. +Avoid printf and use logging macros +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that - can also return an error code; the signed type allows for a negative return - code in case of error. This practice should be used sparingly. +``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``) +which wrap ``tf_log`` and which allow the logging call to be compiled-out +depending on the ``make`` command. Use these macros to avoid print statements +being compiled unconditionally into the binary. -- Use ``u_register_t`` when it's important to store the contents of a register - in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a - standard *C99* type but is widely available in libc implementations, - including the FreeBSD version included with the TF codebase. Where possible, - cast the variable to a more appropriate type before interpreting the data. For - example, the following struct in ``ep_info.h`` could use this type to minimize - the storage required for the set of registers: +Each logging macro has a numerical log level: .. code:: c - typedef struct aapcs64_params { - u_register_t arg0; - u_register_t arg1; - u_register_t arg2; - u_register_t arg3; - u_register_t arg4; - u_register_t arg5; - u_register_t arg6; - u_register_t arg7; - } aapcs64_params_t; + #define LOG_LEVEL_NONE 0 + #define LOG_LEVEL_ERROR 10 + #define LOG_LEVEL_NOTICE 20 + #define LOG_LEVEL_WARNING 30 + #define LOG_LEVEL_INFO 40 + #define LOG_LEVEL_VERBOSE 50 -If some code wants to operate on ``arg0`` and knows that it represents a 32-bit -unsigned integer on all systems, cast it to ``unsigned int``. +By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will +be compiled into debug builds and all statements with a log level +``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be +overridden from the command line or by the platform makefile (although it may be +necessary to clean the build directory first). For example, to enable +``VERBOSE`` logging on FVP: -These guidelines should be updated if additional types are needed. +``make PLAT=fvp LOG_LEVEL=50 all`` -Avoid anonymous typedefs of structs/enums in headers -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use const data where possible +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -For example, the following definition: +For example, the following code: .. code:: c - typedef struct { + struct my_struct { int arg1; int arg2; - } my_struct_t; + }; + void init(struct my_struct *ptr); + + void main(void) + { + struct my_struct x; + x.arg1 = 1; + x.arg2 = 2; + init(&x); + } is better written as: @@ -237,31 +131,18 @@ is better written as: int arg2; }; -This allows function declarations in other header files that depend on the -struct/enum to forward declare the struct/enum instead of including the -entire header: - -.. code:: c - - #include <my_struct.h> - void my_func(my_struct_t *arg); - -instead of: - -.. code:: c - - struct my_struct; - void my_func(struct my_struct *arg); - -Some TF definitions use both a struct/enum name **and** a typedef name. This -is discouraged for new definitions as it makes it difficult for TF to comply -with MISRA rule 8.3, which states that "All declarations of an object or -function shall use the same names and type qualifiers". + void init(const struct my_struct *ptr); -The Linux coding standards also discourage new typedefs and checkpatch emits -a warning for this. + void main(void) + { + const struct my_struct x = { 1, 2 }; + init(&x); + } -Existing typedefs will be retained for compatibility. +This allows the linker to put the data in a read-only data section instead of a +writeable data section, which may result in a smaller and faster binary. Note +that this may require dependent functions (``init()`` in the above example) to +have ``const`` arguments, assuming they don't need to modify the data. Libc functions that are banned or to be used with caution --------------------------------------------------------- @@ -410,14 +291,14 @@ error. This situation should be handled in one of the following ways: then emit an ``ERROR`` message and call the platform-specific function ``plat_error_handler()``. -Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler`` -and ``plat_error_handler`` in the same way (for example, by waiting for a secure -watchdog to time-out or by invoking an interface on the platform's power -controller to reset the platform). However, ``plat_error_handler`` may take -additional action for some errors (for example, it may set a flag so the -platform resets into a different mode). Also, ``plat_panic_handler()`` may -implement additional debug functionality (for example, invoking a hardware -breakpoint). +Cases 1 and 2 are subtly different. A platform may implement +``plat_panic_handler`` and ``plat_error_handler`` in the same way (for example, +by waiting for a secure watchdog to time-out or by invoking an interface on the +platform's power controller to reset the platform). However, +``plat_error_handler`` may take additional action for some errors (for example, +it may set a flag so the platform resets into a different mode). Also, +``plat_panic_handler()`` may implement additional debug functionality (for +example, invoking a hardware breakpoint). Examples of unexpected unrecoverable errors: @@ -456,131 +337,115 @@ Examples: - Secure world is waiting for a hardware response that is critical for continued operation. -Security considerations ------------------------ - -Part of the security of a platform is handling errors correctly, as described in -the previous section. There are several other security considerations covered in -this section. - -Do not leak secrets to the normal world -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The secure world **must not** leak secrets to the normal world, for example in -response to an SMC. - -Handling Denial of Service attacks -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use of built-in *C* and *libc* data types +----------------------------------------- -The secure world **should never** crash or become unusable due to receiving too -many normal world requests (a *Denial of Service* or *DoS* attack). It should -have a mechanism for throttling or ignoring normal world requests. +The |TF-A| codebase should be kept as portable as possible, especially since +both 64-bit and 32-bit platforms are supported. To help with this, the following +data type usage guidelines should be followed: -Performance considerations --------------------------- +- Where possible, use the built-in *C* data types for variable storage (for + example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99* + types. Most code is typically only concerned with the minimum size of the + data stored, which the built-in *C* types guarantee. -Avoid printf and use logging macros -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Avoid using the exact-size standard *C99* types in general (for example, + ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the + compiler from making optimizations. There are legitimate uses for them, + for example to represent data of a known structure. When using them in struct + definitions, consider how padding in the struct will work across architectures. + For example, extra padding may be introduced in |AArch32| systems if a struct + member crosses a 32-bit boundary. -``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``) -which wrap ``tf_log`` and which allow the logging call to be compiled-out -depending on the ``make`` command. Use these macros to avoid print statements -being compiled unconditionally into the binary. +- Use ``int`` as the default integer type - it's likely to be the fastest on all + systems. Also this can be assumed to be 32-bit as a consequence of the + `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call + Standard for the Arm 64-bit Architecture`_ . -Each logging macro has a numerical log level: +- Avoid use of ``short`` as this may end up being slower than ``int`` in some + systems. If a variable must be exactly 16-bit, use ``int16_t`` or + ``uint16_t``. -.. code:: c +- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given + that `int` is 32-bit on Arm platforms, there is no use for it. For integers of + at least 64-bit, use ``long long``. - #define LOG_LEVEL_NONE 0 - #define LOG_LEVEL_ERROR 10 - #define LOG_LEVEL_NOTICE 20 - #define LOG_LEVEL_WARNING 30 - #define LOG_LEVEL_INFO 40 - #define LOG_LEVEL_VERBOSE 50 +- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data. +- Use ``unsigned`` for integers that can never be negative (counts, + indices, sizes, etc). TF intends to comply with MISRA "essential type" coding + rules (10.X), where signed and unsigned types are considered different + essential types. Choosing the correct type will aid this. MISRA static + analysers will pick up any implicit signed/unsigned conversions that may lead + to unexpected behaviour. -By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will -be compiled into debug builds and all statements with a log level -``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be -overridden from the command line or by the platform makefile (although it may be -necessary to clean the build directory first). For example, to enable -``VERBOSE`` logging on FVP: +- For pointer types: -``make PLAT=fvp LOG_LEVEL=50 all`` + - If an argument in a function declaration is pointing to a known type then + simply use a pointer to that type (for example: ``struct my_struct *``). -Use const data where possible -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + - If a variable (including an argument in a function declaration) is pointing + to a general, memory-mapped address, an array of pointers or another + structure that is likely to require pointer arithmetic then use + ``uintptr_t``. This will reduce the amount of casting required in the code. + Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it + may work but is less portable. -For example, the following code: + - For other pointer arguments in a function declaration, use ``void *``. This + includes pointers to types that are abstracted away from the known API and + pointers to arbitrary data. This allows the calling function to pass a + pointer argument to the function without any explicit casting (the cast to + ``void *`` is implicit). The function implementation can then do the + appropriate casting to a specific type. -.. code:: c + - Avoid pointer arithmetic generally (as this violates MISRA C 2012 rule + 18.4) and especially on void pointers (as this is only supported via + language extensions and is considered non-standard). In TF-A, setting the + ``W`` build flag to ``W=3`` enables the *-Wpointer-arith* compiler flag and + this will emit warnings where pointer arithmetic is used. - struct my_struct { - int arg1; - int arg2; - }; + - Use ``ptrdiff_t`` to compare the difference between 2 pointers. - void init(struct my_struct *ptr); +- Use ``size_t`` when storing the ``sizeof()`` something. - void main(void) - { - struct my_struct x; - x.arg1 = 1; - x.arg2 = 2; - init(&x); - } +- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that + can also return an error code; the signed type allows for a negative return + code in case of error. This practice should be used sparingly. -is better written as: +- Use ``u_register_t`` when it's important to store the contents of a register + in its native size (32-bit in |AArch32| and 64-bit in |AArch64|). This is not a + standard *C99* type but is widely available in libc implementations, + including the FreeBSD version included with the TF codebase. Where possible, + cast the variable to a more appropriate type before interpreting the data. For + example, the following struct in ``ep_info.h`` could use this type to minimize + the storage required for the set of registers: .. code:: c - struct my_struct { - int arg1; - int arg2; - }; - - void init(const struct my_struct *ptr); - - void main(void) - { - const struct my_struct x = { 1, 2 }; - init(&x); - } - -This allows the linker to put the data in a read-only data section instead of a -writeable data section, which may result in a smaller and faster binary. Note -that this may require dependent functions (``init()`` in the above example) to -have ``const`` arguments, assuming they don't need to modify the data. - -Library and driver code ------------------------ - -TF library code (under ``lib/`` and ``include/lib``) is any code that provides a -reusable interface to other code, potentially even to code outside of TF. - -In some systems drivers must conform to a specific driver framework to provide -services to the rest of the system. TF has no driver framework and the -distinction between a driver and library is somewhat subjective. + typedef struct aapcs64_params { + u_register_t arg0; + u_register_t arg1; + u_register_t arg2; + u_register_t arg3; + u_register_t arg4; + u_register_t arg5; + u_register_t arg6; + u_register_t arg7; + } aapcs64_params_t; -A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that -interfaces with hardware via a memory mapped interface. +If some code wants to operate on ``arg0`` and knows that it represents a 32-bit +unsigned integer on all systems, cast it to ``unsigned int``. -Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``) -provide a general purpose API to that specific hardware. Other drivers (for -example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``) -provide a specific hardware implementation of a more abstract library API. In -the latter case there may potentially be multiple drivers for the same hardware -device. +These guidelines should be updated if additional types are needed. -Neither libraries nor drivers should depend on platform-specific code. If they -require platform-specific data (for example, a base address) to operate then -they should provide an initialization function that takes the platform-specific -data as arguments. +-------------- -TF common code (under ``common/`` and ``include/common/``) is code that is re-used -by other generic (non-platform-specific) TF code. It is effectively internal -library code. +*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* +.. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ +.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/ +.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/ +.. _`EditorConfig`: http://editorconfig.org/ .. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html -.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf -.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf +.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx +.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods diff --git a/docs/process/coding-style.rst b/docs/process/coding-style.rst new file mode 100644 index 0000000000..fd1984d303 --- /dev/null +++ b/docs/process/coding-style.rst @@ -0,0 +1,468 @@ +Coding Style +============ + +The following sections outline the |TF-A| coding style for *C* code. The style +is based on the `Linux kernel coding style`_, with a few modifications. + +The style should not be considered *set in stone*. Feel free to provide feedback +and suggestions. + +.. note:: + You will almost certainly find code in the |TF-A| repository that does not + follow the style. The intent is for all code to do so eventually. + +File Encoding +------------- + +The source code must use the **UTF-8** character encoding. Comments and +documentation may use non-ASCII characters when required (e.g. Greek letters +used for units) but code itself is still limited to ASCII characters. + +Newlines must be in **Unix** style, which means that only the Line Feed (``LF``) +character is used to break a line and reset to the first column. + +Language +-------- + +The primary language for comments and naming must be International English. In +cases where there is a conflict between the American English and British English +spellings of a word, the American English spelling is used. + +Exceptions are made when referring directly to something that does not use +international style, such as the name of a company. In these cases the existing +name should be used as-is. + +C Language Standard +------------------- + +The C language mode used for TF-A is *GNU99*. This is the "GNU dialect of ISO +C99", which implies the *ISO C99* standard with GNU extensions. + +Both GCC and Clang compiler toolchains have support for *GNU99* mode, though +Clang does lack support for a small number of GNU extensions. These +missing extensions are rarely used, however, and should not pose a problem. + +MISRA Compliance +---------------- + +TF-A attempts to comply with the `MISRA C:2012 Guidelines`_. Coverity +Static Analysis is used to regularly generate a report of current MISRA defects +and to prevent the addition of new ones. + +It is not possible for the project to follow all MISRA guidelines. We maintain +`a spreadsheet`_ that lists all rules and directives and whether we aim to +comply with them or not. A rationale is given for each deviation. + +.. note:: + Enforcing a rule does not mean that the codebase is free of defects + of that rule, only that they would ideally be removed. + +.. note:: + Third-party libraries are not considered in our MISRA analysis and we do not + intend to modify them to make them MISRA compliant. + +Indentation +----------- + +Use **tabs** for indentation. The use of spaces for indentation is forbidden +except in the case where a term is being indented to a boundary that cannot be +achieved using tabs alone. + +Tab spacing should be set to **8 characters**. + +Trailing whitespace is not allowed and must be trimmed. + +Spacing +------- + +Single spacing should be used around most operators, including: + +- Arithmetic operators (``+``, ``-``, ``/``, ``*``) +- Assignment operators (``=``, ``+=``, etc) +- Boolean operators (``&&``, ``||``) +- Comparison operators (``<``, ``>``, ``==``, etc) + +A space should also be used to separate parentheses and braces when they are not +already separated by a newline, such as for the ``if`` statement in the +following example: + +.. code:: c + + int function_foo(bool bar) + { + if (bar) { + function_baz(); + } + } + +Note that there is no space between the name of a function and the following +parentheses. + +Control statements (``if``, ``for``, ``switch``, ``while``, etc) must be +separated from the following open paranthesis by a single space. The previous +example illustrates this for an ``if`` statement. + +Line Length +----------- + +Line length *should* be at most **80 characters**. This limit does not include +non-printing characters such as the line feed. + +This rule is a *should*, not a must, and it is acceptable to exceed the limit +**slightly** where the readability of the code would otherwise be significantly +reduced. Use your judgement in these cases. + +Blank Lines +----------- + +Functions are usually separated by a single blank line. In certain cases it is +acceptable to use additional blank lines for clarity, if required. + +The file must end with a single newline character. Many editors have the option +to insert this automatically and to trim multiple blank lines at the end of the +file. + +Braces +------ + +Opening Brace Placement +^^^^^^^^^^^^^^^^^^^^^^^ + +Braces follow the **Kernighan and Ritchie (K&R)** style, where the opening brace +is **not** placed on a new line. + +Example for a ``while`` loop: + +.. code:: c + + while (condition) { + foo(); + bar(); + } + +This style applies to all blocks except for functions which, following the Linux +style, **do** place the opening brace on a new line. + +Example for a function: + +.. code:: c + + int my_function(void) + { + int a; + + a = 1; + return a; + } + +Conditional Statement Bodies +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Where conditional statements (such as ``if``, ``for``, ``while`` and ``do``) are +used, braces must be placed around the statements that form the body of the +conditional. This is the case regardless of the number of statements in the +body. + +.. note:: + This is a notable departure from the Linux coding style that has been + adopted to follow MISRA guidelines more closely and to help prevent errors. + +For example, use the following style: + +.. code:: c + + if (condition) { + foo++; + } + +instead of omitting the optional braces around a single statement: + +.. code:: c + + /* This is violating MISRA C 2012: Rule 15.6 */ + if (condition) + foo++; + +The reason for this is to prevent accidental changes to control flow when +modifying the body of the conditional. For example, at a quick glance it is easy +to think that the value of ``bar`` is only incremented if ``condition`` +evaluates to ``true`` but this is not the case - ``bar`` will always be +incremented regardless of the condition evaluation. If the developer forgets to +add braces around the conditional body when adding the ``bar++;`` statement then +the program execution will not proceed as intended. + +.. code:: c + + /* This is violating MISRA C 2012: Rule 15.6 */ + if (condition) + foo++; + bar++; + +Naming +------ + +Functions +^^^^^^^^^ + +Use lowercase for function names, separating multiple words with an underscore +character (``_``). This is sometimes referred to as *Snake Case*. An example is +given below: + +.. code:: c + + void bl2_arch_setup(void) + { + ... + } + +Local Variables and Parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Local variables and function parameters use the same format as function names: +lowercase with underscore separation between multiple words. An example is +given below: + +.. code:: c + + static void set_scr_el3_from_rm(uint32_t type, + uint32_t interrupt_type_flags, + uint32_t security_state) + { + uint32_t flag, bit_pos; + + ... + + } + +Preprocessor Macros +^^^^^^^^^^^^^^^^^^^ + +Identifiers that are defined using preprocessor macros are written in all +uppercase text. + +.. code:: c + + #define BUFFER_SIZE_BYTES 64 + +Function Attributes +------------------- + +Place any function attributes after the function type and before the function +name. + +.. code:: c + + void __init plat_arm_interconnect_init(void); + +Alignment +--------- + +Alignment should be performed primarily with tabs, adding spaces if required to +achieve a granularity that is smaller than the tab size. For example, with a tab +size of eight columns it would be necessary to use one tab character and two +spaces to indent text by ten columns. + +Switch Statement Alignment +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When using ``switch`` statements, align each ``case`` statement with the +``switch`` so that they are in the same column. + +.. code:: c + + switch (condition) { + case A: + foo(); + case B: + bar(); + default: + baz(); + } + +Pointer Alignment +^^^^^^^^^^^^^^^^^ + +The reference and dereference operators (ampersand and *pointer star*) must be +aligned with the name of the object on which they are operating, as opposed to +the type of the object. + +.. code:: c + + uint8_t *foo; + + foo = &bar; + + +Comments +-------- + +The general rule for comments is that the double-slash style of comment (``//``) +is not allowed. Examples of the allowed comment formats are shown below: + +.. code:: c + + /* + * This example illustrates the first allowed style for multi-line comments. + * + * Blank lines within multi-lines are allowed when they add clarity or when + * they separate multiple contexts. + * + */ + +.. code:: c + + /************************************************************************** + * This is the second allowed style for multi-line comments. + * + * In this style, the first and last lines use asterisks that run the full + * width of the comment at its widest point. + * + * This style can be used for additional emphasis. + * + *************************************************************************/ + +.. code:: c + + /* Single line comments can use this format */ + +.. code:: c + + /*************************************************************************** + * This alternative single-line comment style can also be used for emphasis. + **************************************************************************/ + +Headers and inclusion +--------------------- + +Header guards +^^^^^^^^^^^^^ + +For a header file called "some_driver.h" the style used by |TF-A| is: + +.. code:: c + + #ifndef SOME_DRIVER_H + #define SOME_DRIVER_H + + <header content> + + #endif /* SOME_DRIVER_H */ + +Include statement ordering +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +All header files that are included by a source file must use the following, +grouped ordering. This is to improve readability (by making it easier to quickly +read through the list of headers) and maintainability. + +#. *System* includes: Header files from the standard *C* library, such as + ``stddef.h`` and ``string.h``. + +#. *Project* includes: Header files under the ``include/`` directory within + |TF-A| are *project* includes. + +#. *Platform* includes: Header files relating to a single, specific platform, + and which are located under the ``plat/<platform_name>`` directory within + |TF-A|, are *platform* includes. + +Within each group, ``#include`` statements must be in alphabetical order, +taking both the file and directory names into account. + +Groups must be separated by a single blank line for clarity. + +The example below illustrates the ordering rules using some contrived header +file names; this type of name reuse should be otherwise avoided. + +.. code:: c + + #include <string.h> + + #include <a_dir/example/a_header.h> + #include <a_dir/example/b_header.h> + #include <a_dir/test/a_header.h> + #include <b_dir/example/a_header.h> + + #include "a_header.h" + +Include statement variants +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Two variants of the ``#include`` directive are acceptable in the |TF-A| +codebase. Correct use of the two styles improves readability by suggesting the +location of the included header and reducing ambiguity in cases where generic +and platform-specific headers share a name. + +For header files that are in the same directory as the source file that is +including them, use the ``"..."`` variant. + +For header files that are **not** in the same directory as the source file that +is including them, use the ``<...>`` variant. + +Example (bl1_fwu.c): + +.. code:: c + + #include <assert.h> + #include <errno.h> + #include <string.h> + + #include "bl1_private.h" + +Typedefs +-------- + +Avoid anonymous typedefs of structs/enums in headers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For example, the following definition: + +.. code:: c + + typedef struct { + int arg1; + int arg2; + } my_struct_t; + + +is better written as: + +.. code:: c + + struct my_struct { + int arg1; + int arg2; + }; + +This allows function declarations in other header files that depend on the +struct/enum to forward declare the struct/enum instead of including the +entire header: + +.. code:: c + + struct my_struct; + void my_func(struct my_struct *arg); + +instead of: + +.. code:: c + + #include <my_struct.h> + void my_func(my_struct_t *arg); + +Some TF definitions use both a struct/enum name **and** a typedef name. This +is discouraged for new definitions as it makes it difficult for TF to comply +with MISRA rule 8.3, which states that "All declarations of an object or +function shall use the same names and type qualifiers". + +The Linux coding standards also discourage new typedefs and checkpatch emits +a warning for this. + +Existing typedefs will be retained for compatibility. + +-------------- + +*Copyright (c) 2020, Arm Limited. All rights reserved.* + +.. _`Linux kernel coding style`: https://www.kernel.org/doc/html/latest/process/coding-style.html +.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx +.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index f569fcbe7a..68c494baad 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -23,7 +23,7 @@ Making Changes - Make commits of logical units. See these general `Git guidelines`_ for contributing to a project. -- Follow the :ref:`Coding Style & Guidelines`. +- Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`. - Use the checkpatch.pl script provided with the Linux source tree. A Makefile target is provided for convenience. @@ -128,7 +128,7 @@ Binary Components -------------- -*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* .. _developer.trustedfirmware.org: https://developer.trustedfirmware.org .. _issue: https://developer.trustedfirmware.org/project/board/1/ diff --git a/docs/process/index.rst b/docs/process/index.rst index 9c12de82fc..1cb5354056 100644 --- a/docs/process/index.rst +++ b/docs/process/index.rst @@ -8,6 +8,7 @@ Processes & Policies security platform-compatibility-policy + coding-style coding-guidelines contributing faq diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst index a18a792038..43a5721251 100644 --- a/docs/process/security-hardening.rst +++ b/docs/process/security-hardening.rst @@ -1,10 +1,30 @@ -Security hardening -================== +Secure Development Guidelines +============================= This page contains guidance on what to check for additional security measures, including build options that can be modified to improve security or catch issues early in development. +Security considerations +----------------------- + +Part of the security of a platform is handling errors correctly, as described in +the previous section. There are several other security considerations covered in +this section. + +Do not leak secrets to the normal world +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The secure world **must not** leak secrets to the normal world, for example in +response to an SMC. + +Handling Denial of Service attacks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The secure world **should never** crash or become unusable due to receiving too +many normal world requests (a *Denial of Service* or *DoS* attack). It should +have a mechanism for throttling or ignoring normal world requests. + Build options ------------- @@ -53,4 +73,4 @@ Several build options can be used to check for security issues. Refer to the -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c index 885874272f..c51f3b1d78 100644 --- a/drivers/arm/css/mhu/css_mhu_doorbell.c +++ b/drivers/arm/css/mhu/css_mhu_doorbell.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,11 +20,13 @@ void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info) void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) { + uintptr_t mhuv2_base = plat_info->db_reg_addr & MHU_V2_FRAME_BASE_MASK; + /* wake receiver */ - MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR); + MHU_V2_ACCESS_REQUEST(mhuv2_base); /* wait for receiver to acknowledge its ready */ - while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0) + while (MHU_V2_IS_ACCESS_READY(mhuv2_base) == 0) ; MHU_RING_DOORBELL(plat_info->db_reg_addr, @@ -32,7 +34,7 @@ void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) plat_info->db_preserve_mask); /* clear the access request for the receiver */ - MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR); + MHU_V2_CLEAR_REQUEST(mhuv2_base); return; } diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c index b945cda788..097d2eb2b6 100644 --- a/drivers/arm/css/scp/css_pm_scmi.c +++ b/drivers/arm/css/scp/css_pm_scmi.c @@ -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 */ @@ -63,17 +63,45 @@ typedef enum { } scmi_power_state_t; /* - * The global handle for invoking the SCMI driver APIs after the driver + * The global handles for invoking the SCMI driver APIs after the driver * has been initialized. */ -static void *scmi_handle; +static void *scmi_handles[PLAT_ARM_SCMI_CHANNEL_COUNT]; -/* The SCMI channel global object */ -static scmi_channel_t channel; +/* The global SCMI channels array */ +static scmi_channel_t scmi_channels[PLAT_ARM_SCMI_CHANNEL_COUNT]; +/* + * Channel ID for the default SCMI channel. + * The default channel is used to issue SYSTEM level SCMI requests and is + * initialized to the channel which has the boot cpu as its resource. + */ +static uint32_t default_scmi_channel_id; + +/* + * TODO: Allow use of channel specific lock instead of using a single lock for + * all the channels. + */ ARM_SCMI_INSTANTIATE_LOCK; /* + * Function to obtain the SCMI Domain ID and SCMI Channel number from the linear + * core position. The SCMI Channel number is encoded in the upper 16 bits and + * the Domain ID is encoded in the lower 16 bits in each entry of the mapping + * array exported by the platform. + */ +static void css_scp_core_pos_to_scmi_channel(unsigned int core_pos, + unsigned int *scmi_domain_id, unsigned int *scmi_channel_id) +{ + unsigned int composite_id; + + composite_id = plat_css_core_pos_to_scmi_dmn_id_map[core_pos]; + + *scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id); + *scmi_domain_id = GET_SCMI_DOMAIN_ID(composite_id); +} + +/* * Helper function to suspend a CPU power domain and its parent power domains * if applicable. */ @@ -87,10 +115,10 @@ void css_scp_suspend(const struct psci_power_state *target_state) /* Check if power down at system power domain level is requested */ if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) { - /* Issue SCMI command for SYSTEM_SUSPEND */ - ret = scmi_sys_pwr_state_set(scmi_handle, - SCMI_SYS_PWR_FORCEFUL_REQ, - SCMI_SYS_PWR_SUSPEND); + /* Issue SCMI command for SYSTEM_SUSPEND on all SCMI channels */ + ret = scmi_sys_pwr_state_set( + scmi_handles[default_scmi_channel_id], + SCMI_SYS_PWR_FORCEFUL_REQ, SCMI_SYS_PWR_SUSPEND); if (ret != SCMI_E_SUCCESS) { ERROR("SCMI system power domain suspend return 0x%x unexpected\n", ret); @@ -99,7 +127,7 @@ void css_scp_suspend(const struct psci_power_state *target_state) return; } #if !HW_ASSISTED_COHERENCY - unsigned int lvl; + unsigned int lvl, channel_id, domain_id; uint32_t scmi_pwr_state = 0; /* * If we reach here, then assert that power down at system power domain @@ -127,9 +155,10 @@ void css_scp_suspend(const struct psci_power_state *target_state) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); + css_scp_core_pos_to_scmi_channel(plat_my_core_pos(), + &domain_id, &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", @@ -145,7 +174,7 @@ void css_scp_suspend(const struct psci_power_state *target_state) */ void css_scp_off(const struct psci_power_state *target_state) { - unsigned int lvl = 0; + unsigned int lvl = 0, channel_id, domain_id; int ret; uint32_t scmi_pwr_state = 0; @@ -168,10 +197,10 @@ void css_scp_off(const struct psci_power_state *target_state) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); - + css_scp_core_pos_to_scmi_channel(plat_my_core_pos(), + &domain_id, &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", ret); @@ -185,8 +214,8 @@ void css_scp_off(const struct psci_power_state *target_state) */ void css_scp_on(u_register_t mpidr) { - unsigned int lvl = 0; - int core_pos, ret; + unsigned int lvl = 0, channel_id, core_pos, domain_id; + int ret; uint32_t scmi_pwr_state = 0; for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) @@ -196,13 +225,12 @@ void css_scp_on(u_register_t mpidr) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); core_pos = plat_core_pos_by_mpidr(mpidr); - assert((core_pos >= 0) && - (((unsigned int)core_pos) < PLATFORM_CORE_COUNT)); - - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[core_pos], - scmi_pwr_state); + assert(core_pos >= 0 && (core_pos < PLATFORM_CORE_COUNT)); + css_scp_core_pos_to_scmi_channel(core_pos, &domain_id, + &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", ret); @@ -216,8 +244,9 @@ void css_scp_on(u_register_t mpidr) */ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) { - int ret, cpu_idx; + int ret; uint32_t scmi_pwr_state = 0, lvl_state; + unsigned int channel_id, cpu_idx, domain_id; /* We don't support get power state at the system power domain level */ if ((power_level > PLAT_MAX_PWR_LVL) || @@ -230,9 +259,9 @@ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) cpu_idx = plat_core_pos_by_mpidr(mpidr); assert(cpu_idx > -1); - ret = scmi_pwr_state_get(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx], - &scmi_pwr_state); + css_scp_core_pos_to_scmi_channel(cpu_idx, &domain_id, &channel_id); + ret = scmi_pwr_state_get(scmi_handles[channel_id], + domain_id, &scmi_pwr_state); if (ret != SCMI_E_SUCCESS) { WARN("SCMI get power state command return 0x%x unexpected\n", @@ -271,7 +300,7 @@ void __dead2 css_scp_system_off(int state) * Issue SCMI command. First issue a graceful * request and if that fails force the request. */ - ret = scmi_sys_pwr_state_set(scmi_handle, + ret = scmi_sys_pwr_state_set(scmi_handles[default_scmi_channel_id], SCMI_SYS_PWR_FORCEFUL_REQ, state); @@ -325,17 +354,28 @@ static int scmi_ap_core_init(scmi_channel_t *ch) void __init plat_arm_pwrc_setup(void) { - channel.info = plat_css_get_scmi_info(); - channel.lock = ARM_SCMI_LOCK_GET_INSTANCE; - scmi_handle = scmi_init(&channel); - if (scmi_handle == NULL) { - ERROR("SCMI Initialization failed\n"); - panic(); - } - if (scmi_ap_core_init(&channel) < 0) { - ERROR("SCMI AP core protocol initialization failed\n"); - panic(); + unsigned int composite_id, idx; + + for (idx = 0; idx < PLAT_ARM_SCMI_CHANNEL_COUNT; idx++) { + INFO("Initializing driver on Channel %d\n", idx); + + scmi_channels[idx].info = plat_css_get_scmi_info(idx); + scmi_channels[idx].lock = ARM_SCMI_LOCK_GET_INSTANCE; + scmi_handles[idx] = scmi_init(&scmi_channels[idx]); + + if (scmi_handles[idx] == NULL) { + ERROR("SCMI Initialization failed on channel %d\n", idx); + panic(); + } + + if (scmi_ap_core_init(&scmi_channels[idx]) < 0) { + ERROR("SCMI AP core protocol initialization failed\n"); + panic(); + } } + + composite_id = plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()]; + default_scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id); } /****************************************************************************** @@ -347,6 +387,7 @@ const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops) { uint32_t msg_attr; int ret; + void *scmi_handle = scmi_handles[default_scmi_channel_id]; assert(scmi_handle); @@ -411,14 +452,17 @@ int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie) #if PROGRAMMABLE_RESET_ADDRESS void plat_arm_program_trusted_mailbox(uintptr_t address) { - int ret; + int ret, i; - assert(scmi_handle); - ret = scmi_ap_core_set_reset_addr(scmi_handle, address, - SCMI_AP_CORE_LOCK_ATTR); - if (ret != SCMI_E_SUCCESS) { - ERROR("CSS: Failed to program reset address: %d\n", ret); - panic(); + for (i = 0; i < PLAT_ARM_SCMI_CHANNEL_COUNT; i++) { + assert(scmi_handles[i]); + + ret = scmi_ap_core_set_reset_addr(scmi_handles[i], address, + SCMI_AP_CORE_LOCK_ATTR); + if (ret != SCMI_E_SUCCESS) { + ERROR("CSS: Failed to program reset address: %d\n", ret); + panic(); + } } } #endif diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h index e6f7a1bd1b..88302fd7bb 100644 --- a/include/drivers/arm/css/css_mhu_doorbell.h +++ b/include/drivers/arm/css/css_mhu_doorbell.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 */ @@ -11,13 +11,13 @@ #include <lib/mmio.h> -/* MHUv2 Base Address */ -#define MHUV2_BASE_ADDR PLAT_MHUV2_BASE +/* MHUv2 Frame Base Mask */ +#define MHU_V2_FRAME_BASE_MASK UL(~0xFFF) /* MHUv2 Control Registers Offsets */ -#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80 -#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 -#define MHU_V2_ACCESS_READY_OFFSET 0xF8C +#define MHU_V2_MSG_NO_CAP_OFFSET UL(0xF80) +#define MHU_V2_ACCESS_REQ_OFFSET UL(0xF88) +#define MHU_V2_ACCESS_READY_OFFSET UL(0xF8C) #define SENDER_REG_STAT(_channel) (0x20 * (_channel)) #define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC) diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h index 1f8dc6ccea..e8a2863a9f 100644 --- a/include/drivers/arm/css/scmi.h +++ b/include/drivers/arm/css/scmi.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 */ @@ -162,7 +162,7 @@ int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr); int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr); /* API to get the platform specific SCMI channel information. */ -scmi_channel_plat_info_t *plat_css_get_scmi_info(void); +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id); /* API to override default PSCI callbacks for platforms that support SCMI. */ const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops); diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 5bd53f3b53..c825bf4dca 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -18,6 +18,12 @@ * Definitions common to all ARM standard platforms *****************************************************************************/ +/* + * Root of trust key hash lengths + */ +#define ARM_ROTPK_HEADER_LEN 19 +#define ARM_ROTPK_HASH_LEN 32 + /* Special value used to verify platform parameters from BL2 to BL31 */ #define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 02feec7086..32dc9f93df 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -142,6 +142,11 @@ void arm_setup_romlib(void); #define STATE_SW_E_PARAM (-2) #define STATE_SW_E_DENIED (-3) +/* plat_get_rotpk_info() flags */ +#define ARM_ROTPK_REGS_ID 1 +#define ARM_ROTPK_DEVEL_RSA_ID 2 +#define ARM_ROTPK_DEVEL_ECDSA_ID 3 + /* IO storage utility functions */ void arm_io_setup(void); @@ -255,9 +260,17 @@ int plat_arm_bl1_fwu_needed(void); __dead2 void plat_arm_error_handler(int err); /* - * Optional function in ARM standard platforms + * Optional functions in ARM standard platforms */ void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames); +int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, + unsigned int *flags); #if ARM_PLAT_MT unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr); diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index 2adf11d66e..7b61484455 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -29,6 +29,10 @@ #define SID_REG_BASE 0x2a4a0000 #define SID_SYSTEM_ID_OFFSET 0x40 #define SID_SYSTEM_CFG_OFFSET 0x70 +#define SID_NODE_ID_OFFSET 0x60 +#define SID_CHIP_ID_MASK 0xFF +#define SID_MULTI_CHIP_MODE_MASK 0x100 +#define SID_MULTI_CHIP_MODE_SHIFT 8 /* The slave_bootsecure controls access to GPU, DMC and CS. */ #define CSS_NIC400_SLAVE_BOOTSECURE 8 diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h index 93f86162e9..e5357f50be 100644 --- a/include/plat/arm/css/common/css_pm.h +++ b/include/plat/arm/css/common/css_pm.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 */ @@ -44,4 +44,15 @@ int css_node_hw_state(u_register_t mpidr, unsigned int power_level); */ extern const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[]; +#define SCMI_DOMAIN_ID_MASK U(0xFFFF) +#define SCMI_CHANNEL_ID_MASK U(0xFFFF) +#define SCMI_CHANNEL_ID_SHIFT U(16) + +#define SET_SCMI_CHANNEL_ID(n) (((n) & SCMI_CHANNEL_ID_MASK) << \ + SCMI_CHANNEL_ID_SHIFT) +#define SET_SCMI_DOMAIN_ID(n) ((n) & SCMI_DOMAIN_ID_MASK) +#define GET_SCMI_CHANNEL_ID(n) (((n) >> SCMI_CHANNEL_ID_SHIFT) & \ + SCMI_CHANNEL_ID_MASK) +#define GET_SCMI_DOMAIN_ID(n) ((n) & SCMI_DOMAIN_ID_MASK) + #endif /* CSS_PM_H */ diff --git a/include/tools_share/sptool.h b/include/tools_share/sptool.h index 67a2cf093c..53668e09c7 100644 --- a/include/tools_share/sptool.h +++ b/include/tools_share/sptool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,21 +9,17 @@ #include <stdint.h> -/* Header for a secure partition package. There is one per package. */ -struct sp_pkg_header { - uint64_t version; - uint64_t number_of_sp; -}; +/* 4 Byte magic name "SPKG" */ +#define SECURE_PARTITION_MAGIC 0x474B5053 -/* - * Entry descriptor in a secure partition package. Each entry comprises a - * secure partition and its resource description. - */ -struct sp_pkg_entry { - uint64_t sp_offset; - uint64_t sp_size; - uint64_t rd_offset; - uint64_t rd_size; +/* Header for a secure partition package. */ +struct sp_pkg_header { + uint32_t magic; + uint32_t version; + uint32_t pm_offset; + uint32_t pm_size; + uint32_t img_offset; + uint32_t img_size; }; #endif /* SPTOOL_H */ diff --git a/plat/amlogic/axg/axg_bl31_setup.c b/plat/amlogic/axg/axg_bl31_setup.c new file mode 100644 index 0000000000..8cc9d69f41 --- /dev/null +++ b/plat/amlogic/axg/axg_bl31_setup.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/bl_common.h> +#include <common/interrupt_props.h> +#include <drivers/arm/gicv2.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_mmu_helpers.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +#include "aml_private.h" + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; +static image_info_t bl30_image_info; +static image_info_t bl301_image_info; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? + &bl33_image_ep_info : &bl32_image_ep_info; + + /* None of the images can have 0x0 as the entrypoint. */ + if (next_image_info->pc != 0U) + return next_image_info; + + return NULL; +} + +/******************************************************************************* + * Perform any BL31 early platform setup. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before + * they are lost (potentially). This needs to be done before the MMU is + * initialized so that the memory layout can be used while creating page + * tables. BL2 has flushed this information to memory, so we are guaranteed + * to pick up good data. + ******************************************************************************/ +struct axg_bl31_param { + param_header_t h; + image_info_t *bl31_image_info; + entry_point_info_t *bl32_ep_info; + image_info_t *bl32_image_info; + entry_point_info_t *bl33_ep_info; + image_info_t *bl33_image_info; + image_info_t *scp_image_info[]; +}; + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + struct axg_bl31_param *from_bl2; + + /* Initialize the console to provide early debug support */ + aml_console_init(); + + from_bl2 = (struct axg_bl31_param *)arg0; + + /* Check params passed from BL2 are not NULL. */ + assert(from_bl2 != NULL); + assert(from_bl2->h.type == PARAM_BL31); + assert(from_bl2->h.version >= VERSION_1); + + /* + * Copy BL32 and BL33 entry point information. It is stored in Secure + * RAM, in BL2's address space. + */ + bl32_image_ep_info = *from_bl2->bl32_ep_info; + bl33_image_ep_info = *from_bl2->bl33_ep_info; + +#if AML_USE_ATOS + /* + * BL2 is unconditionally setting 0 (OPTEE_AARCH64) in arg0 even when + * the BL32 image is 32bit (OPTEE_AARCH32). This is causing the boot to + * hang when ATOS (32bit Amlogic BL32 binary-only TEE OS) is used. + * + * Hardcode to OPTEE_AARCH32 / MODE_RW_32. + */ + bl32_image_ep_info.args.arg0 = MODE_RW_32; +#endif + + if (bl33_image_ep_info.pc == 0U) { + ERROR("BL31: BL33 entrypoint not obtained from BL2\n"); + panic(); + } + + bl30_image_info = *from_bl2->scp_image_info[0]; + bl301_image_info = *from_bl2->scp_image_info[1]; +} + +void bl31_plat_arch_setup(void) +{ + aml_setup_page_tables(); + + enable_mmu_el3(0); +} + +static inline bool axg_scp_ready(void) +{ + return AML_AO_RTI_SCP_IS_READY(mmio_read_32(AML_AO_RTI_SCP_STAT)); +} + +static inline void axg_scp_boot(void) +{ + aml_scpi_upload_scp_fw(bl30_image_info.image_base, + bl30_image_info.image_size, 0); + aml_scpi_upload_scp_fw(bl301_image_info.image_base, + bl301_image_info.image_size, 1); + while (!axg_scp_ready()) + ; +} + +/******************************************************************************* + * GICv2 driver setup information + ******************************************************************************/ +static const interrupt_prop_t axg_interrupt_props[] = { + INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL) +}; + +static const gicv2_driver_data_t axg_gic_data = { + .gicd_base = AML_GICD_BASE, + .gicc_base = AML_GICC_BASE, + .interrupt_props = axg_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(axg_interrupt_props) +}; + +void bl31_platform_setup(void) +{ + aml_mhu_secure_init(); + + gicv2_driver_init(&axg_gic_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + + axg_scp_boot(); +} diff --git a/plat/amlogic/axg/axg_common.c b/plat/amlogic/axg/axg_common.c new file mode 100644 index 0000000000..870daf4591 --- /dev/null +++ b/plat/amlogic/axg/axg_common.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <bl31/interrupt_mgmt.h> +#include <common/bl_common.h> +#include <common/ep_info.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_tables_v2.h> +#include <platform_def.h> +#include <stdint.h> + +/******************************************************************************* + * Platform memory map regions + ******************************************************************************/ +#define MAP_NSDRAM0 MAP_REGION_FLAT(AML_NSDRAM0_BASE, \ + AML_NSDRAM0_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_NS_SHARE_MEM MAP_REGION_FLAT(AML_NS_SHARE_MEM_BASE, \ + AML_NS_SHARE_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_SEC_SHARE_MEM MAP_REGION_FLAT(AML_SEC_SHARE_MEM_BASE, \ + AML_SEC_SHARE_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE, \ + AML_SEC_DEVICE0_SIZE, \ + MT_DEVICE | MT_RW) + +#define MAP_GIC_DEVICE MAP_REGION_FLAT(AML_GIC_DEVICE_BASE, \ + AML_GIC_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE, \ + AML_SEC_DEVICE1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE, \ + AML_SEC_DEVICE2_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_TZRAM MAP_REGION_FLAT(AML_TZRAM_BASE, \ + AML_TZRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +static const mmap_region_t axg_mmap[] = { + MAP_NSDRAM0, + MAP_NS_SHARE_MEM, + MAP_SEC_SHARE_MEM, + MAP_SEC_DEVICE0, + MAP_GIC_DEVICE, + MAP_SEC_DEVICE1, + MAP_SEC_DEVICE2, + MAP_TZRAM, + {0} +}; + +/******************************************************************************* + * Per-image regions + ******************************************************************************/ +#define MAP_BL31 MAP_REGION_FLAT(BL31_BASE, \ + BL31_END - BL31_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_BL_CODE MAP_REGION_FLAT(BL_CODE_BASE, \ + BL_CODE_END - BL_CODE_BASE, \ + MT_CODE | MT_SECURE) + +#define MAP_BL_RO_DATA MAP_REGION_FLAT(BL_RO_DATA_BASE, \ + BL_RO_DATA_END - BL_RO_DATA_BASE, \ + MT_RO_DATA | MT_SECURE) + +#define MAP_BL_COHERENT MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, \ + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/******************************************************************************* + * Function that sets up the translation tables. + ******************************************************************************/ +void aml_setup_page_tables(void) +{ +#if IMAGE_BL31 + const mmap_region_t axg_bl_mmap[] = { + MAP_BL31, + MAP_BL_CODE, + MAP_BL_RO_DATA, +#if USE_COHERENT_MEM + MAP_BL_COHERENT, +#endif + {0} + }; +#endif + + mmap_add(axg_bl_mmap); + + mmap_add(axg_mmap); + + init_xlat_tables(); +} + +/******************************************************************************* + * Function that returns the system counter frequency + ******************************************************************************/ +unsigned int plat_get_syscnt_freq2(void) +{ + mmio_clrbits_32(AML_SYS_CPU_CFG7, PLAT_SYS_CPU_CFG7); + mmio_clrbits_32(AML_AO_TIMESTAMP_CNTL, PLAT_AO_TIMESTAMP_CNTL); + + return AML_OSC24M_CLK_IN_HZ; +} diff --git a/plat/amlogic/axg/axg_def.h b/plat/amlogic/axg/axg_def.h new file mode 100644 index 0000000000..d90681afdb --- /dev/null +++ b/plat/amlogic/axg/axg_def.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AXG_DEF_H +#define AXG_DEF_H + +#include <lib/utils_def.h> + +/******************************************************************************* + * System oscillator + ******************************************************************************/ +#define AML_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */ + +/******************************************************************************* + * Memory regions + ******************************************************************************/ +#define AML_NS_SHARE_MEM_BASE UL(0x05000000) +#define AML_NS_SHARE_MEM_SIZE UL(0x00100000) + +#define AML_SEC_SHARE_MEM_BASE UL(0x05200000) +#define AML_SEC_SHARE_MEM_SIZE UL(0x00100000) + +#define AML_GIC_DEVICE_BASE UL(0xFFC00000) +#define AML_GIC_DEVICE_SIZE UL(0x00008000) + +#define AML_NSDRAM0_BASE UL(0x01000000) +#define AML_NSDRAM0_SIZE UL(0x0F000000) + +#define BL31_BASE UL(0x05100000) +#define BL31_SIZE UL(0x00100000) +#define BL31_LIMIT (BL31_BASE + BL31_SIZE) + +/* Shared memory used for SMC services */ +#define AML_SHARE_MEM_INPUT_BASE UL(0x050FE000) +#define AML_SHARE_MEM_OUTPUT_BASE UL(0x050FF000) + +#define AML_SEC_DEVICE0_BASE UL(0xFFD00000) +#define AML_SEC_DEVICE0_SIZE UL(0x00026000) + +#define AML_SEC_DEVICE1_BASE UL(0xFF800000) +#define AML_SEC_DEVICE1_SIZE UL(0x0000A000) + +#define AML_SEC_DEVICE2_BASE UL(0xFF620000) +#define AML_SEC_DEVICE2_SIZE UL(0x00028000) + +#define AML_TZRAM_BASE UL(0xFFFC0000) +#define AML_TZRAM_SIZE UL(0x00020000) + +/* Mailboxes */ +#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xFFFD3800) +#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xFFFD3A00) +#define AML_PSCI_MAILBOX_BASE UL(0xFFFD3F00) + +/******************************************************************************* + * GIC-400 and interrupt handling related constants + ******************************************************************************/ +#define AML_GICD_BASE UL(0xFFC01000) +#define AML_GICC_BASE UL(0xFFC02000) + +#define IRQ_SEC_PHY_TIMER 29 + +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 +#define IRQ_SEC_SGI_8 16 + +/******************************************************************************* + * UART definitions + ******************************************************************************/ +#define AML_UART0_AO_BASE UL(0xFF803000) +#define AML_UART0_AO_CLK_IN_HZ AML_OSC24M_CLK_IN_HZ +#define AML_UART_BAUDRATE U(115200) + +/******************************************************************************* + * Memory-mapped I/O Registers + ******************************************************************************/ +#define AML_AO_TIMESTAMP_CNTL UL(0xFF8000B4) + +#define AML_SYS_CPU_CFG7 UL(0xFF634664) + +#define AML_AO_RTI_STATUS_REG3 UL(0xFF80001C) +#define AML_AO_RTI_SCP_STAT UL(0xFF80023C) +#define AML_AO_RTI_SCP_READY_OFF U(0x14) +#define AML_A0_RTI_SCP_READY_MASK U(3) +#define AML_AO_RTI_SCP_IS_READY(v) \ + ((((v) >> AML_AO_RTI_SCP_READY_OFF) & \ + AML_A0_RTI_SCP_READY_MASK) == AML_A0_RTI_SCP_READY_MASK) + +#define AML_HIU_MAILBOX_SET_0 UL(0xFF63C404) +#define AML_HIU_MAILBOX_STAT_0 UL(0xFF63C408) +#define AML_HIU_MAILBOX_CLR_0 UL(0xFF63C40C) +#define AML_HIU_MAILBOX_SET_3 UL(0xFF63C428) +#define AML_HIU_MAILBOX_STAT_3 UL(0xFF63C42C) +#define AML_HIU_MAILBOX_CLR_3 UL(0xFF63C430) + +#define AML_SHA_DMA_BASE UL(0xFF63E000) +#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08) +#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x28) + +/******************************************************************************* + * System Monitor Call IDs and arguments + ******************************************************************************/ +#define AML_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020) +#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021) + +#define AML_SM_EFUSE_READ U(0x82000030) +#define AML_SM_EFUSE_USER_MAX U(0x82000033) + +#define AML_SM_JTAG_ON U(0x82000040) +#define AML_SM_JTAG_OFF U(0x82000041) +#define AML_SM_GET_CHIP_ID U(0x82000044) + +#define AML_JTAG_STATE_ON U(0) +#define AML_JTAG_STATE_OFF U(1) + +#define AML_JTAG_M3_AO U(0) +#define AML_JTAG_M3_EE U(1) +#define AML_JTAG_A53_AO U(2) +#define AML_JTAG_A53_EE U(3) + +#endif /* AXG_DEF_H */ diff --git a/plat/amlogic/axg/axg_pm.c b/plat/amlogic/axg/axg_pm.c new file mode 100644 index 0000000000..e67f263a4b --- /dev/null +++ b/plat/amlogic/axg/axg_pm.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <assert.h> +#include <common/debug.h> +#include <drivers/arm/gicv2.h> +#include <drivers/console.h> +#include <errno.h> +#include <lib/mmio.h> +#include <lib/psci/psci.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +#include "aml_private.h" + +#define SCPI_POWER_ON 0 +#define SCPI_POWER_RETENTION 1 +#define SCPI_POWER_OFF 3 + +#define SCPI_SYSTEM_SHUTDOWN 0 +#define SCPI_SYSTEM_REBOOT 1 + +static uintptr_t axg_sec_entrypoint; + +static void axg_pm_set_reset_addr(u_register_t mpidr, uint64_t value) +{ + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4); + + mmio_write_64(cpu_mailbox_addr, value); +} + +static void axg_pm_reset(u_register_t mpidr, uint32_t value) +{ + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4) + 8; + + mmio_write_32(cpu_mailbox_addr, value); +} + +static void __dead2 axg_system_reset(void) +{ + u_register_t mpidr = read_mpidr_el1(); + int ret; + + INFO("BL31: PSCI_SYSTEM_RESET\n"); + + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT); + if (ret != 0) { + ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret); + panic(); + } + + axg_pm_reset(mpidr, 0); + + wfi(); + + ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n"); + panic(); +} + +static void __dead2 axg_system_off(void) +{ + u_register_t mpidr = read_mpidr_el1(); + int ret; + + INFO("BL31: PSCI_SYSTEM_OFF\n"); + + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN); + if (ret != 0) { + ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret); + panic(); + } + + axg_pm_set_reset_addr(mpidr, 0); + axg_pm_reset(mpidr, 0); + + dmbsy(); + wfi(); + + ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n"); + panic(); +} + +static int32_t axg_pwr_domain_on(u_register_t mpidr) +{ + axg_pm_set_reset_addr(mpidr, axg_sec_entrypoint); + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON); + dmbsy(); + sev(); + + return PSCI_E_SUCCESS; +} + +static void axg_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + + axg_pm_set_reset_addr(read_mpidr_el1(), 0); +} + +static void axg_pwr_domain_off(const psci_power_state_t *target_state) +{ + u_register_t mpidr = read_mpidr_el1(); + uint32_t system_state = SCPI_POWER_ON; + uint32_t cluster_state = SCPI_POWER_ON; + + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + axg_pm_reset(mpidr, -1); + + gicv2_cpuif_disable(); + + if (target_state->pwr_domain_state[MPIDR_AFFLVL2] == + PLAT_LOCAL_STATE_OFF) + system_state = SCPI_POWER_OFF; + + if (target_state->pwr_domain_state[MPIDR_AFFLVL1] == + PLAT_LOCAL_STATE_OFF) + cluster_state = SCPI_POWER_OFF; + + + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_OFF, cluster_state, + system_state); +} + +static void __dead2 axg_pwr_domain_pwr_down_wfi(const psci_power_state_t + *target_state) +{ + dsbsy(); + axg_pm_reset(read_mpidr_el1(), 0); + + for (;;) + wfi(); +} + +/******************************************************************************* + * Platform handlers and setup function. + ******************************************************************************/ +static const plat_psci_ops_t axg_ops = { + .pwr_domain_on = axg_pwr_domain_on, + .pwr_domain_on_finish = axg_pwr_domain_on_finish, + .pwr_domain_off = axg_pwr_domain_off, + .pwr_domain_pwr_down_wfi = axg_pwr_domain_pwr_down_wfi, + .system_off = axg_system_off, + .system_reset = axg_system_reset +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + axg_sec_entrypoint = sec_entrypoint; + *psci_ops = &axg_ops; + return 0; +} diff --git a/plat/amlogic/axg/include/platform_def.h b/plat/amlogic/axg/include/platform_def.h new file mode 100644 index 0000000000..a47cf7348e --- /dev/null +++ b/plat/amlogic/axg/include/platform_def.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <arch.h> +#include <lib/utils_def.h> + +#include "../axg_def.h" + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE UL(0x1000) + +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT + +#define AML_PRIMARY_CPU U(0) + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +#define PLAT_SYS_CPU_CFG7 (U(1) << 25) +#define PLAT_AO_TIMESTAMP_CNTL U(0x1ff) + +/* Local power state for power domains in Run state. */ +#define PLAT_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define PLAT_LOCAL_STATE_RET U(1) +/* Local power state for power-down. Valid for CPU and cluster power domains. */ +#define PLAT_LOCAL_STATE_OFF U(2) + +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define PLAT_LOCAL_PSTATE_WIDTH U(4) +#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1) + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_SHIFT U(6) +#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) + +/* Memory-related defines */ +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_MMAP_REGIONS 16 +#define MAX_XLAT_TABLES 8 + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk new file mode 100644 index 0000000000..3560b0cd18 --- /dev/null +++ b/plat/amlogic/axg/platform.mk @@ -0,0 +1,95 @@ +# +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/xlat_tables_v2/xlat_tables.mk + +AML_PLAT := plat/amlogic +AML_PLAT_SOC := ${AML_PLAT}/${PLAT} +AML_PLAT_COMMON := ${AML_PLAT}/common + +DOIMAGEPATH ?= tools/amlogic +DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage + +PLAT_INCLUDES := -Iinclude/drivers/amlogic/ \ + -I${AML_PLAT_SOC}/include \ + -I${AML_PLAT_COMMON}/include + +GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + plat/common/plat_psci_common.c \ + drivers/amlogic/console/aarch64/meson_console.S \ + ${AML_PLAT_SOC}/${PLAT}_bl31_setup.c \ + ${AML_PLAT_SOC}/${PLAT}_pm.c \ + ${AML_PLAT_SOC}/${PLAT}_common.c \ + ${AML_PLAT_COMMON}/aarch64/aml_helpers.S \ + ${AML_PLAT_COMMON}/aml_efuse.c \ + ${AML_PLAT_COMMON}/aml_mhu.c \ + ${AML_PLAT_COMMON}/aml_scpi.c \ + ${AML_PLAT_COMMON}/aml_sip_svc.c \ + ${AML_PLAT_COMMON}/aml_thermal.c \ + ${AML_PLAT_COMMON}/aml_topology.c \ + ${AML_PLAT_COMMON}/aml_console.c \ + drivers/amlogic/crypto/sha_dma.c \ + ${XLAT_TABLES_LIB_SRCS} \ + ${GIC_SOURCES} + +# Tune compiler for Cortex-A53 +ifeq ($(notdir $(CC)),armclang) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else ifneq ($(findstring clang,$(notdir $(CC))),) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else + TF_CFLAGS_aarch64 += -mtune=cortex-a53 +endif + +# Build config flags +# ------------------ + +# Enable all errata workarounds for Cortex-A53 +ERRATA_A53_855873 := 1 +ERRATA_A53_819472 := 1 +ERRATA_A53_824069 := 1 +ERRATA_A53_827319 := 1 + +WORKAROUND_CVE_2017_5715 := 0 + +# Have different sections for code and rodata +SEPARATE_CODE_AND_RODATA := 1 + +# Use Coherent memory +USE_COHERENT_MEM := 1 + +AML_USE_ATOS := 0 +$(eval $(call assert_boolean,AML_USE_ATOS)) +$(eval $(call add_define,AML_USE_ATOS)) + +# Verify build config +# ------------------- + +ifneq (${RESET_TO_BL31}, 0) + $(error Error: ${PLAT} needs RESET_TO_BL31=0) +endif + +ifeq (${ARCH},aarch32) + $(error Error: AArch32 not supported on ${PLAT}) +endif + +all: ${BUILD_PLAT}/bl31.img +distclean realclean clean: cleanimage + +cleanimage: + ${Q}${MAKE} -C ${DOIMAGEPATH} clean + +${DOIMAGETOOL}: + ${Q}${MAKE} -C ${DOIMAGEPATH} + +${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL} + ${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img + diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index c71e932a0f..3c19230bd6 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,130 +8,61 @@ #include <stdint.h> #include <string.h> +#include <common/debug.h> +#include <drivers/arm/cryptocell/cc_rotpk.h> +#include <drivers/delay_timer.h> #include <lib/cassert.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/common_def.h> #include <plat/common/platform.h> -#include <tools_share/tbbr_oid.h> #include <platform_def.h> +#include <tools_share/tbbr_oid.h> -/* SHA256 algorithm */ -#define SHA256_BYTES 32 - -/* ROTPK locations */ -#define ARM_ROTPK_REGS_ID 1 -#define ARM_ROTPK_DEVEL_RSA_ID 2 -#define ARM_ROTPK_DEVEL_ECDSA_ID 3 - -static const unsigned char rotpk_hash_hdr[] = \ - "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \ - "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; -static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1; -static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES]; -/* Use the cryptocell variants if Cryptocell is present */ #if !ARM_CRYPTOCELL_INTEG #if !ARM_ROTPK_LOCATION_ID #error "ARM_ROTPK_LOCATION_ID not defined" #endif +#endif /* Weak definition may be overridden in specific platform */ #pragma weak plat_get_nv_ctr #pragma weak plat_set_nv_ctr -#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) -static const unsigned char arm_devel_rotpk_hash[] = \ - "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \ - "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \ - "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \ - "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA"; -#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) -static const unsigned char arm_devel_rotpk_hash[] = \ - "\x2E\x40\xBF\x6E\xF9\x12\xBB\x98" \ - "\x31\x71\x09\x0E\x1E\x15\x3D\x0B" \ - "\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B" \ - "\xA0\xB0\x20\x86\x4E\x6C\x07\x17"; -#endif +extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[]; + +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; /* - * Return the ROTPK hash in the following ASN.1 structure in DER format: - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm AlgorithmIdentifier, - * digest OCTET STRING - * } + * Return the ROTPK hash stored in dedicated registers. */ -int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, +int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, unsigned int *flags) { uint8_t *dst; + uint32_t *src, tmp; + unsigned int words, i; assert(key_ptr != NULL); assert(key_len != NULL); assert(flags != NULL); /* Copy the DER header */ - memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); - dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len]; -#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \ - || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) - memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES); -#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) - uint32_t *src, tmp; - unsigned int words, i; + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + + words = ARM_ROTPK_HASH_LEN >> 2; - /* - * Append the hash from Trusted Root-Key Storage registers. The hash has - * not been written linearly into the registers, so we have to do a bit - * of byte swapping: - * - * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C - * +---------------------------------------------------------------+ - * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | - * +---------------------------------------------------------------+ - * | ... ... | | ... ... | - * | +--------------------+ | +-------+ - * | | | | - * +----------------------------+ +----------------------------+ - * | | | | - * +-------+ | +--------------------+ | - * | | | | - * v v v v - * +---------------------------------------------------------------+ - * | | | - * +---------------------------------------------------------------+ - * 0 15 16 31 - * - * Additionally, we have to access the registers in 32-bit words - */ - words = SHA256_BYTES >> 3; - - /* Swap bytes 0-15 (first four registers) */ src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; for (i = 0 ; i < words ; i++) { tmp = src[words - 1 - i]; /* Words are read in little endian */ - *dst++ = (uint8_t)((tmp >> 24) & 0xFF); - *dst++ = (uint8_t)((tmp >> 16) & 0xFF); - *dst++ = (uint8_t)((tmp >> 8) & 0xFF); *dst++ = (uint8_t)(tmp & 0xFF); - } - - /* Swap bytes 16-31 (last four registers) */ - src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2); - for (i = 0 ; i < words ; i++) { - tmp = src[words - 1 - i]; - *dst++ = (uint8_t)((tmp >> 24) & 0xFF); - *dst++ = (uint8_t)((tmp >> 16) & 0xFF); *dst++ = (uint8_t)((tmp >> 8) & 0xFF); - *dst++ = (uint8_t)(tmp & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); } -#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \ - || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */ *key_ptr = (void *)rotpk_hash_der; *key_len = (unsigned int)sizeof(rotpk_hash_der); @@ -139,6 +70,65 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, return 0; } +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) +/* + * Return development ROTPK hash generated from ROT_KEY. + */ +int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + *key_ptr = arm_rotpk_header; + *key_len = arm_rotpk_hash_end - arm_rotpk_header; + *flags = ROTPK_IS_HASH; + return 0; +} +#endif + +#if ARM_CRYPTOCELL_INTEG +/* + * Return ROTPK hash from CryptoCell. + */ +int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + unsigned char *dst; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + /* Copy the DER header */ + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + *key_ptr = rotpk_hash_der; + *key_len = sizeof(rotpk_hash_der); + return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags); +} +#endif + +/* + * Wraper function for most Arm platforms to get ROTPK hash. + */ +int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ +#if ARM_CRYPTOCELL_INTEG + return arm_get_rotpk_info_cc(key_ptr, key_len, flags); +#else + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) + return arm_get_rotpk_info_dev(key_ptr, key_len, flags); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + return arm_get_rotpk_info_regs(key_ptr, key_len, flags); +#else + return 1; +#endif + +#endif /* ARM_CRYPTOCELL_INTEG */ +} + /* * Return the non-volatile counter value stored in the platform. The cookie * will contain the OID of the counter in the certificate. @@ -179,37 +169,3 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) { return 1; } -#else /* ARM_CRYPTOCELL_INTEG */ - -#include <drivers/arm/cryptocell/cc_rotpk.h> - -/* - * Return the ROTPK hash in the following ASN.1 structure in DER format: - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm AlgorithmIdentifier, - * digest OCTET STRING - * } - */ -int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, - unsigned int *flags) -{ - unsigned char *dst; - - assert(key_ptr != NULL); - assert(key_len != NULL); - assert(flags != NULL); - - /* Copy the DER header */ - memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); - dst = &rotpk_hash_der[rotpk_hash_hdr_len]; - *key_ptr = rotpk_hash_der; - *key_len = sizeof(rotpk_hash_der); - return cc_get_rotpk_hash(dst, SHA256_BYTES, flags); -} -#endif /* ARM_CRYPTOCELL_INTEG */ diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index b98dfd48b2..da63430454 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -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 # @@ -12,31 +12,60 @@ BL1_SOURCES += drivers/cfi/v2m/v2m_flash.c BL2_SOURCES += drivers/cfi/v2m/v2m_flash.c ifneq (${TRUSTED_BOARD_BOOT},0) - ifneq (${ARM_CRYPTOCELL_INTEG}, 1) - # ROTPK hash location - ifeq (${ARM_ROTPK_LOCATION}, regs) - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID - else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) - KEY_ALG := rsa - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID - else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) - KEY_ALG := ecdsa - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID - else - $(error "Unsupported ARM_ROTPK_LOCATION value") - endif - $(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) - - # Certificate NV-Counters. Use values corresponding to tied off values in - # ARM development platforms - TFW_NVCTR_VAL ?= 31 - NTFW_NVCTR_VAL ?= 223 - else - # Certificate NV-Counters when CryptoCell is integrated. For development - # platforms we set the counter to first valid value. - TFW_NVCTR_VAL ?= 0 - NTFW_NVCTR_VAL ?= 0 - endif - BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c - BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c +ifneq (${ARM_CRYPTOCELL_INTEG}, 1) +# ROTPK hash location +ifeq (${ARM_ROTPK_LOCATION}, regs) + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID +else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) + KEY_ALG := rsa + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID + ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin +$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) +$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) +$(warning Development keys support for FVP is deprecated. Use `regs` \ +option instead) +else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) + KEY_ALG := ecdsa + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID + ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin +$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) +$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) +$(warning Development keys support for FVP is deprecated. Use `regs` \ +option instead) +else + $(error "Unsupported ARM_ROTPK_LOCATION value") +endif + +$(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) + +# Force generation of the new hash if ROT_KEY is specified +ifdef ROT_KEY + HASH_PREREQUISITES = $(ROT_KEY) FORCE +FORCE: +else + HASH_PREREQUISITES = $(ROT_KEY) +endif + +$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES) +ifndef ROT_KEY + $(error Cannot generate hash: no ROT_KEY defined) +endif + openssl rsa -in $< -pubout -outform DER | openssl dgst \ + -sha256 -binary > $@ + +# Certificate NV-Counters. Use values corresponding to tied off values in +# ARM development platforms +TFW_NVCTR_VAL ?= 31 +NTFW_NVCTR_VAL ?= 223 +else +# Certificate NV-Counters when CryptoCell is integrated. For development +# platforms we set the counter to first valid value. +TFW_NVCTR_VAL ?= 0 +NTFW_NVCTR_VAL ?= 0 +endif +BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S +BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S + endif diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S new file mode 100644 index 0000000000..80f2192e4d --- /dev/null +++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "plat/arm/common/arm_def.h" + + .global arm_rotpk_header + .global arm_rotpk_header_end + .section .rodata.arm_rotpk_hash, "a" + +arm_rotpk_header: + .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 + .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +arm_rotpk_header_len: + +#ifdef ARM_ROTPK_HASH + .global arm_rotpk_hash_end + .incbin ARM_ROTPK_HASH +arm_rotpk_hash_end: +#endif + +.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header +.error "Invalid ROTPK header length." +.endif diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index dc50764356..a09b80e10b 100644 --- a/plat/arm/board/fvp/fvp_trusted_boot.c +++ b/plat/arm/board/fvp/fvp_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,12 +9,31 @@ #include <string.h> #include <lib/mmio.h> - +#include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> #include <platform_def.h> #include <tools_share/tbbr_oid.h> /* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} + +/* * Store a new non-volatile counter value. * * On some FVP versions, the non-volatile counters are read-only so this diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index c2b7b98d4d..602ea6defa 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -139,13 +139,13 @@ # if TRUSTED_BOARD_BOOT # define PLATFORM_STACK_SIZE UL(0x1000) # else -# define PLATFORM_STACK_SIZE UL(0x440) +# define PLATFORM_STACK_SIZE UL(0x500) # endif #elif defined(IMAGE_BL2) # if TRUSTED_BOARD_BOOT # define PLATFORM_STACK_SIZE UL(0x1000) # else -# define PLATFORM_STACK_SIZE UL(0x400) +# define PLATFORM_STACK_SIZE UL(0x440) # endif #elif defined(IMAGE_BL2U) # define PLATFORM_STACK_SIZE UL(0x400) diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 97a326c092..6fb34c48ab 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -139,7 +139,6 @@ BL1_SOURCES += drivers/arm/smmu/smmu_v3.c \ plat/arm/board/fvp/fvp_bl1_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_trusted_boot.c \ ${FVP_CPU_LIBS} \ ${FVP_INTERCONNECT_SOURCES} @@ -158,7 +157,6 @@ BL2_SOURCES += drivers/arm/sp805/sp805.c \ plat/arm/board/fvp/fvp_bl2_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_trusted_boot.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ ${FVP_SECURITY_SOURCES} @@ -302,8 +300,10 @@ endif include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c +BL2_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c # FVP being a development platform, enable capability to disable Authentication # dynamically if TRUSTED_BOARD_BOOT is set. -ifeq (${TRUSTED_BOARD_BOOT}, 1) - DYN_DISABLE_AUTH := 1 +DYN_DISABLE_AUTH := 1 endif diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 16bb33d7ef..eddd7e5704 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -224,7 +224,6 @@ /* MHU related constants */ #define PLAT_CSS_MHU_BASE UL(0x2b1f0000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* * Base address of the first memory region used for communication between AP @@ -301,4 +300,7 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c index 052ab9f8a7..075f512c36 100644 --- a/plat/arm/board/juno/juno_topology.c +++ b/plat/arm/board/juno/juno_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,7 +20,7 @@ static scmi_channel_plat_info_t juno_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -scmi_channel_plat_info_t *plat_css_get_scmi_info(void) +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &juno_scmi_plat_info; } diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c new file mode 100644 index 0000000000..25a74705d9 --- /dev/null +++ b/plat/arm/board/juno/juno_trusted_boot.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <string.h> + +#include <drivers/arm/cryptocell/cc_rotpk.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/common_def.h> +#include <plat/common/platform.h> + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; + +extern unsigned char arm_rotpk_header[]; + +/* + * Return the ROTPK hash stored in the registers of Juno board. + */ +static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + uint8_t *dst; + uint32_t *src, tmp; + unsigned int words, i; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + /* Copy the DER header */ + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + + + /* + * Append the hash from Trusted Root-Key Storage registers. The hash has + * not been written linearly into the registers, so we have to do a bit + * of byte swapping: + * + * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C + * +---------------------------------------------------------------+ + * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | + * +---------------------------------------------------------------+ + * | ... ... | | ... ... | + * | +--------------------+ | +-------+ + * | | | | + * +----------------------------+ +----------------------------+ + * | | | | + * +-------+ | +--------------------+ | + * | | | | + * v v v v + * +---------------------------------------------------------------+ + * | | | + * +---------------------------------------------------------------+ + * 0 15 16 31 + * + * Additionally, we have to access the registers in 32-bit words + */ + words = ARM_ROTPK_HASH_LEN >> 3; + + /* Swap bytes 0-15 (first four registers) */ + src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + /* Words are read in little endian */ + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + /* Swap bytes 16-31 (last four registers) */ + src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2); + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + *key_ptr = (void *)rotpk_hash_der; + *key_len = (unsigned int)sizeof(rotpk_hash_der); + *flags = ROTPK_IS_HASH; + return 0; +} + +#endif + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ +#if ARM_CRYPTOCELL_INTEG + return arm_get_rotpk_info_cc(key_ptr, key_len, flags); +#else + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) + return arm_get_rotpk_info_dev(key_ptr, key_len, flags); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + return juno_get_rotpk_info_regs(key_ptr, key_len, flags); +#else + return 1; +#endif + +#endif /* ARM_CRYPTOCELL_INTEG */ +} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index bd6bae536d..a85ad53761 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -91,6 +91,11 @@ ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) BL1_SOURCES += drivers/arm/css/sds/sds.c endif +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c +BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c +endif + endif ifneq (${RESET_TO_BL31},0) diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 6a309e8e16..cc07852c27 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.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 */ @@ -90,7 +90,6 @@ #define PLAT_ARM_NSTIMER_FRAME_ID 0 #define PLAT_CSS_MHU_BASE 0x45000000 -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE #define PLAT_MAX_PWR_LVL 2 #define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \ @@ -144,4 +143,7 @@ #define SBSA_SECURE_WDOG_BASE UL(0x2A480000) #define SBSA_SECURE_WDOG_TIMEOUT UL(100) +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index b150b89599..136287a8da 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -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 */ @@ -74,7 +74,7 @@ static uintptr_t n1sdp_multichip_gicr_frames[3] = { 0 }; -scmi_channel_plat_info_t *plat_css_get_scmi_info() +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &n1sdp_scmi_plat_info; } diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts new file mode 100644 index 0000000000..4d4580d68b --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + /* compatible string */ + compatible = "arm,rd-daniel"; + + /* + * Place holder for system-id node with default values. The + * value of platform-id and config-id will be set to the + * correct values during the BL2 stage of boot. + */ + system-id { + platform-id = <0x0>; + config-id = <0x0>; + multi-chip-mode = <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 0000000000..9acec137e7 --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + /* Platform Config */ + compatible = "arm,tb_fw"; + nt_fw_config_addr = <0x0 0xFEF00000>; + nt_fw_config_max_size = <0x0100000>; + + /* + * 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/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h new file mode 100644 index 0000000000..516360278e --- /dev/null +++ b/plat/arm/board/rddaniel/include/platform_def.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <lib/utils_def.h> + +#include <sgi_base_platform_def.h> + +#define PLAT_ARM_CLUSTER_COUNT U(16) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) +#define CSS_SGI_MAX_PE_PER_CPU U(1) + +#define PLAT_CSS_MHU_BASE UL(0x45400000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE + +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifdef __aarch64__ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk new file mode 100644 index 0000000000..67f57779a2 --- /dev/null +++ b/plat/arm/board/rddaniel/platform.mk @@ -0,0 +1,43 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include plat/arm/css/sgi/sgi-common.mk + +RDDANIEL_BASE = plat/arm/board/rddaniel + +PLAT_INCLUDES += -I${RDDANIEL_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_zeus.S + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDDANIEL_BASE}/rddaniel_err.c + +BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_plat.c \ + ${RDDANIEL_BASE}/rddaniel_security.c \ + ${RDDANIEL_BASE}/rddaniel_err.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDDANIEL_BASE}/rddaniel_plat.c \ + ${RDDANIEL_BASE}/rddaniel_topology.c \ + drivers/cfi/v2m/v2m_flash.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) + +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_nt_fw_config.dts +NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb + +# Add the NT_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) + +override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rddaniel/rddaniel_err.c b/plat/arm/board/rddaniel/rddaniel_err.c new file mode 100644 index 0000000000..5e10942199 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_err.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * rddaniel error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (1) { + wfi(); + } +} diff --git a/plat/arm/board/rddaniel/rddaniel_plat.c b/plat/arm/board/rddaniel/rddaniel_plat.c new file mode 100644 index 0000000000..ab5251e511 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_plat.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/common/platform.h> +#include <sgi_plat.h> + +unsigned int plat_arm_sgi_get_platform_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) + & SID_SYSTEM_ID_PART_NUM_MASK; +} + +unsigned int plat_arm_sgi_get_config_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); +} + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/rddaniel/rddaniel_security.c b/plat/arm/board/rddaniel/rddaniel_security.c new file mode 100644 index 0000000000..6aa38c822c --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_security.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <platform_def.h> + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/rddaniel/rddaniel_topology.c b/plat/arm/board/rddaniel/rddaniel_topology.c new file mode 100644 index 0000000000..55f5e04da5 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_topology.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> +#include <plat/arm/css/common/css_pm.h> + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char rd_daniel_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return rd_daniel_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)) +}; diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts index 41769217a9..0af821e15d 100644 --- a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,6 +17,7 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index 2be3f8852f..3fb640972a 100644 --- a/plat/arm/board/rde1edge/include/platform_def.h +++ b/plat/arm/board/rde1edge/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(2) #define PLAT_CSS_MHU_BASE UL(0x45400000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define RDE1EDGE_DMC620_BASE0 UL(0x4e000000) @@ -37,4 +36,9 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index 43c37ffc11..88aa634b86 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c +BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb @@ -42,4 +47,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +ifneq ($(CSS_SGI_CHIP_COUNT),1) + $(error "Chip count for RDE1Edge should be 1, currently set to \ + ${CSS_SGI_CHIP_COUNT}.") +endif + override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c index a1b8d621d6..44d818aecb 100644 --- a/plat/arm/board/rde1edge/rde1edge_plat.c +++ b/plat/arm/board/rde1edge/rde1edge_plat.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <plat/common/platform.h> +#include <sgi_plat.h> unsigned int plat_arm_sgi_get_platform_id(void) { @@ -16,3 +17,13 @@ unsigned int plat_arm_sgi_get_config_id(void) { return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); } + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return 0; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c index 0b56f208ae..a16283e450 100644 --- a/plat/arm/board/rde1edge/rde1edge_topology.c +++ b/plat/arm/board/rde1edge/rde1edge_topology.c @@ -7,12 +7,15 @@ #include <plat/arm/common/plat_arm.h> /****************************************************************************** - * The power domain tree descriptor. + * The power domain tree descriptor. RD-E1-Edge platform consists of two + * clusters with eight CPUs in each cluster. The CPUs are multi-threaded with + * two threads per CPU. ******************************************************************************/ static const unsigned char rde1edge_pd_tree_desc[] = { + CSS_SGI_CHIP_COUNT, PLAT_ARM_CLUSTER_COUNT, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER + CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU, + CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU }; /****************************************************************************** diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c new file mode 100644 index 0000000000..c271f7f2dc --- /dev/null +++ b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts index fff5874769..68366c5ca1 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts @@ -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 */ @@ -17,5 +17,6 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index c635faa441..ab63e23ece 100644 --- a/plat/arm/board/rdn1edge/include/platform_def.h +++ b/plat/arm/board/rdn1edge/include/platform_def.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,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45400000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define RDN1EDGE_DMC620_BASE0 UL(0x4e000000) @@ -27,15 +26,23 @@ #define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 +/* Virtual address used by dynamic mem_protect for chunk_base */ +#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) + /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes */ #ifdef __aarch64__ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43) #else #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index ca1e95eaf0..04f70f3f25 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -26,9 +26,18 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ ${RDN1EDGE_BASE}/rdn1edge_plat.c \ ${RDN1EDGE_BASE}/rdn1edge_topology.c \ drivers/cfi/v2m/v2m_flash.c \ + drivers/arm/gic/v3/gic600_multichip.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +endif + +# Enable dynamic addition of MMAP regions in BL31 +BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb @@ -42,4 +51,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),1 2)) + $(error "Chip count for RDN1Edge platform should either 1 or 2, currently \ + set to ${CSS_SGI_CHIP_COUNT}.") +endif + override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c index 3b7e5ee4e4..f62c6f402b 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_plat.c +++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c @@ -1,10 +1,44 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <common/debug.h> +#include <drivers/arm/gic600_multichip.h> +#include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> +#include <sgi_base_platform_def.h> +#include <sgi_plat.h> + +#if defined(IMAGE_BL31) +static const mmap_region_t rdn1edge_dynamic_mmap[] = { + ARM_MAP_SHARED_RAM_REMOTE_CHIP(1), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1) +}; + +static struct gic600_multichip_data rdn1e1_multichip_data __init = { + .rt_owner_base = PLAT_ARM_GICD_BASE, + .rt_owner = 0, + .chip_count = CSS_SGI_CHIP_COUNT, + .chip_addrs = { + PLAT_ARM_GICD_BASE >> 16, + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16 + }, + .spi_ids = { + {32, 255}, + {0, 0} + } +}; + +static uintptr_t rdn1e1_multichip_gicr_frames[] = { + PLAT_ARM_GICR_BASE, /* Chip 0's GICR Base */ + PLAT_ARM_GICR_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), /* Chip 1's GICR BASE */ + UL(0) /* Zero Termination */ +}; +#endif /* IMAGE_BL31 */ unsigned int plat_arm_sgi_get_platform_id(void) { @@ -16,3 +50,48 @@ unsigned int plat_arm_sgi_get_config_id(void) { return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); } + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + +/* + * IMAGE_BL31 macro is added to build bl31_platform_setup function only for BL31 + * because PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not + * for other stages. + */ +#if defined(IMAGE_BL31) +void bl31_platform_setup(void) +{ + int i, ret; + + if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) { + ERROR("Chip Count is set to %d but multi-chip mode not enabled\n", + CSS_SGI_CHIP_COUNT); + panic(); + } else if (plat_arm_sgi_get_multi_chip_mode() == 1 && + CSS_SGI_CHIP_COUNT > 1) { + INFO("Enabling support for multi-chip in RD-N1-Edge\n"); + + for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) { + ret = mmap_add_dynamic_region( + rdn1edge_dynamic_mmap[i].base_pa, + rdn1edge_dynamic_mmap[i].base_va, + rdn1edge_dynamic_mmap[i].size, + rdn1edge_dynamic_mmap[i].attr + ); + if (ret != 0) { + ERROR("Failed to add dynamic mmap entry\n"); + panic(); + } + } + + plat_arm_override_gicr_frames(rdn1e1_multichip_gicr_frames); + gic600_multichip_init(&rdn1e1_multichip_data); + } + + sgi_bl31_common_platform_setup(); +} +#endif /* IMAGE_BL31 */ diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/rdn1edge/rdn1edge_topology.c index 687ae35953..5bbea6998c 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_topology.c +++ b/plat/arm/board/rdn1edge/rdn1edge_topology.c @@ -5,14 +5,19 @@ */ #include <plat/arm/common/plat_arm.h> +#include <plat/arm/css/common/css_pm.h> /****************************************************************************** * The power domain tree descriptor. ******************************************************************************/ static const unsigned char rdn1edge_pd_tree_desc[] = { - PLAT_ARM_CLUSTER_COUNT, + (PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT), + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#if (CSS_SGI_CHIP_COUNT > 1) CSS_SGI_MAX_CPUS_PER_CLUSTER, CSS_SGI_MAX_CPUS_PER_CLUSTER +#endif }; /******************************************************************************* @@ -28,5 +33,22 @@ const unsigned char *plat_get_power_domain_tree_desc(void) * to the SCMI power domain ID implemented by SCP. ******************************************************************************/ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { - 0, 1, 2, 3, 4, 5, 6, 7 + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), +#if (CSS_SGI_CHIP_COUNT > 1) + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x7)), +#endif }; diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c new file mode 100644 index 0000000000..c271f7f2dc --- /dev/null +++ b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts index 1e1ea14b0e..260247a0d8 100644 --- a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts +++ b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,5 +17,6 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index fd59e5277e..95986cf4a3 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.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,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45000000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define SGI575_DMC620_BASE0 UL(0x4e000000) @@ -38,4 +37,9 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index ce2717fe02..76cc4e2c2e 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c +BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb @@ -41,3 +46,8 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) + +ifneq ($(CSS_SGI_CHIP_COUNT),1) + $(error "Chip count for SGI575 should be 1, currently set to \ + ${CSS_SGI_CHIP_COUNT}.") +endif diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c index 0d3fd16ab6..dc294e6a8d 100644 --- a/plat/arm/board/sgi575/sgi575_plat.c +++ b/plat/arm/board/sgi575/sgi575_plat.c @@ -1,11 +1,11 @@ /* - * 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 */ #include <plat/common/platform.h> - +#include <sgi_plat.h> #include <sgi_variant.h> unsigned int plat_arm_sgi_get_platform_id(void) @@ -18,3 +18,13 @@ unsigned int plat_arm_sgi_get_config_id(void) return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT) & SSC_VERSION_CONFIG_MASK; } + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return 0; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c new file mode 100644 index 0000000000..c271f7f2dc --- /dev/null +++ b/plat/arm/board/sgi575/sgi575_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 7a843c369c..f096ca53d3 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -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,3 +21,8 @@ BL2_SOURCES += lib/utils/mem_region.c \ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c +BL2_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c +endif diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c new file mode 100644 index 0000000000..c271f7f2dc --- /dev/null +++ b/plat/arm/board/sgm775/sgm775_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S index b80903d061..04bfb77718 100644 --- a/plat/arm/css/sgi/aarch64/sgi_helper.S +++ b/plat/arm/css/sgi/aarch64/sgi_helper.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 */ @@ -18,19 +18,22 @@ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) * * Helper function to calculate the core position. + * (ChipId * PLAT_ARM_CLUSTER_COUNT * + * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) + * (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) + * (CPUId * CSS_SGI_MAX_PE_PER_CPU) + * ThreadId * * which can be simplified as: * - * ((ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER + CPUId) * - * CSS_SGI_MAX_PE_PER_CPU) + ThreadId + * ((((ChipId * PLAT_ARM_CLUSTER_COUNT) + ClusterId) * + * CSS_SGI_MAX_CPUS_PER_CLUSTER) + CPUId) * CSS_SGI_MAX_PE_PER_CPU + + * ThreadId * ------------------------------------------------------ */ func plat_arm_calc_core_pos - mov x3, x0 + mov x4, x0 /* * The MT bit in MPIDR is always set for SGI platforms @@ -38,15 +41,18 @@ func plat_arm_calc_core_pos */ /* Extract individual affinity fields from MPIDR */ - ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS /* Compute linear position */ + mov x4, #PLAT_ARM_CLUSTER_COUNT + madd x2, x3, x4, x2 mov x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER madd x1, x2, x4, x1 - mov x5, #CSS_SGI_MAX_PE_PER_CPU - madd x0, x1, x5, x0 + mov x4, #CSS_SGI_MAX_PE_PER_CPU + madd x0, x1, x4, x0 ret endfunc plat_arm_calc_core_pos diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index e21457304b..4986378e99 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.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 */ @@ -17,12 +17,16 @@ #include <plat/arm/soc/common/soc_css_def.h> #include <plat/common/common_def.h> -#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ - CSS_SGI_MAX_CPUS_PER_CLUSTER * \ +#define PLATFORM_CORE_COUNT (CSS_SGI_CHIP_COUNT * \ + PLAT_ARM_CLUSTER_COUNT * \ + CSS_SGI_MAX_CPUS_PER_CLUSTER * \ CSS_SGI_MAX_PE_PER_CPU) #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */ +/* Remote chip address offset (4TB per chip) */ +#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) ((ULL(1) << 42) * (n)) + /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the * plat_arm_mmap array defined for each BL stage. @@ -35,14 +39,14 @@ # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else # define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 8 # endif #elif defined(IMAGE_BL32) # define PLAT_ARM_MMAP_ENTRIES 8 # define MAX_XLAT_TABLES 5 #elif !USE_ROMLIB # define PLAT_ARM_MMAP_ENTRIES 11 -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 7 #else # define PLAT_ARM_MMAP_ENTRIES 12 # define MAX_XLAT_TABLES 6 @@ -129,10 +133,29 @@ CSS_SGI_DEVICE_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -/* GIC related constants */ -#define PLAT_ARM_GICD_BASE 0x30000000 -#define PLAT_ARM_GICC_BASE 0x2C000000 -#define PLAT_ARM_GICR_BASE 0x300C0000 +#define ARM_MAP_SHARED_RAM_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + ARM_SHARED_RAM_BASE, \ + ARM_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE \ + ) + +#define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + CSS_SGI_DEVICE_BASE, \ + CSS_SGI_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE \ + ) + +#define SOC_CSS_MAP_DEVICE_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + SOC_CSS_DEVICE_BASE, \ + SOC_CSS_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE \ + ) /* Map the secure region for access from S-EL0 */ #define PLAT_ARM_SECURE_MAP_DEVICE MAP_REGION_FLAT( \ @@ -212,4 +235,7 @@ #define SBSA_SECURE_WDOG_BASE UL(0x2A480000) #define SBSA_SECURE_WDOG_TIMEOUT UL(100) +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT CSS_SGI_CHIP_COUNT + #endif /* SGI_BASE_PLATFORM_DEF_H */ diff --git a/plat/arm/css/sgi/include/sgi_plat.h b/plat/arm/css/sgi/include/sgi_plat.h new file mode 100644 index 0000000000..a5fbded3ca --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_plat.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_PLAT_H +#define SGI_PLAT_H + +/* BL31 platform setup common to all SGI based platforms */ +void sgi_bl31_common_platform_setup(void); + +#endif /* SGI_PLAT_H */ diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h index c75f2132b9..f4c5300d09 100644 --- a/plat/arm/css/sgi/include/sgi_variant.h +++ b/plat/arm/css/sgi/include/sgi_variant.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 */ @@ -8,16 +8,21 @@ #define SGI_VARIANT_H /* SSC_VERSION values for SGI575 */ -#define SGI575_SSC_VER_PART_NUM 0x0783 +#define SGI575_SSC_VER_PART_NUM 0x0783 /* SID Version values for RD-N1E1-Edge */ #define RD_N1E1_EDGE_SID_VER_PART_NUM 0x0786 #define RD_E1_EDGE_CONFIG_ID 0x2 +/* SID Version values for RD-Daniel */ +#define RD_DANIEL_SID_VER_PART_NUM 0x078a + /* Structure containing SGI platform variant information */ typedef struct sgi_platform_info { unsigned int platform_id; /* Part Number of the platform */ unsigned int config_id; /* Config Id of the platform */ + unsigned int chip_id; /* Chip Id or Node number */ + unsigned int multi_chip_mode; /* Multi-chip mode availability */ } sgi_platform_info_t; extern sgi_platform_info_t sgi_plat_info; @@ -28,4 +33,7 @@ unsigned int plat_arm_sgi_get_platform_id(void); /* returns the configuration id of the platform */ unsigned int plat_arm_sgi_get_config_id(void); +/* returns true if operating in multi-chip configuration */ +unsigned int plat_arm_sgi_get_multi_chip_mode(void); + #endif /* SGI_VARIANT_H */ diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index 71601118f6..40a7fd8a3e 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -16,6 +16,8 @@ EL3_EXCEPTION_HANDLING := 0 HANDLE_EA_EL3_FIRST := 0 +CSS_SGI_CHIP_COUNT := 1 + INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c PLAT_INCLUDES += -I${CSS_ENT_BASE}/include @@ -52,6 +54,8 @@ endif $(eval $(call add_define,SGI_PLAT)) +$(eval $(call add_define,CSS_SGI_CHIP_COUNT)) + override CSS_LOAD_SCP_IMAGES := 0 override NEED_BL2U := no override ARM_BL31_IN_DRAM := 1 diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index ba050d5f1c..fcb7e1f9fa 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -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 */ @@ -28,18 +28,57 @@ static scmi_channel_plat_info_t sgi575_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info = { +static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = { + { .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE, .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0), .db_preserve_mask = 0xfffffffe, .db_modify_mask = 0x1, .ring_doorbell = &mhuv2_ring_doorbell, + }, + #if (CSS_SGI_CHIP_COUNT > 1) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif + #if (CSS_SGI_CHIP_COUNT > 2) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif + #if (CSS_SGI_CHIP_COUNT > 3) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif }; -scmi_channel_plat_info_t *plat_css_get_scmi_info(void) +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { - if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) - return &rd_n1e1_edge_scmi_plat_info; + if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM || + sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM) { + if (channel_id >= sizeof(rd_n1e1_edge_scmi_plat_info)) + panic(); + return &rd_n1e1_edge_scmi_plat_info[channel_id]; + } else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM) return &sgi575_scmi_plat_info; else @@ -51,11 +90,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { sgi_plat_info.platform_id = plat_arm_sgi_get_platform_id(); sgi_plat_info.config_id = plat_arm_sgi_get_config_id(); + sgi_plat_info.multi_chip_mode = plat_arm_sgi_get_multi_chip_mode(); arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); } -void bl31_platform_setup(void) +void sgi_bl31_common_platform_setup(void) { arm_bl31_platform_setup(); @@ -66,9 +106,13 @@ void bl31_platform_setup(void) const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { - /* For RD-E1-Edge platform only CPU ON/OFF is supported */ - if ((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) && - (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) { + /* + * For RD-E1-Edge and RD-Daniel platforms, only CPU power ON/OFF + * PSCI platform callbacks are supported. + */ + if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) && + (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) || + (sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM)) { ops->cpu_standby = NULL; ops->system_off = NULL; ops->system_reset = NULL; diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c index a2f10dcc7f..09f3b728db 100644 --- a/plat/arm/css/sgi/sgi_image_load.c +++ b/plat/arm/css/sgi/sgi_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,6 +62,13 @@ static int plat_sgi_append_config_node(void) return -1; } + platcfg = plat_arm_sgi_get_multi_chip_mode(); + err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg); + if (err < 0) { + ERROR("Failed to set multi-chip-mode\n"); + return -1; + } + flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size); return 0; 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 24bbed513f..90511ac6a7 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.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 */ @@ -86,7 +86,6 @@ /* MHU related constants */ #define PLAT_CSS_MHU_BASE 0x2b1f0000 -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE #define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000 #define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 @@ -239,4 +238,7 @@ /* System power domain level */ #define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* SGM_BASE_PLATFORM_DEF_H */ diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c index 7e92ac8350..907e9fdacf 100644 --- a/plat/arm/css/sgm/sgm_bl31_setup.c +++ b/plat/arm/css/sgm/sgm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,7 +20,7 @@ static scmi_channel_plat_info_t sgm775_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -scmi_channel_plat_info_t *plat_css_get_scmi_info() +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &sgm775_scmi_plat_info; } diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 13099b40fe..4b11440955 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -14,6 +14,7 @@ #include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables.h> +#include "socfpga_mailbox.h" #include "socfpga_private.h" static entry_point_info_t bl32_image_ep_info; @@ -107,6 +108,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_agilex_mmap[] = { diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index c4b9e59671..38f46963a4 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -73,6 +73,29 @@ /* Mailbox REBOOT commands */ #define MBOX_CMD_REBOOT_HPS 71 +/* Mailbox RSU commands */ +#define MBOX_GET_SUBPARTITION_TABLE 90 +#define MBOX_RSU_STATUS 91 +#define MBOX_RSU_UPDATE 92 + +/* Mailbox RSU macros */ +#define RSU_VERSION_ACMF BIT(8) +#define RSU_VERSION_ACMF_MASK 0xff00 + +/* HPS stage notify command */ +#define MBOX_HPS_STAGE_NOTIFY 93 + +/* Execution states for HPS_STAGE_NOTIFY */ +#define HPS_EXECUTION_STATE_FSBL 0 +#define HPS_EXECUTION_STATE_SSBL 1 +#define HPS_EXECUTION_STATE_OS 2 + +/* Mailbox reconfiguration commands */ +#define MBOX_CONFIG_STATUS 4 +#define MBOX_RECONFIG 6 +#define MBOX_RECONFIG_DATA 8 +#define MBOX_RECONFIG_STATUS 9 + /* Generic error handling */ #define MBOX_TIMEOUT -2047 #define MBOX_NO_RESPONSE -2 @@ -98,13 +121,6 @@ #define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007 #define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008 -/* Mailbox reconfiguration commands */ -#define MBOX_CONFIG_STATUS 4 -#define MBOX_RECONFIG 6 -#define MBOX_RECONFIG_DATA 8 -#define MBOX_RECONFIG_STATUS 9 - - void mailbox_set_int(int interrupt_input); int mailbox_init(void); void mailbox_set_qspi_close(void); @@ -122,4 +138,9 @@ void mailbox_clear_response(void); uint32_t intel_mailbox_get_config_status(uint32_t cmd); int intel_mailbox_is_fpga_not_ready(void); +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_update(uint32_t *flash_offset); +int mailbox_hps_stage_notify(uint32_t execution_stage); + #endif /* SOCFPGA_MBOX_H */ diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 6bb41f31b6..2b1d9837ce 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -28,6 +28,7 @@ #define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D #define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E #define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F +#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E /* FPGA config helpers */ #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 8d7c1d6638..673c2d56e1 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -267,6 +267,55 @@ void mailbox_reset_cold(void) mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0); } +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE, + NULL, 0, 0, (uint32_t *)resp_buf, + resp_buf_len); +} + +struct rsu_status_info { + uint64_t current_image; + uint64_t fail_image; + uint32_t state; + uint32_t version; + uint32_t error_location; + uint32_t error_details; + uint32_t retry_counter; +}; + +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) +{ + int ret; + struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; + + info->retry_counter = ~0; + + ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, 0, + (uint32_t *)resp_buf, resp_buf_len); + + if (ret < 0) + return ret; + + if (info->retry_counter != ~0) + if (!(info->version & RSU_VERSION_ACMF_MASK)) + info->version |= RSU_VERSION_ACMF; + + return ret; +} + +int mailbox_rsu_update(uint32_t *flash_offset) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, + (uint32_t *)flash_offset, 2, 0, NULL, 0); +} + +int mailbox_hps_stage_notify(uint32_t execution_stage) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, + &execution_stage, 1, 0, NULL, 0); +} + int mailbox_init(void) { int status = 0; diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index d8a6c19804..d27ab9f966 100644 --- a/plat/intel/soc/common/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -130,9 +130,14 @@ static void __dead2 socfpga_system_off(void) panic(); } +extern uint64_t intel_rsu_update_address; + static void __dead2 socfpga_system_reset(void) { - mailbox_reset_cold(); + if (intel_rsu_update_address) + mailbox_rsu_update((uint32_t *)&intel_rsu_update_address); + else + mailbox_reset_cold(); while (1) wfi(); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 41dae9e763..5b600e5ea8 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -252,12 +252,16 @@ static bool is_fpga_config_buffer_full(void) return true; } -static bool is_address_in_ddr_range(uint64_t addr) +static bool is_address_in_ddr_range(uint64_t addr, uint64_t size) { - if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE) - return true; + if (size > (UINT64_MAX - addr)) + return false; + if (addr < DRAM_BASE) + return false; + if (addr + size > DRAM_BASE + DRAM_SIZE) + return false; - return false; + return true; } static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) @@ -266,8 +270,7 @@ static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) intel_fpga_sdm_write_all(); - if (!is_address_in_ddr_range(mem) || - !is_address_in_ddr_range(mem + size) || + if (!is_address_in_ddr_range(mem, size) || is_fpga_config_buffer_full()) return INTEL_SIP_SMC_STATUS_REJECTED; @@ -365,6 +368,66 @@ uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, return INTEL_SIP_SMC_STATUS_ERROR; } +/* Intel Remote System Update (RSU) services */ +uint64_t intel_rsu_update_address; + +static uint32_t intel_rsu_status(uint64_t *respbuf, uint32_t respbuf_sz) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_update(uint64_t update_address) +{ + intel_rsu_update_address = update_address; + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_notify(uint64_t execution_stage) +{ + if (mailbox_hps_stage_notify((uint32_t)execution_stage) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, + uint32_t *ret_stat) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + *ret_stat = respbuf[8]; + return INTEL_SIP_SMC_STATUS_OK; +} + +/* Mailbox services */ +static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len, + int urgent, uint32_t *response, + int resp_len, int *mbox_status, + int *len_in_resp) +{ + *len_in_resp = 0; + *mbox_status = 0; + + if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) + return INTEL_SIP_SMC_STATUS_REJECTED; + + int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent, + response, resp_len); + + if (status < 0) { + *mbox_status = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *mbox_status = 0; + *len_in_resp = status; + return INTEL_SIP_SMC_STATUS_OK; +} + /* * This function is responsible for handling all SiP calls from the NS world */ @@ -381,7 +444,10 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, uint32_t val = 0; uint32_t status = INTEL_SIP_SMC_STATUS_OK; uint32_t completed_addr[3]; + uint64_t rsu_respbuf[9]; uint32_t count = 0; + u_register_t x5, x6; + int mbox_status, len_in_resp; switch (smc_fid) { case SIP_SVC_UID: @@ -446,6 +512,41 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, (uint32_t)x3, &val); SMC_RET3(handle, status, val, x1); + case INTEL_SIP_SMC_RSU_STATUS: + status = intel_rsu_status(rsu_respbuf, + ARRAY_SIZE(rsu_respbuf)); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET4(handle, rsu_respbuf[0], rsu_respbuf[1], + rsu_respbuf[2], rsu_respbuf[3]); + } + + case INTEL_SIP_SMC_RSU_UPDATE: + status = intel_rsu_update(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_NOTIFY: + status = intel_rsu_notify(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_RETRY_COUNTER: + status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf, + ARRAY_SIZE(rsu_respbuf), &val); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET2(handle, status, val); + } + + case INTEL_SIP_SMC_MBOX_SEND_CMD: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, + (uint32_t *)x5, x6, &mbox_status, + &len_in_resp); + SMC_RET4(handle, status, mbox_status, x5, len_in_resp); + default: return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index 29f57c467b..4c3123815a 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -16,6 +16,7 @@ #include <plat/common/platform.h> #include <platform_def.h> +#include "socfpga_mailbox.h" #include "socfpga_private.h" #include "socfpga_reset_manager.h" #include "socfpga_system_manager.h" @@ -115,6 +116,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_stratix10_mmap[] = { diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c index ae899c424e..eaf96751ce 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c @@ -316,7 +316,7 @@ int tegra_bpmp_ipc_enable_clock(uint32_t clk_id) /* prepare the MRQ_CLK command */ req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id); - ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req), + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req), NULL, 0); if (ret != 0) { ERROR("%s: failed for module %d with error %d\n", __func__, @@ -339,7 +339,7 @@ int tegra_bpmp_ipc_disable_clock(uint32_t clk_id) /* prepare the MRQ_CLK command */ req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id); - ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req), + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req), NULL, 0); if (ret != 0) { ERROR("%s: failed for module %d with error %d\n", __func__, diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h index 7059c37016..d85b906b88 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h @@ -1,17 +1,17 @@ /* - * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef INTF_H -#define INTF_H +#ifndef BPMP_INTF_H +#define BPMP_INTF_H /** * Flags used in IPC req */ #define FLAG_DO_ACK (U(1) << 0) -#define FLAG_RING_DOORBELL (U(1) << 1) +#define FLAG_RING_DOORBELL (U(1) << 1) /* Bit 1 is designated for CCPlex in secure world */ #define HSP_MASTER_CCPLEX_BIT (U(1) << 1) @@ -77,16 +77,16 @@ struct __attribute__((packed)) mrq_reset_request { * */ enum { - CMD_CLK_GET_RATE = 1, - CMD_CLK_SET_RATE = 2, - CMD_CLK_ROUND_RATE = 3, - CMD_CLK_GET_PARENT = 4, - CMD_CLK_SET_PARENT = 5, - CMD_CLK_IS_ENABLED = 6, - CMD_CLK_ENABLE = 7, - CMD_CLK_DISABLE = 8, - CMD_CLK_GET_ALL_INFO = 14, - CMD_CLK_GET_MAX_CLK_ID = 15, + CMD_CLK_GET_RATE = U(1), + CMD_CLK_SET_RATE = U(2), + CMD_CLK_ROUND_RATE = U(3), + CMD_CLK_GET_PARENT = U(4), + CMD_CLK_SET_PARENT = U(5), + CMD_CLK_IS_ENABLED = U(6), + CMD_CLK_ENABLE = U(7), + CMD_CLK_DISABLE = U(8), + CMD_CLK_GET_ALL_INFO = U(14), + CMD_CLK_GET_MAX_CLK_ID = U(15), CMD_CLK_MAX, }; @@ -124,4 +124,4 @@ struct mrq_clk_request { */ #define make_mrq_clk_cmd(cmd, id) (((cmd) << 24) | (id & 0xFFFFFF)) -#endif /* INTF_H */ +#endif /* BPMP_INTF_H */ diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h index 42e6a1f7cc..1b318213b9 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef IVC_H -#define IVC_H +#ifndef BPMP_IVC_H +#define BPMP_IVC_H #include <lib/utils_def.h> #include <stdint.h> @@ -15,22 +15,21 @@ #define IVC_CHHDR_TX_FIELDS U(16) #define IVC_CHHDR_RX_FIELDS U(16) -struct ivc; struct ivc_channel_header; -/* callback handler for notify on receiving a response */ -typedef void (* ivc_notify_function)(const struct ivc *); - struct ivc { struct ivc_channel_header *rx_channel; struct ivc_channel_header *tx_channel; uint32_t w_pos; uint32_t r_pos; - ivc_notify_function notify; + void (*notify)(const struct ivc *); uint32_t nframes; uint32_t frame_size; }; +/* callback handler for notify on receiving a response */ +typedef void (* ivc_notify_function)(const struct ivc *); + int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base, uint32_t nframes, uint32_t frame_size, ivc_notify_function notify); @@ -48,4 +47,4 @@ bool tegra_ivc_tx_empty(const struct ivc *ivc); bool tegra_ivc_can_write(const struct ivc *ivc); bool tegra_ivc_can_read(const struct ivc *ivc); -#endif /* IVC_H */ +#endif /* BPMP_IVC_H */ diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 2f31906d83..c2ef981eed 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, NVIDIA Corporation. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,17 +27,6 @@ static uint64_t video_mem_base; static uint64_t video_mem_size_mb; /* - * The following platform setup functions are weakly defined. They - * provide typical implementations that will be overridden by a SoC. - */ -#pragma weak plat_memctrl_tzdram_setup - -void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) -{ - ; /* do nothing */ -} - -/* * Init Memory controller during boot. */ void tegra_memctrl_setup(void) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index cbe3377b0c..8a49e232db 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -65,35 +65,6 @@ static aapcs64_params_t bl32_args; extern uint64_t ns_image_entrypoint; /******************************************************************************* - * The following platform setup functions are weakly defined. They - * provide typical implementations that will be overridden by a SoC. - ******************************************************************************/ -#pragma weak plat_early_platform_setup -#pragma weak plat_get_bl31_params -#pragma weak plat_get_bl31_plat_params -#pragma weak plat_late_platform_setup - -void plat_early_platform_setup(void) -{ - ; /* do nothing */ -} - -struct tegra_bl31_params *plat_get_bl31_params(void) -{ - return NULL; -} - -plat_params_from_bl2_t *plat_get_bl31_plat_params(void) -{ - return NULL; -} - -void plat_late_platform_setup(void) -{ - ; /* do nothing */ -} - -/******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for * security state specified. BL33 corresponds to the non-secure image type * while BL32 corresponds to the secure image type. @@ -137,8 +108,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, /* * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so * there's no argument to relay from a previous bootloader. Platforms - * might use custom ways to get arguments, so provide handlers which - * they can override. + * might use custom ways to get arguments. */ if (arg_from_bl2 == NULL) { arg_from_bl2 = plat_get_bl31_params(); diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 34b5638ecd..50c9592f17 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -25,7 +25,6 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ plat/common/aarch64/crash_console_helpers.S \ ${TEGRA_GICv2_SOURCES} \ ${COMMON_DIR}/aarch64/tegra_helpers.S \ - ${COMMON_DIR}/drivers/pmc/pmc.c \ ${COMMON_DIR}/lib/debug/profiler.c \ ${COMMON_DIR}/tegra_bl31_setup.c \ ${COMMON_DIR}/tegra_delay_timer.c \ diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 39dc42c5ba..1f59f30aad 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,97 +28,6 @@ extern uint64_t tegra_bl31_phys_base; extern uint64_t tegra_sec_entry_point; -/* - * The following platform setup functions are weakly defined. They - * provide typical implementations that will be overridden by a SoC. - */ -#pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early -#pragma weak tegra_soc_cpu_standby -#pragma weak tegra_soc_pwr_domain_suspend -#pragma weak tegra_soc_pwr_domain_on -#pragma weak tegra_soc_pwr_domain_off -#pragma weak tegra_soc_pwr_domain_on_finish -#pragma weak tegra_soc_pwr_domain_power_down_wfi -#pragma weak tegra_soc_prepare_system_reset -#pragma weak tegra_soc_prepare_system_off -#pragma weak tegra_soc_get_target_pwr_state - -int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) -{ - return PSCI_E_NOT_SUPPORTED; -} - -int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) -{ - (void)cpu_state; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - (void)target_state; - return PSCI_E_NOT_SUPPORTED; -} - -int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) -{ - (void)mpidr; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) -{ - (void)target_state; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - (void)target_state; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) -{ - (void)target_state; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_prepare_system_reset(void) -{ - return PSCI_E_SUCCESS; -} - -__dead2 void tegra_soc_prepare_system_off(void) -{ - ERROR("Tegra System Off: operation not handled.\n"); - panic(); -} - -plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, - const plat_local_state_t *states, - uint32_t ncpu) -{ - plat_local_state_t target = PLAT_MAX_OFF_STATE, temp; - uint32_t num_cpu = ncpu; - const plat_local_state_t *local_state = states; - - (void)lvl; - - assert(ncpu != 0U); - - do { - temp = *local_state; - if ((temp < target)) { - target = temp; - } - --num_cpu; - local_state++; - } while (num_cpu != 0U); - - return target; -} - /******************************************************************************* * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND` * call to get the `power_state` parameter. This allows the platform to encode @@ -311,10 +221,10 @@ __dead2 void tegra_system_reset(void) /* per-SoC system reset handler */ (void)tegra_soc_prepare_system_reset(); - /* - * Program the PMC in order to restart the system. - */ - tegra_pmc_system_reset(); + /* wait for the system to reset */ + for (;;) { + ; + } } /******************************************************************************* diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c index b8ba09562a..1d48cc01b4 100644 --- a/plat/nvidia/tegra/common/tegra_sip_calls.c +++ b/plat/nvidia/tegra/common/tegra_sip_calls.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,32 +27,6 @@ #define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006 /******************************************************************************* - * SoC specific SiP handler - ******************************************************************************/ -#pragma weak plat_sip_handler -int32_t plat_sip_handler(uint32_t smc_fid, - uint64_t x1, - uint64_t x2, - uint64_t x3, - uint64_t x4, - const void *cookie, - void *handle, - uint64_t flags) -{ - /* unused parameters */ - (void)smc_fid; - (void)x1; - (void)x2; - (void)x3; - (void)x4; - (void)cookie; - (void)handle; - (void)flags; - - return -ENOTSUP; -} - -/******************************************************************************* * This function is responsible for handling all SiP calls ******************************************************************************/ uintptr_t tegra_sip_handler(uint32_t smc_fid, diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index dfed2aa60c..8e6c1fd2b8 100644 --- a/plat/nvidia/tegra/include/t132/tegra_def.h +++ b/plat/nvidia/tegra/include/t132/tegra_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -110,4 +111,10 @@ #define TEGRA_TZRAM_BASE U(0x7C010000) #define TEGRA_TZRAM_SIZE U(0x10000) +/******************************************************************************* + * Tegra DRAM memory base address + ******************************************************************************/ +#define TEGRA_DRAM_BASE ULL(0x80000000) +#define TEGRA_DRAM_END ULL(0x27FFFFFFF) + #endif /* TEGRA_DEF_H */ diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index da050a8952..f2a2334efe 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -279,4 +280,10 @@ #define TEGRA_TZRAM_BASE U(0x30000000) #define TEGRA_TZRAM_SIZE U(0x40000) +/******************************************************************************* + * Tegra DRAM memory base address + ******************************************************************************/ +#define TEGRA_DRAM_BASE ULL(0x80000000) +#define TEGRA_DRAM_END ULL(0x27FFFFFFF) + #endif /* TEGRA_DEF_H */ diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index df1d656305..a58ae9d931 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -257,6 +257,12 @@ #define TEGRA_GPCDMA_RST_CLR_REG_OFFSET U(0x6A0008) /******************************************************************************* + * Tegra DRAM memory base address + ******************************************************************************/ +#define TEGRA_DRAM_BASE ULL(0x80000000) +#define TEGRA_DRAM_END ULL(0xFFFFFFFFF) + +/******************************************************************************* * XUSB STREAMIDs ******************************************************************************/ #define TEGRA_SID_XUSB_HOST U(0x1b) diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index bbcfdc5c12..4a39aa1fb1 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -268,4 +269,10 @@ #define TEGRA_TZRAM_CARVEOUT_BASE U(0x7C04C000) #define TEGRA_TZRAM_CARVEOUT_SIZE U(0x4000) +/******************************************************************************* + * Tegra DRAM memory base address + ******************************************************************************/ +#define TEGRA_DRAM_BASE ULL(0x80000000) +#define TEGRA_DRAM_END ULL(0x27FFFFFFF) + #endif /* TEGRA_DEF_H */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index 761acdea5e..b419d94e5a 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,12 +19,6 @@ #include <tegra_gic.h> /******************************************************************************* - * Tegra DRAM memory base address - ******************************************************************************/ -#define TEGRA_DRAM_BASE ULL(0x80000000) -#define TEGRA_DRAM_END ULL(0x27FFFFFFF) - -/******************************************************************************* * Implementation defined ACTLR_EL1 bit definitions ******************************************************************************/ #define ACTLR_EL1_PMSTATE_MASK (ULL(0xF) << 0) @@ -106,6 +101,7 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr); int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state); int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state); int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state); +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state); int32_t tegra_soc_prepare_system_reset(void); __dead2 void tegra_soc_prepare_system_off(void); plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c index bd3f46fcca..0e2edf0969 100644 --- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -35,6 +36,30 @@ static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER]; +plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, + const plat_local_state_t *states, + uint32_t ncpu) +{ + plat_local_state_t target = PLAT_MAX_OFF_STATE, temp; + uint32_t num_cpu = ncpu; + const plat_local_state_t *local_state = states; + + (void)lvl; + + assert(ncpu != 0U); + + do { + temp = *local_state; + if ((temp < target)) { + target = temp; + } + --num_cpu; + local_state++; + } while (num_cpu != 0U); + + return target; +} + int32_t tegra_soc_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { @@ -112,6 +137,12 @@ int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) return PSCI_E_SUCCESS; } +int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) +{ + (void)cpu_state; + return PSCI_E_SUCCESS; +} + int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { uint64_t val; @@ -139,6 +170,16 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) return PSCI_E_SUCCESS; } +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) +{ + return PSCI_E_SUCCESS; +} + int tegra_soc_prepare_system_reset(void) { /* @@ -152,5 +193,16 @@ int tegra_soc_prepare_system_reset(void) /* Wait 1 ms to make sure clock source/device logic is stabilized. */ mdelay(1); + /* + * Program the PMC in order to restart the system. + */ + tegra_pmc_system_reset(); + return PSCI_E_SUCCESS; } + +__dead2 void tegra_soc_prepare_system_off(void) +{ + ERROR("Tegra System Off: operation not handled.\n"); + panic(); +} diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c index df62678970..2f54dd5253 100644 --- a/plat/nvidia/tegra/soc/t132/plat_setup.c +++ b/plat/nvidia/tegra/soc/t132/plat_setup.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -121,3 +122,35 @@ void plat_gic_setup(void) tegra_gic_setup(NULL, 0); tegra_gic_init(); } + +/******************************************************************************* + * Return pointer to the BL31 params from previous bootloader + ******************************************************************************/ +struct tegra_bl31_params *plat_get_bl31_params(void) +{ + return NULL; +} + +/******************************************************************************* + * Return pointer to the BL31 platform params from previous bootloader + ******************************************************************************/ +plat_params_from_bl2_t *plat_get_bl31_plat_params(void) +{ + return NULL; +} + +/******************************************************************************* + * Handler for early platform setup + ******************************************************************************/ +void plat_early_platform_setup(void) +{ + ; /* do nothing */ +} + +/******************************************************************************* + * Handler for late platform setup + ******************************************************************************/ +void plat_late_platform_setup(void) +{ + ; /* do nothing */ +} diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk index bb7b7ee661..183e1889cc 100644 --- a/plat/nvidia/tegra/soc/t132/platform_t132.mk +++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -23,6 +24,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ + ${COMMON_DIR}/drivers/pmc/pmc.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_sip_calls.c \ ${SOC_DIR}/plat_setup.c \ diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index df943969e2..4ca5e77ad8 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -95,71 +95,71 @@ const static uint32_t tegra186_streamid_override_regs[] = { ******************************************************************************/ const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = { mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(GPUSWR2, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(GPUSRD, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(ISPWA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(ISPRA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 11394c0ce4..2000e53fd6 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -83,6 +84,12 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state, return ret; } +int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) +{ + (void)cpu_state; + return PSCI_E_SUCCESS; +} + int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { const plat_local_state_t *pwr_domain_state; @@ -289,6 +296,11 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta return PSCI_E_SUCCESS; } +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) { int32_t ret = PSCI_E_SUCCESS; diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 1018caa946..7e18b5c421 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -193,6 +194,14 @@ void plat_early_platform_setup(void) } } +/******************************************************************************* + * Handler for late platform setup + ******************************************************************************/ +void plat_late_platform_setup(void) +{ + ; /* do nothing */ +} + /* Secure IRQs for Tegra186 */ static const interrupt_prop_t tegra186_interrupt_props[] = { INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY, diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h index ccc46655ab..9ccb823825 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h @@ -19,123 +19,124 @@ * occur when there is only new functionality. */ enum { - TEGRA_NVG_VERSION_MAJOR = 6, - TEGRA_NVG_VERSION_MINOR = 6 + TEGRA_NVG_VERSION_MAJOR = U(6), + TEGRA_NVG_VERSION_MINOR = U(6) }; typedef enum { - TEGRA_NVG_CHANNEL_VERSION = 0, - TEGRA_NVG_CHANNEL_POWER_PERF = 1, - TEGRA_NVG_CHANNEL_POWER_MODES = 2, - TEGRA_NVG_CHANNEL_WAKE_TIME = 3, - TEGRA_NVG_CHANNEL_CSTATE_INFO = 4, - TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = 5, - TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = 6, - TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = 8, - TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = 10, - TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = 11, - TEGRA_NVG_CHANNEL_NUM_CORES = 20, - TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = 21, - TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = 22, - TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = 23, - TEGRA_NVG_CHANNEL_SHUTDOWN = 42, - TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43, - TEGRA_NVG_CHANNEL_ONLINE_CORE = 44, - TEGRA_NVG_CHANNEL_CC3_CTRL = 45, - TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = 49, - TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = 50, - TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = 53, - TEGRA_NVG_CHANNEL_SECURITY_CONFIG = 54, - TEGRA_NVG_CHANNEL_DEBUG_CONFIG = 55, - TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = 56, - TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = 57, - TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = 58, - TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = 59, - TEGRA_NVG_CHANNEL_DDA_MCF_ISO = 60, - TEGRA_NVG_CHANNEL_DDA_MCF_SISO = 61, - TEGRA_NVG_CHANNEL_DDA_MCF_NISO = 62, - TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = 63, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = 64, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = 65, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = 66, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = 67, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = 68, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = 69, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = 70, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = 71, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = 72, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = 73, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = 74, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = 75, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = 76, - TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = 77, - TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = 78, - TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = 79, + TEGRA_NVG_CHANNEL_VERSION = U(0), + TEGRA_NVG_CHANNEL_POWER_PERF = U(1), + TEGRA_NVG_CHANNEL_POWER_MODES = U(2), + TEGRA_NVG_CHANNEL_WAKE_TIME = U(3), + TEGRA_NVG_CHANNEL_CSTATE_INFO = U(4), + TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = U(5), + TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = U(6), + TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = U(8), + TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = U(10), + TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = U(11), + TEGRA_NVG_CHANNEL_NUM_CORES = U(20), + TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = U(21), + TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = U(22), + TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = U(23), + TEGRA_NVG_CHANNEL_SHUTDOWN = U(42), + TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = U(43), + TEGRA_NVG_CHANNEL_ONLINE_CORE = U(44), + TEGRA_NVG_CHANNEL_CC3_CTRL = U(45), + TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = U(49), + TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = U(50), + TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = U(53), + TEGRA_NVG_CHANNEL_SECURITY_CONFIG = U(54), + TEGRA_NVG_CHANNEL_DEBUG_CONFIG = U(55), + TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = U(56), + TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = U(57), + TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = U(58), + TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = U(59), + TEGRA_NVG_CHANNEL_DDA_MCF_ISO = U(60), + TEGRA_NVG_CHANNEL_DDA_MCF_SISO = U(61), + TEGRA_NVG_CHANNEL_DDA_MCF_NISO = U(62), + TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = U(63), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = U(64), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = U(65), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = U(66), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = U(67), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = U(68), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = U(69), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = U(70), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = U(71), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = U(72), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = U(73), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = U(74), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = U(75), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = U(76), + TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = U(77), + TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = U(78), + TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = U(79), TEGRA_NVG_CHANNEL_LAST_INDEX } tegra_nvg_channel_id_t; typedef enum { - NVG_STAT_QUERY_SC7_ENTRIES = 1, - NVG_STAT_QUERY_CC6_ENTRIES = 6, - NVG_STAT_QUERY_CG7_ENTRIES = 7, - NVG_STAT_QUERY_C6_ENTRIES = 10, - NVG_STAT_QUERY_C7_ENTRIES = 14, - NVG_STAT_QUERY_SC7_RESIDENCY_SUM = 32, - NVG_STAT_QUERY_CC6_RESIDENCY_SUM = 41, - NVG_STAT_QUERY_CG7_RESIDENCY_SUM = 46, - NVG_STAT_QUERY_C6_RESIDENCY_SUM = 51, - NVG_STAT_QUERY_C7_RESIDENCY_SUM = 56, - NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = 60, - NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = 61, - NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = 62, - NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = 63, - NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = 64, - NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = 70, - NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = 71, - NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = 72, - NVG_STAT_QUERY_C6_EXIT_TIME_SUM = 73, - NVG_STAT_QUERY_C7_EXIT_TIME_SUM = 74, - NVG_STAT_QUERY_SC7_ENTRY_LAST = 80, - NVG_STAT_QUERY_CC6_ENTRY_LAST = 81, - NVG_STAT_QUERY_CG7_ENTRY_LAST = 82, - NVG_STAT_QUERY_C6_ENTRY_LAST = 83, - NVG_STAT_QUERY_C7_ENTRY_LAST = 84, - NVG_STAT_QUERY_SC7_EXIT_LAST = 90, - NVG_STAT_QUERY_CC6_EXIT_LAST = 91, - NVG_STAT_QUERY_CG7_EXIT_LAST = 92, - NVG_STAT_QUERY_C6_EXIT_LAST = 93, - NVG_STAT_QUERY_C7_EXIT_LAST = 94 + NVG_STAT_QUERY_SC7_ENTRIES = U(1), + NVG_STAT_QUERY_CC6_ENTRIES = U(6), + NVG_STAT_QUERY_CG7_ENTRIES = U(7), + NVG_STAT_QUERY_C6_ENTRIES = U(10), + NVG_STAT_QUERY_C7_ENTRIES = U(14), + NVG_STAT_QUERY_SC7_RESIDENCY_SUM = U(32), + NVG_STAT_QUERY_CC6_RESIDENCY_SUM = U(41), + NVG_STAT_QUERY_CG7_RESIDENCY_SUM = U(46), + NVG_STAT_QUERY_C6_RESIDENCY_SUM = U(51), + NVG_STAT_QUERY_C7_RESIDENCY_SUM = U(56), + NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = U(60), + NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = U(61), + NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = U(62), + NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = U(63), + NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = U(64), + NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = U(70), + NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = U(71), + NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = U(72), + NVG_STAT_QUERY_C6_EXIT_TIME_SUM = U(73), + NVG_STAT_QUERY_C7_EXIT_TIME_SUM = U(74), + NVG_STAT_QUERY_SC7_ENTRY_LAST = U(80), + NVG_STAT_QUERY_CC6_ENTRY_LAST = U(81), + NVG_STAT_QUERY_CG7_ENTRY_LAST = U(82), + NVG_STAT_QUERY_C6_ENTRY_LAST = U(83), + NVG_STAT_QUERY_C7_ENTRY_LAST = U(84), + NVG_STAT_QUERY_SC7_EXIT_LAST = U(90), + NVG_STAT_QUERY_CC6_EXIT_LAST = U(91), + NVG_STAT_QUERY_CG7_EXIT_LAST = U(92), + NVG_STAT_QUERY_C6_EXIT_LAST = U(93), + NVG_STAT_QUERY_C7_EXIT_LAST = U(94) + } tegra_nvg_stat_query_t; typedef enum { - TEGRA_NVG_CORE_C0 = 0, - TEGRA_NVG_CORE_C1 = 1, - TEGRA_NVG_CORE_C6 = 6, - TEGRA_NVG_CORE_C7 = 7, - TEGRA_NVG_CORE_WARMRSTREQ = 8 + TEGRA_NVG_CORE_C0 = U(0), + TEGRA_NVG_CORE_C1 = U(1), + TEGRA_NVG_CORE_C6 = U(6), + TEGRA_NVG_CORE_C7 = U(7), + TEGRA_NVG_CORE_WARMRSTREQ = U(8) } tegra_nvg_core_sleep_state_t; typedef enum { - TEGRA_NVG_SHUTDOWN = 0U, - TEGRA_NVG_REBOOT = 1U + TEGRA_NVG_SHUTDOWN = U(0), + TEGRA_NVG_REBOOT = U(1) } tegra_nvg_shutdown_reboot_state_t; typedef enum { - TEGRA_NVG_CLUSTER_CC0 = 0, - TEGRA_NVG_CLUSTER_AUTO_CC1 = 1, - TEGRA_NVG_CLUSTER_CC6 = 6 + TEGRA_NVG_CLUSTER_CC0 = U(0), + TEGRA_NVG_CLUSTER_AUTO_CC1 = U(1), + TEGRA_NVG_CLUSTER_CC6 = U(6) } tegra_nvg_cluster_sleep_state_t; typedef enum { - TEGRA_NVG_CG_CG0 = 0, - TEGRA_NVG_CG_CG7 = 7 + TEGRA_NVG_CG_CG0 = U(0), + TEGRA_NVG_CG_CG7 = U(7) } tegra_nvg_cluster_group_sleep_state_t; typedef enum { - TEGRA_NVG_SYSTEM_SC0 = 0, - TEGRA_NVG_SYSTEM_SC7 = 7, - TEGRA_NVG_SYSTEM_SC8 = 8 + TEGRA_NVG_SYSTEM_SC0 = U(0), + TEGRA_NVG_SYSTEM_SC7 = U(7), + TEGRA_NVG_SYSTEM_SC8 = U(8) } tegra_nvg_system_sleep_state_t; // --------------------------------------------------------------------------- @@ -145,95 +146,95 @@ typedef enum { typedef union { uint64_t flat; struct nvg_version_channel_t { - uint32_t minor_version : 32; - uint32_t major_version : 32; + uint32_t minor_version : U(32); + uint32_t major_version : U(32); } bits; } nvg_version_data_t; typedef union { uint64_t flat; struct nvg_power_perf_channel_t { - uint32_t perf_per_watt : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t perf_per_watt : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_power_perf_channel_t; typedef union { uint64_t flat; struct nvg_power_modes_channel_t { - uint32_t low_battery : 1; - uint32_t reserved_1_1 : 1; - uint32_t battery_save : 1; - uint32_t reserved_31_3 : 29; - uint32_t reserved_63_32 : 32; + uint32_t low_battery : U(1); + uint32_t reserved_1_1 : U(1); + uint32_t battery_save : U(1); + uint32_t reserved_31_3 : U(29); + uint32_t reserved_63_32 : U(32); } bits; } nvg_power_modes_channel_t; typedef union nvg_channel_1_data_u { uint64_t flat; struct nvg_channel_1_data_s { - uint32_t perf_per_watt_mode : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t perf_per_watt_mode : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_channel_1_data_t; typedef union { uint64_t flat; struct nvg_ccplex_cache_control_channel_t { - uint32_t gpu_ways : 5; - uint32_t reserved_7_5 : 3; - uint32_t gpu_only_ways : 5; - uint32_t reserved_31_13 : 19; - uint32_t reserved_63_32 : 32; + uint32_t gpu_ways : U(5); + uint32_t reserved_7_5 : U(3); + uint32_t gpu_only_ways : U(5); + uint32_t reserved_31_13 : U(19); + uint32_t reserved_63_32 : U(32); } bits; } nvg_ccplex_cache_control_channel_t; typedef union nvg_channel_2_data_u { uint64_t flat; struct nvg_channel_2_data_s { - uint32_t reserved_1_0 : 2; - uint32_t battery_saver_mode : 1; - uint32_t reserved_31_3 : 29; - uint32_t reserved_63_32 : 32; + uint32_t reserved_1_0 : U(2); + uint32_t battery_saver_mode : U(1); + uint32_t reserved_31_3 : U(29); + uint32_t reserved_63_32 : U(32); } bits; } nvg_channel_2_data_t; typedef union { uint64_t flat; struct nvg_wake_time_channel_t { - uint32_t wake_time : 32; - uint32_t reserved_63_32 : 32; + uint32_t wake_time : U(32); + uint32_t reserved_63_32 : U(32); } bits; } nvg_wake_time_channel_t; typedef union { uint64_t flat; struct nvg_cstate_info_channel_t { - uint32_t cluster_state : 3; - uint32_t reserved_6_3 : 4; - uint32_t update_cluster : 1; - uint32_t cg_cstate : 3; - uint32_t reserved_14_11 : 4; - uint32_t update_cg : 1; - uint32_t system_cstate : 4; - uint32_t reserved_22_20 : 3; - uint32_t update_system : 1; - uint32_t reserved_30_24 : 7; - uint32_t update_wake_mask : 1; + uint32_t cluster_state : U(3); + uint32_t reserved_6_3 : U(4); + uint32_t update_cluster : U(1); + uint32_t cg_cstate : U(3); + uint32_t reserved_14_11 : U(4); + uint32_t update_cg : U(1); + uint32_t system_cstate : U(4); + uint32_t reserved_22_20 : U(3); + uint32_t update_system : U(1); + uint32_t reserved_30_24 : U(7); + uint32_t update_wake_mask : U(1); union { - uint32_t flat : 32; + uint32_t flat : U(32); struct { - uint32_t vfiq : 1; - uint32_t virq : 1; - uint32_t fiq : 1; - uint32_t irq : 1; - uint32_t serror : 1; - uint32_t reserved_10_5 : 6; - uint32_t fiqout : 1; - uint32_t irqout : 1; - uint32_t reserved_31_13 : 19; + uint32_t vfiq : U(1); + uint32_t virq : U(1); + uint32_t fiq : U(1); + uint32_t irq : U(1); + uint32_t serror : U(1); + uint32_t reserved_10_5 : U(6); + uint32_t fiqout : U(1); + uint32_t irqout : U(1); + uint32_t reserved_31_13 : U(19); } carmel; } wake_mask; } bits; @@ -242,183 +243,182 @@ typedef union { typedef union { uint64_t flat; struct nvg_lower_bound_channel_t { - uint32_t crossover_value : 32; - uint32_t reserved_63_32 : 32; + uint32_t crossover_value : U(32); + uint32_t reserved_63_32 : U(32); } bits; } nvg_lower_bound_channel_t; typedef union { uint64_t flat; struct nvg_cstate_stat_query_channel_t { - uint32_t unit_id : 4; - uint32_t reserved_15_4 : 12; - uint32_t stat_id : 16; - uint32_t reserved_63_32 : 32; + uint32_t unit_id : U(4); + uint32_t reserved_15_4 : U(12); + uint32_t stat_id : U(16); + uint32_t reserved_63_32 : U(32); } bits; } nvg_cstate_stat_query_channel_t; typedef union { uint64_t flat; struct nvg_num_cores_channel_t { - uint32_t num_cores : 4; - uint32_t reserved_31_4 : 28; - uint32_t reserved_63_32 : 32; + uint32_t num_cores : U(4); + uint32_t reserved_31_4 : U(28); + uint32_t reserved_63_32 : U(32); } bits; } nvg_num_cores_channel_t; typedef union { uint64_t flat; struct nvg_unique_logical_id_channel_t { - uint32_t unique_core_id : 3; - uint32_t reserved_31_3 : 29; - uint32_t reserved_63_32 : 32; + uint32_t unique_core_id : U(3); + uint32_t reserved_31_3 : U(29); + uint32_t reserved_63_32 : U(32); } bits; } nvg_unique_logical_id_channel_t; typedef union { uint64_t flat; struct nvg_logical_to_physical_mappings_channel_t { - uint32_t lcore0_pcore_id : 4; - uint32_t lcore1_pcore_id : 4; - uint32_t lcore2_pcore_id : 4; - uint32_t lcore3_pcore_id : 4; - uint32_t lcore4_pcore_id : 4; - uint32_t lcore5_pcore_id : 4; - uint32_t lcore6_pcore_id : 4; - uint32_t lcore7_pcore_id : 4; - uint32_t reserved_63_32 : 32; + uint32_t lcore0_pcore_id : U(4); + uint32_t lcore1_pcore_id : U(4); + uint32_t lcore2_pcore_id : U(4); + uint32_t lcore3_pcore_id : U(4); + uint32_t lcore4_pcore_id : U(4); + uint32_t lcore5_pcore_id : U(4); + uint32_t lcore6_pcore_id : U(4); + uint32_t lcore7_pcore_id : U(4); + uint32_t reserved_63_32 : U(32); } bits; } nvg_logical_to_physical_mappings_channel_t; typedef union { uint64_t flat; struct nvg_logical_to_mpidr_channel_write_t { - uint32_t lcore_id : 3; - uint32_t reserved_31_3 : 29; - uint32_t reserved_63_32 : 32; + uint32_t lcore_id : U(3); + uint32_t reserved_31_3 : U(29); + uint32_t reserved_63_32 : U(32); } write; struct nvg_logical_to_mpidr_channel_read_t { - uint32_t mpidr : 32; - uint32_t reserved_63_32 : 32; + uint32_t mpidr : U(32); + uint32_t reserved_63_32 : U(32); } read; } nvg_logical_to_mpidr_channel_t; typedef union { uint64_t flat; struct nvg_is_sc7_allowed_channel_t { - uint32_t is_sc7_allowed : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t is_sc7_allowed : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_is_sc7_allowed_channel_t; typedef union { uint64_t flat; struct nvg_core_online_channel_t { - uint32_t core_id : 4; - uint32_t reserved_31_4 : 28; - uint32_t reserved_63_32 : 32; + uint32_t core_id : U(4); + uint32_t reserved_31_4 : U(28); + uint32_t reserved_63_32 : U(32); } bits; } nvg_core_online_channel_t; typedef union { uint64_t flat; struct nvg_cc3_control_channel_t { - uint32_t freq_req : 9; - uint32_t reserved_30_9 : 22; - uint32_t enable : 1; - uint32_t reserved_63_32 : 32; + uint32_t freq_req : U(9); + uint32_t reserved_30_9 : U(22); + uint32_t enable : U(1); + uint32_t reserved_63_32 : U(32); } bits; } nvg_cc3_control_channel_t; typedef enum { - TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = 0, - TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = 1, - TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = 2, - TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = 3, - TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = 4, - TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = 5, - TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = 6, - TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = 7, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = 8, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = 9, - TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = 10, - TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = 11, - TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = 12, - TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = 13, - TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = 14, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = 15, - TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = 16, - TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = 17, - TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = 18, - TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = 19, - TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = 20, - TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = 21, - TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = 22, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = 23, - TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = 24, - TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = 25, - TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = 26, - TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = 27, - TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = 28, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = 29, - TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = 30, - TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = 31, - TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = 32, - TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = 33, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = 34, - TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = 35, + TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = U(0), + TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = U(1), + TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = U(2), + TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = U(3), + TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = U(4), + TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = U(5), + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = U(6), + TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = U(7), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = U(8), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = U(9), + TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = U(10), + TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = U(11), + TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = U(12), + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = U(13), + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = U(14), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = U(15), + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = U(16), + TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = U(17), + TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = U(18), + TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = U(19), + TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = U(20), + TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = U(21), + TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = U(22), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = U(23), + TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = U(24), + TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = U(25), + TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = U(26), + TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = U(27), + TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = U(28), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = U(29), + TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = U(30), + TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = U(31), + TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = U(32), + TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = U(33), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = U(34), + TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = U(35), TEGRA_NVG_CHANNEL_UPDATE_GSC_LAST_INDEX } tegra_nvg_channel_update_gsc_gsc_enum_t; typedef union { uint64_t flat; struct nvg_update_ccplex_gsc_channel_t { - uint32_t gsc_enum : 16; - uint32_t reserved_31_16 : 16; - uint32_t reserved_63_32 : 32; + uint32_t gsc_enum : U(16); + uint32_t reserved_31_16 : U(16); + uint32_t reserved_63_32 : U(32); } bits; } nvg_update_ccplex_gsc_channel_t; typedef union { uint64_t flat; struct nvg_security_config_channel_t { - uint32_t strict_checking_enabled : 1; - uint32_t strict_checking_locked : 1; - uint32_t reserved_31_2 : 30; - uint32_t reserved_63_32 : 32; + uint32_t strict_checking_enabled : U(1); + uint32_t strict_checking_locked : U(1); + uint32_t reserved_31_2 : U(30); + uint32_t reserved_63_32 : U(32); } bits; } nvg_security_config_t; typedef union { uint64_t flat; struct nvg_shutdown_channel_t { - uint32_t reboot : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t reboot : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_shutdown_t; typedef union { uint64_t flat; struct nvg_debug_config_channel_t { - uint32_t enter_debug_state_on_mca : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t enter_debug_state_on_mca : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_debug_config_t; typedef union { uint64_t flat; struct nvg_hsm_error_ctrl_channel_t { - uint32_t uncorr : 1; - uint32_t corr : 1; - uint32_t reserved_31_2 : 30; - uint32_t reserved_63_32 : 32; + uint32_t uncorr : U(1); + uint32_t corr : U(1); + uint32_t reserved_31_2 : U(30); + uint32_t reserved_63_32 : U(32); } bits; } nvg_hsm_error_ctrl_channel_t; extern nvg_debug_config_t nvg_debug_config; -#endif - +#endif /* T194_NVG_H */ diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c index 1012cdf113..ef740a143a 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c @@ -15,8 +15,8 @@ #include <t194_nvg.h> #include <tegra_private.h> -#define ID_AFR0_EL1_CACHE_OPS_SHIFT 12 -#define ID_AFR0_EL1_CACHE_OPS_MASK 0xFU +#define ID_AFR0_EL1_CACHE_OPS_SHIFT U(12) +#define ID_AFR0_EL1_CACHE_OPS_MASK U(0xF) /* * Reports the major and minor version of this interface. * @@ -209,7 +209,7 @@ void nvg_enable_strict_checking_mode(void) uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET | STRICT_CHECKING_LOCKED_SET); - nvg_set_request_data(TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params); + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params); } #endif @@ -221,7 +221,8 @@ void nvg_enable_strict_checking_mode(void) void nvg_system_reboot(void) { /* issue command for reboot */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_REBOOT); + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN, + (uint64_t)TEGRA_NVG_REBOOT); } /* @@ -232,5 +233,6 @@ void nvg_system_reboot(void) void nvg_system_shutdown(void) { /* issue command for shutdown */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_SHUTDOWN); + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN, + (uint64_t)TEGRA_NVG_SHUTDOWN); } diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c index 3a2e959d0d..a3b3389401 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c @@ -15,6 +15,7 @@ #include <drivers/delay_timer.h> #include <lib/mmio.h> #include <lib/psci/psci.h> +#include <se.h> #include <tegra_platform.h> #include "se_private.h" @@ -54,7 +55,7 @@ static bool tegra_se_is_operation_complete(void) */ do { val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS); - se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY); + se_is_busy = ((val & CTX_SAVE_AUTO_SE_BUSY) != 0U); /* sleep until SE finishes */ if (se_is_busy) { @@ -186,7 +187,8 @@ int32_t tegra_se_suspend(void) assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock before SE context save */ - tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + assert(ret == 0); /* save SE registers */ se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT); @@ -201,7 +203,8 @@ int32_t tegra_se_suspend(void) } /* Disable SE clock after SE context save */ - tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + assert(ret == 0); return ret; } @@ -211,11 +214,14 @@ int32_t tegra_se_suspend(void) */ void tegra_se_resume(void) { + int32_t ret = 0; + /* initialise communication channel with BPMP */ assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock before SE context restore */ - tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + assert(ret == 0); /* * When TZ takes over after System Resume, TZ should first reconfigure @@ -229,5 +235,6 @@ void tegra_se_resume(void) mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]); /* Disable SE clock after SE context restore */ - tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + assert(ret == 0); } diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h index a2c5d1c381..577217b8e7 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h @@ -74,12 +74,12 @@ static inline uint32_t tegra_se_read_32(uint32_t offset) { - return mmio_read_32(TEGRA_SE0_BASE + offset); + return mmio_read_32((uint32_t)(TEGRA_SE0_BASE + offset)); } static inline void tegra_se_write_32(uint32_t offset, uint32_t val) { - mmio_write_32(TEGRA_SE0_BASE + offset, val); + mmio_write_32((uint32_t)(TEGRA_SE0_BASE + offset), val); } #endif /* SE_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index cc8be128a7..144e41885d 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -44,14 +44,6 @@ static struct t19x_psci_percpu_data { uint32_t wake_time; } __aligned(CACHE_WRITEBACK_GRANULE) t19x_percpu_data[PLATFORM_CORE_COUNT]; -/* - * tegra_fake_system_suspend acts as a boolean var controlling whether - * we are going to take fake system suspend code or normal system suspend code - * path. This variable is set inside the sip call handlers, when the kernel - * requests an SIP call to set the suspend debug flags. - */ -bool tegra_fake_system_suspend; - int32_t tegra_soc_validate_power_state(uint32_t power_state, psci_power_state_t *req_state) { @@ -171,30 +163,27 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) assert(ret == 0); } - if (!tegra_fake_system_suspend) { - - /* Prepare for system suspend */ - mce_update_cstate_info(&sc7_cstate_info); + /* Prepare for system suspend */ + mce_update_cstate_info(&sc7_cstate_info); - do { - val = (uint32_t)mce_command_handler( - (uint32_t)MCE_CMD_IS_SC7_ALLOWED, - (uint32_t)TEGRA_NVG_CORE_C7, - MCE_CORE_SLEEP_TIME_INFINITE, - 0U); - } while (val == 0U); - - /* Instruct the MCE to enter system suspend state */ - ret = mce_command_handler( - (uint64_t)MCE_CMD_ENTER_CSTATE, - (uint64_t)TEGRA_NVG_CORE_C7, + do { + val = (uint32_t)mce_command_handler( + (uint32_t)MCE_CMD_IS_SC7_ALLOWED, + (uint32_t)TEGRA_NVG_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); - assert(ret == 0); - - /* set system suspend state for house-keeping */ - tegra194_set_system_suspend_entry(); - } + } while (val == 0U); + + /* Instruct the MCE to enter system suspend state */ + ret = mce_command_handler( + (uint64_t)MCE_CMD_ENTER_CSTATE, + (uint64_t)TEGRA_NVG_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, + 0U); + assert(ret == 0); + + /* set system suspend state for house-keeping */ + tegra194_set_system_suspend_entry(); } else { ; /* do nothing */ } @@ -301,7 +290,6 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA194_STATE_ID_MASK; uint64_t val; - u_register_t ns_sctlr_el1; if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { /* @@ -313,35 +301,16 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta tegra194_get_cpu_reset_handler_size(); memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE); - - /* - * In fake suspend mode, ensure that the loopback procedure - * towards system suspend exit is started, instead of calling - * WFI. This is done by disabling both MMU's of EL1 & El3 - * and calling tegra_secure_entrypoint(). - */ - if (tegra_fake_system_suspend) { - - /* - * Disable EL1's MMU. - */ - ns_sctlr_el1 = read_sctlr_el1(); - ns_sctlr_el1 &= (~((u_register_t)SCTLR_M_BIT)); - write_sctlr_el1(ns_sctlr_el1); - - /* - * Disable MMU to power up the CPU in a "clean" - * state - */ - disable_mmu_el3(); - tegra_secure_entrypoint(); - panic(); - } } return PSCI_E_SUCCESS; } +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) { uint64_t target_cpu = mpidr & MPIDR_CPU_MASK; diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c index 8873358cd7..33694a16da 100644 --- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,12 +18,9 @@ #include <tegra_platform.h> #include <stdbool.h> -extern bool tegra_fake_system_suspend; - /******************************************************************************* * Tegra194 SiP SMCs ******************************************************************************/ -#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2FFFE03U /******************************************************************************* * This function is responsible for handling all T194 SiP calls @@ -39,25 +36,11 @@ int32_t plat_sip_handler(uint32_t smc_fid, { int32_t ret = -ENOTSUP; + (void)smc_fid; (void)x1; (void)x4; (void)cookie; (void)flags; - if (smc_fid == TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND) { - /* - * System suspend mode is set if the platform ATF is - * running on VDK and there is a debug SIP call. This mode - * ensures that the debug path is exercised, instead of - * regular code path to suit the pre-silicon platform needs. - * This includes replacing the call to WFI, with calls to - * system suspend exit procedures. - */ - if (tegra_platform_is_virt_dev_kit()) { - tegra_fake_system_suspend = true; - ret = 0; - } - } - return ret; } diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 12241c2f3f..4ef9558eec 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -184,6 +185,12 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, return target; } +int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) +{ + (void)cpu_state; + return PSCI_E_SUCCESS; +} + int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { u_register_t mpidr = read_mpidr(); @@ -412,6 +419,11 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) return PSCI_E_SUCCESS; } +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) { const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); @@ -567,5 +579,16 @@ int tegra_soc_prepare_system_reset(void) /* Wait 1 ms to make sure clock source/device logic is stabilized. */ mdelay(1); + /* + * Program the PMC in order to restart the system. + */ + tegra_pmc_system_reset(); + return PSCI_E_SUCCESS; } + +__dead2 void tegra_soc_prepare_system_off(void) +{ + ERROR("Tegra System Off: operation not handled.\n"); + panic(); +} diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index bfa818419f..da1f1b33eb 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -141,6 +142,22 @@ void plat_enable_console(int32_t id) } /******************************************************************************* + * Return pointer to the BL31 params from previous bootloader + ******************************************************************************/ +struct tegra_bl31_params *plat_get_bl31_params(void) +{ + return NULL; +} + +/******************************************************************************* + * Return pointer to the BL31 platform params from previous bootloader + ******************************************************************************/ +plat_params_from_bl2_t *plat_get_bl31_plat_params(void) +{ + return NULL; +} + +/******************************************************************************* * Handler for early platform setup ******************************************************************************/ void plat_early_platform_setup(void) @@ -168,6 +185,9 @@ static const interrupt_prop_t tegra210_interrupt_props[] = { GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), }; +/******************************************************************************* + * Handler for late platform setup + ******************************************************************************/ void plat_late_platform_setup(void) { const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index a11aef4dd2..4f2db53864 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -33,6 +34,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ ${COMMON_DIR}/drivers/bpmp/bpmp.c \ ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ + ${COMMON_DIR}/drivers/pmc/pmc.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_setup.c \ ${SOC_DIR}/drivers/se/security_engine.c \ diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index b95bf5a519..bc10569ba7 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -15,6 +15,7 @@ ifeq (${ARM_ARCH_MAJOR},7) MARCH32_DIRECTIVE := -mcpu=cortex-a15 $(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)) $(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER)) +$(eval $(call add_define,ARMV7_SUPPORTS_VFP)) # Qemu expects a BL32 boot stage. NEED_BL32 := yes endif # ARMv7 diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index 7158bfaf3d..b87ac3fd6b 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.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 */ @@ -80,7 +80,6 @@ #define DRAMINFO_BASE 0x2E00FFC0 #define PLAT_SQ_MHU_BASE 0x45000000 -#define PLAT_MHUV2_BASE 0xFFFFFFFF /* MHUV2 is not supported */ #define PLAT_SQ_SCP_COM_SHARED_MEM_BASE 0x45400000 #define SCPI_CMD_GET_DRAMINFO 0x1 diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index a3a9f43165..45b2803704 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -165,7 +165,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, { uint32_t result[4] = {0}; - pm_get_callbackdata(result, sizeof(result)); + pm_get_callbackdata(result, ARRAY_SIZE(result)); SMC_RET2(handle, (uint64_t)result[0] | ((uint64_t)result[1] << 32), (uint64_t)result[2] | ((uint64_t)result[3] << 32)); diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 98dbe7d6e8..3f4f0691e5 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -423,7 +423,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, { uint32_t result[4] = {0}; - pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t))); + pm_get_callbackdata(result, ARRAY_SIZE(result)); SMC_RET2(handle, (uint64_t)result[0] | ((uint64_t)result[1] << 32), (uint64_t)result[2] | ((uint64_t)result[3] << 32)); diff --git a/tools/sptool/sptool.c b/tools/sptool/sptool.c index a33b664461..38baa2cd99 100644 --- a/tools/sptool/sptool.c +++ b/tools/sptool/sptool.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <stdarg.h> +#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -16,25 +17,26 @@ #define PAGE_SIZE 4096 /* - * Linked list of entries describing entries in the secure - * partition package. + * Entry describing Secure Partition package. */ -struct sp_entry_info { +struct sp_pkg_info { /* Location of the files in the host's RAM. */ - void *sp_data, *rd_data; + void *img_data, *pm_data; /* Size of the files. */ - uint64_t sp_size, rd_size; + uint32_t img_size, pm_size; /* Location of the binary files inside the package output file */ - uint64_t sp_offset, rd_offset; - - struct sp_entry_info *next; + uint32_t img_offset, pm_offset; }; -static struct sp_entry_info *sp_info_head; - -static uint64_t sp_count; +/* + * List of input provided by user + */ +struct arg_list { + char *usr_input; + struct arg_list *next; +}; /* Align an address to a power-of-two boundary. */ static unsigned int align_to(unsigned int address, unsigned int boundary) @@ -89,26 +91,61 @@ static void xfseek(FILE *fp, long offset, int whence) } } -static void cleanup(void) +/* + * Free SP package structure + */ +static void cleanup(struct sp_pkg_info *sp) { - struct sp_entry_info *sp = sp_info_head; - while (sp != NULL) { - struct sp_entry_info *next = sp->next; - - if (sp->sp_data != NULL) - free(sp->sp_data); + if (sp != NULL) { + if (sp->img_data != NULL) { + free(sp->img_data); + } - if (sp->rd_data != NULL) - free(sp->rd_data); + if (sp->pm_data != NULL) { + free(sp->pm_data); + } free(sp); - sp = next; } +} - sp_count = 0; - sp_info_head = NULL; +/* + * Free argument list structure + */ +static void freelist(struct arg_list *head) +{ + struct arg_list *tmp; + + while (head != NULL) { + tmp = head; + head = head->next; + free(tmp); + } +} + +/* + * Append user inputs in argument list structure + */ +static void append_user_input(struct arg_list **head, char *args) +{ + struct arg_list *tmp = *head; + + if (tmp == NULL) { + tmp = xzalloc(sizeof(struct arg_list), + "Failed to allocate arg_list struct"); + tmp->usr_input = args; + *head = tmp; + } else { + while (tmp->next != NULL) { + tmp = tmp->next; + } + tmp->next = xzalloc(sizeof(struct arg_list), + "Failed to allocate arg_list struct"); + tmp = tmp->next; + tmp->usr_input = args; + } } /* @@ -116,7 +153,7 @@ static void cleanup(void) * load the file into it. Fill 'size' with the file size. Exit the program on * error. */ -static void load_file(const char *path, void **ptr, uint64_t *size) +static void load_file(const char *path, void **ptr, uint32_t *size) { FILE *f = fopen(path, "rb"); if (f == NULL) { @@ -147,59 +184,40 @@ static void load_file(const char *path, void **ptr, uint64_t *size) fclose(f); } -static void load_sp_rd(char *path) +/* + * Parse the string containing input payloads and fill in the + * SP Package data structure. + */ +static void load_sp_pm(char *path, struct sp_pkg_info **sp_out) { + struct sp_pkg_info *sp_pkg; + char *split_mark = strstr(path, ":"); *split_mark = '\0'; char *sp_path = path; - char *rd_path = split_mark + 1; - - struct sp_entry_info *sp; - - if (sp_info_head == NULL) { - sp_info_head = xzalloc(sizeof(struct sp_entry_info), - "Failed to allocate sp_entry_info struct"); - - sp = sp_info_head; - } else { - sp = sp_info_head; - - while (sp->next != NULL) { - sp = sp->next; - } - - sp->next = xzalloc(sizeof(struct sp_entry_info), - "Failed to allocate sp_entry_info struct"); + char *pm_path = split_mark + 1; - sp = sp->next; - } + sp_pkg = xzalloc(sizeof(struct sp_pkg_info), + "Failed to allocate sp_pkg_info struct"); - load_file(sp_path, &sp->sp_data, &sp->sp_size); - printf("Loaded image file %s (%lu bytes)\n", sp_path, sp->sp_size); + load_file(pm_path, &sp_pkg->pm_data, &sp_pkg->pm_size); + printf("\nLoaded SP Manifest file %s (%u bytes)\n", pm_path, sp_pkg->pm_size); - load_file(rd_path, &sp->rd_data, &sp->rd_size); - printf("Loaded RD file %s (%lu bytes)\n", rd_path, sp->rd_size); + load_file(sp_path, &sp_pkg->img_data, &sp_pkg->img_size); + printf("Loaded SP Image file %s (%u bytes)\n", sp_path, sp_pkg->img_size); - sp_count++; + *sp_out = sp_pkg; } -static void output_write(const char *path) +/* + * Write SP package data structure into output file. + */ +static void output_write(const char *path, struct sp_pkg_info *sp, bool header) { - struct sp_entry_info *sp; - - if (sp_count == 0) { - fprintf(stderr, "error: At least one SP must be provided.\n"); - exit(1); - } - - /* The layout of the structs is specified in the header file sptool.h */ - - printf("Writing %lu partitions to output file.\n", sp_count); - - unsigned int header_size = (sizeof(struct sp_pkg_header) * 8) - + (sizeof(struct sp_pkg_entry) * 8 * sp_count); + struct sp_pkg_header sp_header_info; + unsigned int file_ptr = 0; FILE *f = fopen(path, "wb"); if (f == NULL) { @@ -207,70 +225,46 @@ static void output_write(const char *path) exit(1); } - unsigned int file_ptr = align_to(header_size, PAGE_SIZE); - - /* First, save all partition images aligned to page boundaries */ - - sp = sp_info_head; - - for (uint64_t i = 0; i < sp_count; i++) { - xfseek(f, file_ptr, SEEK_SET); - - printf("Writing image %lu to offset 0x%x (0x%lx bytes)\n", - i, file_ptr, sp->sp_size); - - sp->sp_offset = file_ptr; - xfwrite(sp->sp_data, sp->sp_size, f); - file_ptr = align_to(file_ptr + sp->sp_size, PAGE_SIZE); - sp = sp->next; + /* Reserve Header size */ + if (header) { + file_ptr = sizeof(struct sp_pkg_header); } - /* Now, save resource description blobs aligned to 8 bytes */ + /* Save partition manifest */ + xfseek(f, file_ptr, SEEK_SET); + printf("Writing SP Manifest at offset 0x%x (%u bytes)\n", + file_ptr, sp->pm_size); - sp = sp_info_head; - - for (uint64_t i = 0; i < sp_count; i++) { - xfseek(f, file_ptr, SEEK_SET); - - printf("Writing RD blob %lu to offset 0x%x (0x%lx bytes)\n", - i, file_ptr, sp->rd_size); - - sp->rd_offset = file_ptr; - xfwrite(sp->rd_data, sp->rd_size, f); - file_ptr = align_to(file_ptr + sp->rd_size, 8); - sp = sp->next; - } + sp->pm_offset = file_ptr; + xfwrite(sp->pm_data, sp->pm_size, f); - /* Finally, write header */ + /* Save partition image aligned to Page size */ + file_ptr = align_to((sp->pm_offset + sp->pm_size), PAGE_SIZE); + xfseek(f, file_ptr, SEEK_SET); + printf("Writing SP Image at offset 0x%x (%u bytes)\n", + file_ptr, sp->img_size); - uint64_t version = 0x1; - uint64_t sp_num = sp_count; + sp->img_offset = file_ptr; + xfwrite(sp->img_data, sp->img_size, f); - xfseek(f, 0, SEEK_SET); + /* Finally, write header, if needed */ + if (header) { + sp_header_info.magic = SECURE_PARTITION_MAGIC; + sp_header_info.version = 0x1; + sp_header_info.img_offset = sp->img_offset; + sp_header_info.img_size = sp->img_size; + sp_header_info.pm_offset = sp->pm_offset; + sp_header_info.pm_size = sp->pm_size; - xfwrite(&version, sizeof(uint64_t), f); - xfwrite(&sp_num, sizeof(uint64_t), f); + xfseek(f, 0, SEEK_SET); - sp = sp_info_head; + printf("Writing package header\n"); - for (unsigned int i = 0; i < sp_count; i++) { - - uint64_t sp_offset, sp_size, rd_offset, rd_size; - - sp_offset = sp->sp_offset; - sp_size = align_to(sp->sp_size, PAGE_SIZE); - rd_offset = sp->rd_offset; - rd_size = sp->rd_size; - - xfwrite(&sp_offset, sizeof(uint64_t), f); - xfwrite(&sp_size, sizeof(uint64_t), f); - xfwrite(&rd_offset, sizeof(uint64_t), f); - xfwrite(&rd_size, sizeof(uint64_t), f); - - sp = sp->next; + xfwrite(&sp_header_info, sizeof(struct sp_pkg_header), f); } /* All information has been written now */ + printf("\nsptool: Built Secure Partition blob %s\n", path); fclose(f); } @@ -286,30 +280,51 @@ static void usage(void) #endif printf(" [<args>]\n\n"); - printf("This tool takes as inputs several image binary files and the\n" - "resource description blobs as input and generates a package\n" - "file that contains them.\n\n"); + printf("This tool takes as input set of image binary files and the\n" + "partition manifest blobs as input and generates set of\n" + "output package files\n" + "Usage example: sptool -i sp1.bin:sp1.dtb -o sp1.pkg\n" + " -i sp2.bin:sp2.dtb -o sp2.pkg ...\n\n"); printf("Commands supported:\n"); printf(" -o <path> Set output file path.\n"); - printf(" -i <sp_path:rd_path> Add Secure Partition image and Resource\n" - " Description blob (specified in two paths\n" + printf(" -i <sp_path:pm_path> Add Secure Partition image and\n" + " Manifest blob (specified in two paths\n" " separated by a colon).\n"); + printf(" -n Generate package without header\n"); printf(" -h Show this message.\n"); exit(1); } int main(int argc, char *argv[]) { + struct sp_pkg_info *sp_pkg = NULL; + struct arg_list *in_head = NULL; + struct arg_list *out_head = NULL; + struct arg_list *in_list = NULL; + struct arg_list *out_list = NULL; + unsigned int match_counter = 0; + bool need_header = true; + int ch; - const char *outname = NULL; - while ((ch = getopt(argc, argv, "hi:o:")) != -1) { + if (argc <= 1) { + fprintf(stderr, "error: File paths must be provided.\n\n"); + usage(); + return 1; + } + + while ((ch = getopt(argc, argv, "hni:o:")) != -1) { switch (ch) { case 'i': - load_sp_rd(optarg); + append_user_input(&in_head, optarg); + match_counter++; break; case 'o': - outname = optarg; + append_user_input(&out_head, optarg); + match_counter--; + break; + case 'n': + need_header = false; break; case 'h': default: @@ -317,18 +332,29 @@ int main(int argc, char *argv[]) } } - argc -= optind; - argv += optind; - - if (outname == NULL) { - fprintf(stderr, "error: An output file path must be provided.\n\n"); + if (match_counter) { + fprintf(stderr, "error: Input/Output count mismatch.\n\n"); + freelist(in_head); + freelist(out_head); usage(); return 1; } - output_write(outname); + in_list = in_head; + out_list = out_head; + while (in_list != NULL) { + load_sp_pm(in_list->usr_input, &sp_pkg); + output_write(out_list->usr_input, sp_pkg, need_header); + in_list = in_list->next; + out_list = out_list->next; + } + + argc -= optind; + argv += optind; - cleanup(); + cleanup(sp_pkg); + freelist(in_head); + freelist(out_head); return 0; } |