Merge changes from topic "arm_fpga_resmem" into integration
* changes:
fix(arm_fpga): reserve BL31 memory
fix(arm_fpga): limit BL31 memory usage
diff --git a/Makefile b/Makefile
index b4bebf1..59d14ba 100644
--- a/Makefile
+++ b/Makefile
@@ -525,6 +525,14 @@
ifeq ($(TS_SP_FW_CONFIG),1)
DTC_CPPFLAGS += -DTS_SP_FW_CONFIG
endif
+
+ ifneq ($(ARM_BL2_SP_LIST_DTS),)
+ DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS)
+ endif
+
+ ifneq ($(SP_LAYOUT_FILE),)
+ BL2_ENABLE_SP_LOAD := 1
+ endif
else
# All other SPDs in spd directory
SPD_DIR := spd
@@ -898,6 +906,7 @@
$(eval $(call assert_booleans,\
$(sort \
ALLOW_RO_XLAT_TABLES \
+ BL2_ENABLE_SP_LOAD \
COLD_BOOT_SINGLE_CPU \
CREATE_KEYS \
CTX_INCLUDE_AARCH32_REGS \
@@ -964,6 +973,10 @@
ENABLE_FEAT_RNG \
ENABLE_FEAT_SB \
PSA_FWU_SUPPORT \
+ ENABLE_TRBE_FOR_NS \
+ ENABLE_SYS_REG_TRACE_FOR_NS \
+ ENABLE_TRF_FOR_NS \
+ ENABLE_FEAT_HCX \
)))
$(eval $(call assert_numerics,\
@@ -995,6 +1008,7 @@
ALLOW_RO_XLAT_TABLES \
ARM_ARCH_MAJOR \
ARM_ARCH_MINOR \
+ BL2_ENABLE_SP_LOAD \
COLD_BOOT_SINGLE_CPU \
CTX_INCLUDE_AARCH32_REGS \
CTX_INCLUDE_FPREGS \
@@ -1064,6 +1078,10 @@
NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \
PSA_FWU_SUPPORT \
+ ENABLE_TRBE_FOR_NS \
+ ENABLE_SYS_REG_TRACE_FOR_NS \
+ ENABLE_TRF_FOR_NS \
+ ENABLE_FEAT_HCX \
)))
ifeq (${SANITIZE_UB},trap)
@@ -1093,9 +1111,6 @@
# Generate and include sp_gen.mk if SPD is spmd and SP_LAYOUT_FILE is defined
ifeq (${SPD},spmd)
ifdef SP_LAYOUT_FILE
- ifeq (${SPMD_SPM_AT_SEL2},0)
- $(error "SPMD with SPM at S-EL1 does not require SP_LAYOUT_FILE")
- endif
-include $(BUILD_PLAT)/sp_gen.mk
FIP_DEPS += sp
CRT_DEPS += sp
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index d11b4ab..8f44151 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -1,15 +1,17 @@
#
-# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-BL1_SOURCES += bl1/bl1_main.c \
- bl1/${ARCH}/bl1_arch_setup.c \
+ifneq (${PLAT},fvp_r)
+BL1_SOURCES += bl1/${ARCH}/bl1_arch_setup.c \
bl1/${ARCH}/bl1_context_mgmt.c \
bl1/${ARCH}/bl1_entrypoint.S \
bl1/${ARCH}/bl1_exceptions.S \
- lib/cpus/${ARCH}/cpu_helpers.S \
+ bl1/bl1_main.c
+endif
+BL1_SOURCES += lib/cpus/${ARCH}/cpu_helpers.S \
lib/cpus/errata_report.c \
lib/el3_runtime/${ARCH}/context_mgmt.c \
plat/common/plat_bl1_common.c \
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 1fdf545..7819141 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -90,6 +90,18 @@
BL31_SOURCES += lib/extensions/mpam/mpam.c
endif
+ifeq (${ENABLE_TRBE_FOR_NS},1)
+BL31_SOURCES += lib/extensions/trbe/trbe.c
+endif
+
+ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
+BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
+endif
+
+ifeq (${ENABLE_TRF_FOR_NS},1)
+BL31_SOURCES += lib/extensions/trf/aarch64/trf.c
+endif
+
ifeq (${WORKAROUND_CVE_2017_5715},1)
BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \
lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 44bf32c..f272af5 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -85,6 +85,15 @@
/* Perform late platform-specific setup */
bl31_plat_arch_setup();
+#if ENABLE_FEAT_HCX
+ /*
+ * Assert that FEAT_HCX is supported on this system, without this check
+ * an exception would occur during context save/restore if enabled but
+ * not supported.
+ */
+ assert(is_feat_hcx_present());
+#endif /* ENABLE_FEAT_HCX */
+
#if CTX_INCLUDE_PAUTH_REGS
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 8b5eddd..6339cf8 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -42,6 +42,14 @@
services/std_svc/trng/trng_entropy_pool.c
endif
+ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
+BL32_SOURCES += lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
+endif
+
+ifeq (${ENABLE_TRF_FOR_NS},1)
+BL32_SOURCES += lib/extensions/trf/aarch32/trf.c
+endif
+
BL32_LINKERFILE := bl32/sp_min/sp_min.ld.S
# Include the platform-specific SP_MIN Makefile
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 07f258c..1bd4666 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -535,7 +535,10 @@
^^^^^^^^^^^^^^^^^
:|M|: Saurabh Gorecha <sgorecha@codeaurora.org>
:|G|: `sgorecha`_
-:|M|: Debasish Mandal <dmandal@codeaurora.org>
+:|M|: Lachit Patel <lpatel@codeaurora.org>
+:|G|: `lachitp`_
+:|M|: Sreevyshanavi Kare <skare@codeaurora.org>
+:|G|: `sreekare`_
:|M|: QTI TF Maintainers <qti.trustedfirmware.maintainers@codeaurora.org>
:|F|: docs/plat/qti.rst
:|F|: plat/qti/
@@ -732,6 +735,7 @@
.. _jenswi-linaro: https://github.com/jenswi-linaro
.. _jwerner-chromium: https://github.com/jwerner-chromium
.. _kostapr: https://github.com/kostapr
+.. _lachitp: https://github.com/lachitp
.. _ldts: https://github.com/ldts
.. _marex: https://github.com/marex
.. _masahir0y: https://github.com/masahir0y
@@ -750,6 +754,7 @@
.. _shawnguo2: https://github.com/shawnguo2
.. _smaeul: https://github.com/smaeul
.. _soby-mathew: https://github.com/soby-mathew
+.. _sreekare: https://github.com/sreekare
.. _thloh85-intel: https://github.com/thloh85-intel
.. _thomas-arm: https://github.com/thomas-arm
.. _TonyXie06: https://github.com/TonyXie06
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index 437df67..df2985c 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -110,10 +110,13 @@
- Specifies which messaging methods are supported by the partition, set bit
means the feature is supported, clear bit - not supported:
- - Bit[0]: support for receiving direct message requests
- - Bit[1]: support for sending direct messages
- - Bit[2]: support for indirect messaging
- - Bit[3]: support for managed exit
+ - Bit[0]: partition can receive direct requests if set
+ - Bit[1]: partition can send direct requests if set
+ - Bit[2]: partition can send and receive indirect messages
+
+- managed-exit
+ - value type: <empty>
+ - Specifies if managed exit is supported.
- has-primary-scheduler
- value type: <empty>
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index a5e7e8e..fa51fe0 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -6,59 +6,59 @@
Acronyms
========
-+--------+-----------------------------------+
-| CoT | Chain of Trust |
-+--------+-----------------------------------+
-| DMA | Direct Memory Access |
-+--------+-----------------------------------+
-| DTB | Device Tree Blob |
-+--------+-----------------------------------+
-| DTS | Device Tree Source |
-+--------+-----------------------------------+
-| EC | Execution Context |
-+--------+-----------------------------------+
-| FIP | Firmware Image Package |
-+--------+-----------------------------------+
-| FF-A | Firmware Framework for Armv8-A |
-+--------+-----------------------------------+
-| IPA | Intermediate Physical Address |
-+--------+-----------------------------------+
-| NWd | Normal World |
-+--------+-----------------------------------+
-| ODM | Original Design Manufacturer |
-+--------+-----------------------------------+
-| OEM | Original Equipment Manufacturer |
-+--------+-----------------------------------+
-| PA | Physical Address |
-+--------+-----------------------------------+
-| PE | Processing Element |
-+--------+-----------------------------------+
-| PM | Power Management |
-+--------+-----------------------------------+
-| PVM | Primary VM |
-+--------+-----------------------------------+
-| SMMU | System Memory Management Unit |
-+--------+-----------------------------------+
-| SP | Secure Partition |
-+--------+-----------------------------------+
-| SPD | Secure Payload Dispatcher |
-+--------+-----------------------------------+
-| SPM | Secure Partition Manager |
-+--------+-----------------------------------+
-| SPMC | SPM Core |
-+--------+-----------------------------------+
-| SPMD | SPM Dispatcher |
-+--------+-----------------------------------+
-| SiP | Silicon Provider |
-+--------+-----------------------------------+
-| SWd | Secure World |
-+--------+-----------------------------------+
-| TLV | Tag-Length-Value |
-+--------+-----------------------------------+
-| TOS | Trusted Operating System |
-+--------+-----------------------------------+
-| VM | Virtual Machine |
-+--------+-----------------------------------+
++--------+--------------------------------------+
+| CoT | Chain of Trust |
++--------+--------------------------------------+
+| DMA | Direct Memory Access |
++--------+--------------------------------------+
+| DTB | Device Tree Blob |
++--------+--------------------------------------+
+| DTS | Device Tree Source |
++--------+--------------------------------------+
+| EC | Execution Context |
++--------+--------------------------------------+
+| FIP | Firmware Image Package |
++--------+--------------------------------------+
+| FF-A | Firmware Framework for Arm A-profile |
++--------+--------------------------------------+
+| IPA | Intermediate Physical Address |
++--------+--------------------------------------+
+| NWd | Normal World |
++--------+--------------------------------------+
+| ODM | Original Design Manufacturer |
++--------+--------------------------------------+
+| OEM | Original Equipment Manufacturer |
++--------+--------------------------------------+
+| PA | Physical Address |
++--------+--------------------------------------+
+| PE | Processing Element |
++--------+--------------------------------------+
+| PM | Power Management |
++--------+--------------------------------------+
+| PVM | Primary VM |
++--------+--------------------------------------+
+| SMMU | System Memory Management Unit |
++--------+--------------------------------------+
+| SP | Secure Partition |
++--------+--------------------------------------+
+| SPD | Secure Payload Dispatcher |
++--------+--------------------------------------+
+| SPM | Secure Partition Manager |
++--------+--------------------------------------+
+| SPMC | SPM Core |
++--------+--------------------------------------+
+| SPMD | SPM Dispatcher |
++--------+--------------------------------------+
+| SiP | Silicon Provider |
++--------+--------------------------------------+
+| SWd | Secure World |
++--------+--------------------------------------+
+| TLV | Tag-Length-Value |
++--------+--------------------------------------+
+| TOS | Trusted Operating System |
++--------+--------------------------------------+
+| VM | Virtual Machine |
++--------+--------------------------------------+
Foreword
========
@@ -414,13 +414,17 @@
The SPMC is loaded by BL2 as the BL32 image.
-The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image.
+The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image `[9]`_.
BL2 passes the SPMC manifest address to BL31 through a register.
At boot time, the SPMD in BL31 runs from the primary core, initializes the core
-contexts and launches the SPMC (BL32) passing the SPMC manifest address through
-a register.
+contexts and launches the SPMC (BL32) passing the following information through
+registers:
+
+- X0 holds the ``TOS_FW_CONFIG`` physical address (or SPMC manifest blob).
+- X1 holds the ``HW_CONFIG`` physical address.
+- X4 holds the currently running core linear id.
Loading of SPs
~~~~~~~~~~~~~~
@@ -920,7 +924,7 @@
.. _[1]:
-[1] `Arm Firmware Framework for Armv8-A <https://developer.arm.com/docs/den0077/latest>`__
+[1] `Arm Firmware Framework for Arm A-profile <https://developer.arm.com/docs/den0077/latest>`__
.. _[2]:
@@ -951,6 +955,10 @@
[8] https://lists.trustedfirmware.org/pipermail/tf-a/2020-February/000296.html
+.. _[9]:
+
+[9] https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#dynamic-configuration-during-cold-boot
+
--------------
*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/xlat-tables-lib-v2-design.rst b/docs/components/xlat-tables-lib-v2-design.rst
index af5151f..cac32f5 100644
--- a/docs/components/xlat-tables-lib-v2-design.rst
+++ b/docs/components/xlat-tables-lib-v2-design.rst
@@ -10,7 +10,7 @@
More specifically, some use cases that this library aims to support are:
#. Statically allocate translation tables and populate them (at run-time) based
- on a description of the memory layout. The memory layout is typically
+ upon a description of the memory layout. The memory layout is typically
provided by the platform port as a list of memory regions;
#. Support for generating translation tables pertaining to a different
@@ -26,22 +26,28 @@
#. Support for changing memory attributes of memory regions at run-time.
-About version 1 and version 2
------------------------------
+About version 1, version 2 and MPU libraries
+--------------------------------------------
This document focuses on version 2 of the library, whose sources are available
in the ``lib/xlat_tables_v2`` directory. Version 1 of the library can still be
found in ``lib/xlat_tables`` directory but it is less flexible and doesn't
-support dynamic mapping. Although potential bug fixes will be applied to both
-versions, future features enhancements will focus on version 2 and might not be
-back-ported to version 1. Therefore, it is recommended to use version 2,
-especially for new platform ports.
+support dynamic mapping. ``lib/xlat_mpu``, which configures Arm's MPU
+equivalently, is also addressed here. The ``lib/xlat_mpu`` is experimental,
+meaning that its API may change. It currently strives for consistency and
+code-reuse with xlat_tables_v2. Future versions may be more MPU-specific (e.g.,
+removing all mentions of virtual addresses). Although potential bug fixes will
+be applied to all versions of the xlat_* libs, future feature enhancements will
+focus on version 2 and might not be back-ported to version 1 and MPU versions.
+Therefore, it is recommended to use version 2, especially for new platform
+ports (unless the platform uses an MPU).
-However, please note that version 2 is still in active development and is not
-considered stable yet. Hence, compatibility breaks might be introduced.
+However, please note that version 2 and the MPU version are still in active
+development and is not considered stable yet. Hence, compatibility breaks might
+be introduced.
From this point onwards, this document will implicitly refer to version 2 of the
-library.
+library, unless stated otherwise.
Design concepts and interfaces
@@ -102,6 +108,16 @@
library will choose the mapping granularity for this region as it sees fit (more
details can be found in `The memory mapping algorithm`_ section below).
+The MPU library also uses ``struct mmap_region`` to specify translations, but
+the MPU's translations are limited to specification of valid addresses and
+access permissions. If the requested virtual and physical addresses mismatch
+the system will panic. Being register-based for deterministic memory-reference
+timing, the MPU hardware does not involve memory-resident translation tables.
+
+Currently, the MPU library is also limited to MPU translation at EL2 with no
+MMU translation at other ELs. These limitations, however, are expected to be
+overcome in future library versions.
+
Translation Context
~~~~~~~~~~~~~~~~~~~
@@ -215,7 +231,8 @@
The ``MAP_REGION()`` and ``MAP_REGION_FLAT()`` macros do not allow specifying a
mapping granularity, which leaves the library implementation free to choose
it. However, in cases where a specific granularity is required, the
-``MAP_REGION2()`` macro might be used instead.
+``MAP_REGION2()`` macro might be used instead. Using ``MAP_REGION_FLAT()`` only
+to define regions for the MPU library is strongly recommended.
As explained earlier in this document, when the dynamic mapping feature is
disabled, there is no notion of dynamic regions. Conceptually, there are only
@@ -374,6 +391,9 @@
refer to the comments in the source code of the core module for more details
about the sorting algorithm in use.
+This mapping algorithm does not apply to the MPU library, since the MPU hardware
+directly maps regions by "base" and "limit" (bottom and top) addresses.
+
TLB maintenance operations
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -390,6 +410,11 @@
is deferred to the ``enable_mmu*()`` family of functions, just before the MMU is
turned on.
+Regarding enabling and disabling memory management, for the MPU library, to
+reduce confusion, calls to enable or disable the MPU use ``mpu`` in their names
+in place of ``mmu``. For example, the ``enable_mmu_el2()`` call is changed to
+``enable_mpu_el2()``.
+
TLB invalidation is not required when adding dynamic regions either. Dynamic
regions are not allowed to overlap existing memory region. Therefore, if the
dynamic mapping request is deemed legitimate, it automatically concerns memory
@@ -412,6 +437,6 @@
--------------
-*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.*
.. |Alignment Example| image:: ../resources/diagrams/xlat_align.png
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index b5092c4..4230f9e 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -284,6 +284,10 @@
- ``ERRATA_A78_1952683``: This applies errata 1952683 workaround to Cortex-A78
CPU. This needs to be enabled for revision r0p0, it is fixed in r1p0.
+- ``ERRATA_A78_2132060``: This applies errata 2132060 workaround to Cortex-A78
+ CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2. It
+ is still open.
+
For Cortex-A78 AE, the following errata build flags are defined :
- ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to Cortex-A78
@@ -371,6 +375,10 @@
CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the
CPU. It is still open.
+- ``ERRATA_V1_2108267``: This applies errata 2108267 workaround to Neoverse-V1
+ CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU.
+ It is still open.
+
For Cortex-A710, the following errata build flags are defined :
- ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -381,6 +389,35 @@
Cortex-A710 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
r2p0 of the CPU. It is still open.
+- ``ERRATA_A710_2055002``: This applies errata 2055002 workaround to
+ Cortex-A710 CPU. This needs to be enabled for revisions r1p0, r2p0 of the CPU
+ and is still open.
+
+- ``ERRATA_A710_2017096``: This applies errata 2017096 workaround to
+ Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+ of the CPU and is still open.
+
+- ``ERRATA_A710_2083908``: This applies errata 2083908 workaround to
+ Cortex-A710 CPU. This needs to be enabled for revision r2p0 of the CPU and
+ is still open.
+
+For Neoverse N2, the following errata build flags are defined :
+
+- ``ERRATA_N2_2067956``: This applies errata 2067956 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+- ``ERRATA_N2_2025414``: This applies errata 2025414 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+- ``ERRATA_N2_2189731``: This applies errata 2189731 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+- ``ERRATA_N2_2138956``: This applies errata 2138956 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+- ``ERRATA_N2_2138953``: This applies errata 2138953 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
DSU Errata Workarounds
----------------------
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 901a72a..7fe6ccd 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -55,6 +55,9 @@
- ``BL2_AT_EL3``: This is an optional build option that enables the use of
BL2 at EL3 execution level.
+- ``BL2_ENABLE_SP_LOAD``: Boolean option to enable loading SP packages from the
+ FIP. Automatically enabled if ``SP_LAYOUT_FILE`` is provided.
+
- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
(XIP) memory, like BL1. In these use-cases, it is necessary to initialize
the RW sections in RAM, while leaving the RO sections in place. This option
@@ -235,6 +238,10 @@
builds, but this behaviour can be overridden in each platform's Makefile or
in the build command line.
+- ``ENABLE_FEAT_HCX``: This option sets the bit SCR_EL3.HXEn in EL3 to allow
+ access to HCRX_EL2 (extended hypervisor control register) from EL2 as well as
+ adding HCRX_EL2 to the EL2 context save/restore operations.
+
- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
support in GCC for TF-A. This option is currently only supported for
AArch64. Default is 0.
@@ -775,6 +782,21 @@
functions that wait for an arbitrary time length (udelay and mdelay). The
default value is 0.
+- ``ENABLE_TRBE_FOR_NS``: This flag is used to enable access of trace buffer
+ control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented
+ but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural
+ feature for AArch64. The default is 0 and it is automatically disabled when
+ the target architecture is AArch32.
+
+- ``ENABLE_SYS_REG_TRACE_FOR_NS``: Boolean option to enable trace system
+ registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented
+ but unused). This feature is available if trace unit such as ETMv4.x, and
+ ETE(extending ETM feature) is implemented. This flag is disabled by default.
+
+- ``ENABLE_TRF_FOR_NS``: Boolean option to enable trace filter control registers
+ access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused),
+ if FEAT_TRF is implemented. This flag is disabled by default.
+
GICv3 driver options
--------------------
@@ -790,6 +812,11 @@
GIC-600, so is safe to select even for a GIC500 implementation.
This option defaults to 0.
+- ``GICV3_SUPPORT_GIC600AE_FMU``: Add support for the Fault Management Unit
+ for GIC-600 AE. Enabling this option will introduce support to initialize
+ the FMU. Platforms should call the init function during boot to enable the
+ FMU and its safety mechanisms. This option defaults to 0.
+
- ``GICV3_IMPL_GIC600_MULTICHIP``: Selects GIC-600 variant with multichip
functionality. This option defaults to 0
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 54820e4..f4912f5 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -60,8 +60,8 @@
FDT
Flattened Device Tree
- FFA
- Firmware Framework for A-class processors
+ FF-A
+ Firmware Framework for Arm A-profile
FIP
Firmware Image Package
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index d4fa98d..339ebbe 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -100,12 +100,15 @@
- ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the
SPMC Core manifest. Valid when ``SPD=spmd`` is selected.
+- ``ARM_BL2_SP_LIST_DTS``: Path to DTS file snippet to override the hardcoded
+ SP nodes in tb_fw_config.
+
- ``OPTEE_SP_FW_CONFIG``: DTC build flag to include OP-TEE as SP in tb_fw_config
device tree. This flag is defined only when ``ARM_SPMC_MANIFEST_DTS`` manifest
file name contains pattern optee_sp.
- ``TS_SP_FW_CONFIG``: DTC build flag to include Trusted Services (Crypto and
- secure-storage) as SP in tb_fw_config device tree.
+ internal-trusted-storage) as SP in tb_fw_config device tree.
- ``ARM_GPT_SUPPORT``: Enable GPT parser to get the entry address and length of
the various partitions present in the GPT image. This support is available
diff --git a/docs/plat/arm/fvp_r/index.rst b/docs/plat/arm/fvp_r/index.rst
new file mode 100644
index 0000000..8af16ba
--- /dev/null
+++ b/docs/plat/arm/fvp_r/index.rst
@@ -0,0 +1,46 @@
+ARM V8-R64 Fixed Virtual Platform (FVP)
+=======================================
+
+Some of the features of Armv8-R AArch64 FVP platform referenced in Trusted
+Boot R-class include:
+
+- Secure World Support Only
+- EL2 as Maximum EL support (No EL3)
+- MPU Support only at EL2
+- MPU or MMU Support at EL0/EL1
+- AArch64 Support Only
+- Trusted Board Boot
+
+Further information on v8-R64 FVP is available at `info <https://developer.arm.com/documentation/ddi0600/latest/>`_
+
+Boot Sequence
+-------------
+
+BL1 –> BL33
+
+The execution begins from BL1 which loads the BL33 image, a boot-wrapped (bootloader + Operating System)
+Operating System, from FIP to DRAM.
+
+Build Procedure
+~~~~~~~~~~~~~~~
+
+- Obtain arm `toolchain <https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads>`_.
+ Set the CROSS_COMPILE environment variable to point to the toolchain folder.
+
+- Build TF-A:
+
+ .. code:: shell
+
+ make PLAT=fvp_r BL33=<path_to_os.bin> all fip
+
+ Enable TBBR by adding the following options to the make command:
+
+ .. code:: shell
+
+ MBEDTLS_DIR=<path_to_mbedtls_directory> \
+ TRUSTED_BOARD_BOOT=1 \
+ GENERATE_COT=1 \
+ ARM_ROTPK_LOCATION=devel_rsa \
+ ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst
index c834f6a..f262dc0 100644
--- a/docs/plat/arm/index.rst
+++ b/docs/plat/arm/index.rst
@@ -7,6 +7,7 @@
juno/index
fvp/index
+ fvp_r/index
fvp-ve/index
tc/index
arm_fpga/index
@@ -20,4 +21,4 @@
--------------
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 4dc9ecd..5848005 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -27,6 +27,7 @@
imx8
imx8m
ls1043a
+ nxp/index
poplar
qemu
qemu-sbsa
diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst
index 8af27b1..b125144 100644
--- a/docs/plat/marvell/armada/build.rst
+++ b/docs/plat/marvell/armada/build.rst
@@ -153,6 +153,29 @@
Armada37x0 specific build options:
+- HANDLE_EA_EL3_FIRST
+
+ When ``HANDLE_EA_EL3_FIRST=1``, External Aborts and SError Interrupts will be always trapped
+ in TF-A. TF-A in this case enables dirty hack / workaround for a bug found in U-Boot and
+ Linux kernel PCIe controller driver pci-aardvark.c, traps and then masks SError interrupt
+ caused by AXI SLVERR on external access (syndrome 0xbf000002).
+
+ Otherwise when ``HANDLE_EA_EL3_FIRST=0``, these exceptions will be trapped in the current
+ exception level (or in EL1 if the current exception level is EL0). So exceptions caused by
+ U-Boot will be trapped in U-Boot, exceptions caused by Linux kernel (or user applications)
+ will be trapped in Linux kernel.
+
+ Mentioned bug in pci-aardvark.c driver is fixed in U-Boot version v2021.07 and Linux kernel
+ version v5.13 (workarounded since Linux kernel version 5.9) and also backported in Linux
+ kernel stable releases since versions v5.12.13, v5.10.46, v5.4.128, v4.19.198, v4.14.240.
+
+ If target system has already patched version of U-Boot and Linux kernel then it is strongly
+ recommended to not enable this workaround as it disallows propagating of all External Aborts
+ to running Linux kernel and makes correctable errors as fatal aborts.
+
+ This option is now disabled by default. In past this option was enabled by default in
+ TF-A versions v2.2, v2.3, v2.4 and v2.5.
+
- CM3_SYSTEM_RESET
When ``CM3_SYSTEM_RESET=1``, the Cortex-M3 secure coprocessor will be used for system reset.
diff --git a/docs/plat/nxp/index.rst b/docs/plat/nxp/index.rst
new file mode 100644
index 0000000..8546887
--- /dev/null
+++ b/docs/plat/nxp/index.rst
@@ -0,0 +1,17 @@
+NXP Reference Development Platforms
+===================================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+
+ nxp-layerscape
+ nxp-ls-fuse-prov
+ nxp-ls-tbbr
+
+This chapter holds documentation related to NXP reference development platforms.
+It includes details on image flashing, fuse provisioning and trusted board boot-up.
+
+--------------
+
+*Copyright (c) 2021, NXP Limited. All rights reserved.*
diff --git a/docs/plat/nxp/nxp-layerscape.rst b/docs/plat/nxp/nxp-layerscape.rst
new file mode 100644
index 0000000..9a470e6
--- /dev/null
+++ b/docs/plat/nxp/nxp-layerscape.rst
@@ -0,0 +1,301 @@
+NXP SoCs - Overview
+=====================
+.. section-numbering::
+ :suffix: .
+
+The QorIQ family of ARM based SoCs that are supported on TF-A are:
+
+1. LX2160A
+
+- SoC Overview:
+
+The LX2160A multicore processor, the highest-performance member of the
+Layerscape family, combines FinFET process technology's low power and
+sixteen Arm® Cortex®-A72 cores with datapath acceleration optimized for
+L2/3 packet processing, together with security offload, robust traffic
+management and quality of service.
+
+Details about LX2160A can be found at `lx2160a`_.
+
+- LX2160ARDB Board:
+
+The LX2160A reference design board provides a comprehensive platform
+that enables design and evaluation of the LX2160A or LX2162A processors. It
+comes preloaded with a board support package (BSP) based on a standard Linux
+kernel.
+
+Board details can be fetched from the link: `lx2160ardb`_.
+
+2. LS1028A
+
+- SoC Overview:
+
+The Layerscape LS1028A applications processor for industrial and
+automotive includes a time-sensitive networking (TSN) -enabled Ethernet
+switch and Ethernet controllers to support converged IT and OT networks.
+Two powerful 64-bit Arm®v8 cores support real-time processing for
+industrial control and virtual machines for edge computing in the IoT.
+The integrated GPU and LCD controller enable Human-Machine Interface
+(HMI) systems with next-generation interfaces.
+
+Details about LS1028A can be found at `ls1028a`_.
+
+- LS1028ARDB Boards:
+
+The LS1028A reference design board (RDB) is a computing, evaluation,
+and development platform that supports industrial IoT applications, human
+machine interface solutions, and industrial networking.
+
+Details about LS1028A RDB board can be found at `ls1028ardb`_.
+
+Table of supported boot-modes by each platform & platform that needs FIP-DDR:
+-----------------------------------------------------------------------------
+
++---------------------+---------------------------------------------------------------------+-----------------+
+| | BOOT_MODE | |
+| PLAT +-------+--------+-------+-------+-------+-------------+--------------+ fip_ddr_needed |
+| | sd | qspi | nor | nand | emmc | flexspi_nor | flexspi_nand | |
++=====================+=======+========+=======+=======+=======+=============+==============+=================+
+| lx2160ardb | yes | | | | yes | yes | | yes |
++---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
+| ls1028ardb | yes | | | | yes | yes | | no |
++---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
+
+
+Boot Sequence
+-------------
+::
+
++ Secure World | Normal World
++ EL0 |
++ |
++ EL1 BL32(Tee OS) | kernel
++ ^ | | ^
++ | | | |
++ EL2 | | | BL33(u-boot)
++ | | | ^
++ | v | /
++ EL3 BootROM --> BL2 --> BL31 ---------------/
++
+
+Boot Sequence with FIP-DDR
+--------------------------
+::
+
++ Secure World | Normal World
++ EL0 |
++ |
++ EL1 fip-ddr BL32(Tee OS) | kernel
++ ^ | ^ | | ^
++ | | | | | |
++ EL2 | | | | | BL33(u-boot)
++ | | | | | ^
++ | v | v | /
++ EL3 BootROM --> BL2 -----> BL31 ---------------/
++
+
+DDR Memory Layout
+--------------------------
+
+NXP Platforms divide DRAM into banks:
+
+- DRAM0 Bank: Maximum size of this bank is fixed to 2GB, DRAM0 size is defined in platform_def.h if it is less than 2GB.
+
+- DRAM1 ~ DRAMn Bank: Greater than 2GB belongs to DRAM1 and following banks, and size of DRAMn Bank varies for one platform to others.
+
+The following diagram is default DRAM0 memory layout in which secure memory is at top of DRAM0.
+
+::
+
+ high +---------------------------------------------+
+ | |
+ | Secure EL1 Payload Shared Memory (2 MB) |
+ | |
+ +---------------------------------------------+
+ | |
+ | Secure Memory (64 MB) |
+ | |
+ +---------------------------------------------+
+ | |
+ | Non Secure Memory |
+ | |
+ low +---------------------------------------------+
+
+How to build
+=============
+
+Code Locations
+--------------
+
+- OP-TEE:
+ `link <https://source.codeaurora.org/external/qoriq/qoriq-components/optee_os>`__
+
+- U-Boot:
+ `link <https://source.codeaurora.org/external/qoriq/qoriq-components/u-boot>`__
+
+- RCW:
+ `link <https://source.codeaurora.org/external/qoriq/qoriq-components/rcw>`__
+
+- ddr-phy-binary: Required by platforms that need fip-ddr.
+ `link <https:://github.com/NXP/ddr-phy-binary>`__
+
+- cst: Required for TBBR.
+ `link <https:://source.codeaurora.org/external/qoriq/qoriq-components/cst>`__
+
+Build Procedure
+---------------
+
+- Fetch all the above repositories into local host.
+
+- Prepare AARCH64 toolchain and set the environment variable "CROSS_COMPILE".
+
+ .. code:: shell
+
+ export CROSS_COMPILE=.../bin/aarch64-linux-gnu-
+
+- Build RCW. Refer README from the respective cloned folder for more details.
+
+- Build u-boot and OPTee firstly, and get binary images: u-boot.bin and tee.bin.
+ For u-boot you can use the <platform>_tfa_defconfig for build.
+
+- Copy/clone the repo "ddr-phy-binary" to the tfa directory for platform needing ddr-fip.
+
+- Below are the steps to build TF-A images for the supported platforms.
+
+Compilation steps without BL32
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+BUILD BL2:
+
+-To compile
+ .. code:: shell
+
+ make PLAT=$PLAT \
+ BOOT_MODE=<platform_supported_boot_mode> \
+ RCW=$RCW_BIN \
+ pbl
+
+BUILD FIP:
+
+ .. code:: shell
+
+ make PLAT=$PLAT \
+ BOOT_MODE=<platform_supported_boot_mode> \
+ RCW=$RCW_BIN \
+ BL33=$UBOOT_SECURE_BIN \
+ pbl \
+ fip
+
+Compilation steps with BL32
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+BUILD BL2:
+
+-To compile
+ .. code:: shell
+
+ make PLAT=$PLAT \
+ BOOT_MODE=<platform_supported_boot_mode> \
+ RCW=$RCW_BIN \
+ BL32=$TEE_BIN SPD=opteed\
+ pbl
+
+BUILD FIP:
+
+ .. code:: shell
+
+ make PLAT=$PLAT \
+ BOOT_MODE=<platform_supported_boot_mode> \
+ RCW=$RCW_BIN \
+ BL32=$TEE_BIN SPD=opteed\
+ BL33=$UBOOT_SECURE_BIN \
+ pbl \
+ fip
+
+
+BUILD fip-ddr (Mandatory for certain platforms, refer table above):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-To compile additional fip-ddr for selected platforms(Refer above table if the platform needs fip-ddr).
+ .. code:: shell
+
+ make PLAT=<platform_name> fip-ddr
+
+
+Deploy ATF Images
+=================
+
+Note: The size in the standard uboot commands for copy to nor, qspi, nand or sd
+should be modified based on the binary size of the image to be copied.
+
+- Deploy ATF images on flexspi-Nor flash Alt Bank from U-Boot prompt.
+ -- Commands to flash images for bl2_xxx.pbl and fip.bin.
+
+ .. code:: shell
+
+ tftp 82000000 $path/bl2_flexspi_nor.pbl;
+ i2c mw 66 50 20;sf probe 0:0; sf erase 0 +$filesize; sf write 0x82000000 0x0 $filesize;
+
+ tftp 82000000 $path/fip.bin;
+ i2c mw 66 50 20;sf probe 0:0; sf erase 0x100000 +$filesize; sf write 0x82000000 0x100000 $filesize;
+
+ -- Next step is valid for platform where FIP-DDR is needed.
+
+ .. code:: shell
+
+ tftp 82000000 $path/ddr_fip.bin;
+ i2c mw 66 50 20;sf probe 0:0; sf erase 0x800000 +$filesize; sf write 0x82000000 0x800000 $filesize;
+
+ -- Then reset to alternate bank to boot up ATF.
+
+ .. code:: shell
+
+ qixisreset altbank;
+
+- Deploy ATF images on SD/eMMC from U-Boot prompt.
+ -- file_size_in_block_sizeof_512 = (Size_of_bytes_tftp / 512)
+
+ .. code:: shell
+
+ mmc dev <idx>; (idx = 1 for eMMC; idx = 0 for SD)
+
+ tftp 82000000 $path/bl2_<sd>_or_<emmc>.pbl;
+ mmc write 82000000 8 <file_size_in_block_sizeof_512>;
+
+ tftp 82000000 $path/fip.bin;
+ mmc write 82000000 0x800 <file_size_in_block_sizeof_512>;
+
+ -- Next step is valid for platform that needs FIP-DDR.
+
+ .. code:: shell
+
+ tftp 82000000 $path/ddr_fip.bin;
+ mmc write 82000000 0x4000 <file_size_in_block_sizeof_512>;
+
+ -- Then reset to sd/emmc to boot up ATF from sd/emmc as boot-source.
+
+ .. code:: shell
+
+ qixisreset <sd or emmc>;
+
+Trusted Board Boot:
+===================
+
+For TBBR, the binary name changes:
+
++-------------+--------------------------+---------+-------------------+
+| Boot Type | BL2 | FIP | FIP-DDR |
++=============+==========================+=========+===================+
+| Normal Boot | bl2_<boot_mode>.pbl | fip.bin | ddr_fip.bin |
++-------------+--------------------------+---------+-------------------+
+| TBBR Boot | bl2_<boot_mode>_sec.pbl | fip.bin | ddr_fip_sec.bin |
++-------------+--------------------------+---------+-------------------+
+
+Refer `nxp-ls-tbbr.rst`_ for detailed user steps.
+
+
+.. _lx2160a: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-lx2160a-lx2120a-lx2080a-processors:LX2160A
+.. _lx2160ardb: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-communication-process/layerscape-lx2160a-multicore-communications-processor:LX2160A
+.. _ls1028a: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-1028a-applications-processor:LS1028A
+.. _ls1028ardb: https://www.nxp.com/design/qoriq-developer-resources/layerscape-ls1028a-reference-design-board:LS1028ARDB
+.. _nxp-ls-tbbr.rst: ./nxp-ls-tbbr.rst
diff --git a/docs/plat/nxp/nxp-ls-fuse-prov.rst b/docs/plat/nxp/nxp-ls-fuse-prov.rst
new file mode 100644
index 0000000..64e1c6f
--- /dev/null
+++ b/docs/plat/nxp/nxp-ls-fuse-prov.rst
@@ -0,0 +1,271 @@
+
+Steps to blow fuses on NXP LS SoC:
+==================================
+
+
+- Enable POVDD
+ -- Refer board GSG(Getting Started Guide) for the steps to enable POVDD.
+ -- Once the POVDD is enabled, make sure to set variable POVDD_ENABLE := yes, in the platform.mk.
+
++---+-----------------+-----------+------------+-----------------+-----------------------------+
+| | Platform | Jumper | Switch | LED to Verify | Through GPIO Pin (=number) |
++===+=================+===========+============+=================+=============================+
+| 1.| lx2160ardb | J9 | | | no |
++---+-----------------+-----------+------------+-----------------+-----------------------------+
+| 2.| lx2160aqds | J35 | | | no |
++---+-----------------+-----------+------------+-----------------+-----------------------------+
+| 3.| lx2162aqds | J35 | SW9[4] = 1 | D15 | no |
++---+-----------------+-----------+------------+-----------------+-----------------------------+
+
+- SFP registers to be written to:
+
++---+----------------------------------+----------------------+----------------------+
+| | Platform | OTPMKR0..OTPMKR7 | SRKHR0..SRKHR7 |
++===+==================================+======================+======================+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 0x1e80234..0x1e80250 | 0x1e80254..0x1e80270 |
++---+----------------------------------+----------------------+----------------------+
+
+- At U-Boot prompt, verify that SNVS register - HPSR, whether OTPMK was written, already:
+
++---+----------------------------------+-------------------------------------------+---------------+
+| | Platform | OTPMK_ZERO_BIT(=value) | SNVS_HPSR_REG |
++===+==================================+===========================================+===============+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 27 (= 1 means not blown, =0 means blown) | 0x01E90014 |
++---+----------------------------------+-------------------------------------------+---------------+
+
+From u-boot prompt:
+
+ -- Check for the OTPMK.
+ .. code:: shell
+
+ md $SNVS_HPSR_REG
+
+ Command Output:
+ 01e90014: 88000900
+
+ In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap).
+ +0 +4 +8 +C
+ [0x01E90014] 88000900
+
+ Note: OTPMK_ZERO_BIT is 1, indicating that the OTPMK is not blown.
+
+ -- Check for the SRK Hash.
+ .. code:: shell
+
+ md $SRKHR0 0x10
+
+ Command Output:
+ 01e80254: 00000000 00000000 00000000 00000000 ................
+ 01e80264: 00000000 00000000 00000000 00000000 ................
+
+ Note: Zero means that SRK hash is not blown.
+
+- If not blown, then from the U-Boot prompt, using following commands:
+ -- Provision the OTPMK.
+
+ .. code:: shell
+
+ mw.l $OTPMKR0 <OTMPKR_0_32Bit_val>
+ mw.l $OTPMKR1 <OTMPKR_1_32Bit_val>
+ mw.l $OTPMKR2 <OTMPKR_2_32Bit_val>
+ mw.l $OTPMKR3 <OTMPKR_3_32Bit_val>
+ mw.l $OTPMKR4 <OTMPKR_4_32Bit_val>
+ mw.l $OTPMKR5 <OTMPKR_5_32Bit_val>
+ mw.l $OTPMKR6 <OTMPKR_6_32Bit_val>
+ mw.l $OTPMKR7 <OTMPKR_7_32Bit_val>
+
+ -- Provision the SRK Hash.
+
+ .. code:: shell
+
+ mw.l $SRKHR0 <SRKHR_0_32Bit_val>
+ mw.l $SRKHR1 <SRKHR_1_32Bit_val>
+ mw.l $SRKHR2 <SRKHR_2_32Bit_val>
+ mw.l $SRKHR3 <SRKHR_3_32Bit_val>
+ mw.l $SRKHR4 <SRKHR_4_32Bit_val>
+ mw.l $SRKHR5 <SRKHR_5_32Bit_val>
+ mw.l $SRKHR6 <SRKHR_6_32Bit_val>
+ mw.l $SRKHR7 <SRKHR_7_32Bit_val>
+
+ Note: SRK Hash should be carefully written keeping in mind the SFP Block Endianness.
+
+- At U-Boot prompt, verify that SNVS registers for OTPMK are correctly written:
+
+ -- Check for the OTPMK.
+ .. code:: shell
+
+ md $SNVS_HPSR_REG
+
+ Command Output:
+ 01e90014: 80000900
+
+ OTPMK_ZERO_BIT is zero, indicating that the OTPMK is blown.
+
+ Note: In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap).
+
+ .. code:: shell
+
+ md $OTPMKR0 0x10
+
+ Command Output:
+ 01e80234: ffffffff ffffffff ffffffff ffffffff ................
+ 01e80244: ffffffff ffffffff ffffffff ffffffff ................
+
+ Note: OTPMK will never be visible in plain.
+
+ -- Check for the SRK Hash. For example, if following SRK hash is written:
+
+ SFP SRKHR0 = fdc2fed4
+ SFP SRKHR1 = 317f569e
+ SFP SRKHR2 = 1828425c
+ SFP SRKHR3 = e87b5cfd
+ SFP SRKHR4 = 34beab8f
+ SFP SRKHR5 = df792a70
+ SFP SRKHR6 = 2dff85e1
+ SFP SRKHR7 = 32a29687,
+
+ then following would be the value on dumping SRK hash.
+
+ .. code:: shell
+
+ md $SRKHR0 0x10
+
+ Command Output:
+ 01e80254: d4fec2fd 9e567f31 5c422818 fd5c7be8 ....1.V..(B\.{\.
+ 01e80264: 8fabbe34 702a79df e185ff2d 8796a232 4....y*p-...2...
+
+ Note: SRK Hash is visible in plain based on the SFP Block Endianness.
+
+- Caution: Donot proceed to the next step, until you are sure that OTPMK and SRKH are correctly blown from above steps.
+ -- After the next step, there is no turning back.
+ -- Fuses will be burnt, which cannot be undo.
+
+- Write SFP_INGR[INST] with the PROGFB(0x2) instruction to blow the fuses.
+ -- User need to save the SRK key pair and OTPMK Key forever, to continue using this board.
+
++---+----------------------------------+-------------------------------------------+-----------+
+| | Platform | SFP_INGR_REG | SFP_WRITE_DATE_FRM_MIRROR_REG_TO_FUSE |
++===+==================================+=======================================================+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 0x01E80020 | 0x2 |
++---+----------------------------------+--------------+----------------------------------------+
+
+ .. code:: shell
+
+ md $SFP_INGR_REG $SFP_WRITE_DATE_FRM_MIRROR_REG_TO_FUSE
+
+- On reset, if the SFP register were read from u-boot, it will show the following:
+ -- Check for the OTPMK.
+
+ .. code:: shell
+
+ md $SNVS_HPSR_REG
+
+ Command Output:
+ 01e90014: 80000900
+
+ In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap).
+ +0 +4 +8 +C
+ [0x01E90014] 80000900
+
+ Note: OTPMK_ZERO_BIT is zero, indicating that the OTPMK is blown.
+
+ .. code:: shell
+
+ md $OTPMKR0 0x10
+
+ Command Output:
+ 01e80234: ffffffff ffffffff ffffffff ffffffff ................
+ 01e80244: ffffffff ffffffff ffffffff ffffffff ................
+
+ Note: OTPMK will never be visible in plain.
+
+ -- SRK Hash
+
+ .. code:: shell
+
+ md $SRKHR0 0x10
+
+ Command Output:
+ 01e80254: d4fec2fd 9e567f31 5c422818 fd5c7be8 ....1.V..(B\.{\.
+ 01e80264: 8fabbe34 702a79df e185ff2d 8796a232 4....y*p-...2...
+
+ Note: SRK Hash is visible in plain based on the SFP Block Endianness.
+
+Second method to do the fuse provsioning:
+=========================================
+
+This method is used for quick way to provision fuses.
+Typically used by those who needs to provision number of boards.
+
+- Enable POVDD:
+ -- Refer the table above to enable POVDD.
+
+ Note: If GPIO Pin supports enabling POVDD, it can be done through the below input_fuse_file.
+
+ -- Once the POVDD is enabled, make sure to set variable POVDD_ENABLE := yes, in the platform.mk.
+
+- User need to populate the "input_fuse_file", corresponding to the platform for:
+
+ -- OTPMK
+ -- SRKH
+
+ Table of fuse provisioning input file for every supported platform:
+
++---+----------------------------------+-----------------------------------------------------------------+
+| | Platform | FUSE_PROV_FILE |
++===+==================================+=================================================================+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | ${CST_DIR}/input_files/gen_fusescr/ls2088_1088/input_fuse_file |
++---+----------------------------------+--------------+--------------------------------------------------+
+
+- Create the TF-A binary with FUSE_PROG=1.
+
+ .. code:: shell
+
+ make PLAT=$PLAT FUSE_PROG=1\
+ BOOT_MODE=<platform_supported_boot_mode> \
+ RCW=$RCW_BIN \
+ BL32=$TEE_BIN SPD=opteed\
+ BL33=$UBOOT_SECURE_BIN \
+ pbl \
+ fip \
+ fip_fuse \
+ FUSE_PROV_FILE=../../apps/security/cst/input_files/gen_fusescr/ls2088_1088/input_fuse_file
+
+- Deployment:
+ -- Refer the nxp-layerscape.rst for deploying TF-A images.
+ -- Deploying fip_fuse.bin:
+
+ For Flexspi-Nor:
+
+ .. code:: shell
+
+ tftp 82000000 $path/fuse_fip.bin;
+ i2c mw 66 50 20;sf probe 0:0; sf erase 0x880000 +$filesize; sf write 0x82000000 0x880000 $filesize;
+
+ For SD or eMMC [file_size_in_block_sizeof_512 = (Size_of_bytes_tftp / 512)]:
+
+ .. code:: shell
+
+ tftp 82000000 $path/fuse_fip.bin;
+ mmc write 82000000 0x4408 <file_size_in_block_sizeof_512>;
+
+- Valiation:
+
++---+----------------------------------+---------------------------------------------------+
+| | Platform | Error_Register | Error_Register_Address |
++===+==================================+===================================================+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | DCFG scratch 4 register | 0x01EE020C |
++---+----------------------------------+---------------------------------------------------+
+
+ At the U-Boot prompt, check DCFG scratch 4 register for any error.
+
+ .. code:: shell
+
+ md $Error_Register_Address 1
+
+ Command Ouput:
+ 01ee020c: 00000000
+
+ Note:
+ - 0x00000000 shows no error, then fuse provisioning is successful.
+ - For non-zero value, refer the code header file ".../drivers/nxp/sfp/sfp_error_codes.h"
diff --git a/docs/plat/nxp/nxp-ls-tbbr.rst b/docs/plat/nxp/nxp-ls-tbbr.rst
new file mode 100644
index 0000000..43e15f7
--- /dev/null
+++ b/docs/plat/nxp/nxp-ls-tbbr.rst
@@ -0,0 +1,210 @@
+
+--------------
+NXP Platforms:
+--------------
+TRUSTED_BOARD_BOOT option can be enabled by specifying TRUSTED_BOARD_BOOT=1 on command line during make.
+
+
+
+Bare-Minimum Preparation to run TBBR on NXP Platforms:
+=======================================================
+- OTPMK(One Time Programable Key) needs to be burnt in fuses.
+ -- It is the 256 bit key that stores a secret value used by the NXP SEC 4.0 IP in Trusted or Secure mode.
+
+ Note: It is primarily for the purpose of decrypting additional secrets stored in system non-volatile memory.
+
+ -- NXP CST tool gives an option to generate it.
+
+ Use the below command from directory 'cst', with correct options.
+
+ .. code:: shell
+
+ ./gen_otpmk_drbg
+
+- SRKH (Super Root Key Hash) needs to be burnt in fuses.
+ -- It is the 256 bit hash of the list of the public keys of the SRK key pair.
+ -- NXP CST tool gives an option to generate the RSA key pair and its hash.
+
+ Use the below command from directory 'cst', with correct options.
+
+ .. code:: shell
+
+ ./gen_keys
+
+Refer fuse frovisioning readme 'nxp-ls-fuse-prov.rst' for steps to blow these keys.
+
+
+
+Two options are provided for TRUSTED_BOARD_BOOT:
+================================================
+
+-------------------------------------------------------------------------
+Option 1: CoT using X 509 certificates
+-------------------------------------------------------------------------
+
+- This CoT is as provided by ARM.
+
+- To use this option user needs to specify mbedtld dir path in MBEDTLS_DIR.
+
+- To generate CSF header, path of CST repository needs to be specified as CST_DIR
+
+- CSF header is embedded to each of the BL2 image.
+
+- GENERATE_COT=1 adds the tool 'cert_create' to the build environment to generate:
+ -- X509 Certificates as (.crt) files.
+ -- X509 Pem key file as (.pem) files.
+
+- SAVE_KEYS=1 saves the keys and certificates, if GENERATE_COT=1.
+ -- For this to work, file name for cert and keys are provided as part of compilation or build command.
+
+ --- default file names will be used, incase not provided as part compilation or build command.
+ --- default folder 'BUILD_PLAT' will be used to store them.
+
+- ROTPK for x.509 certificates is generated and embedded in bl2.bin and
+ verified as part of CoT by Boot ROM during secure boot.
+
+- Compilation steps:
+
+All Images
+ .. code:: shell
+
+ make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 MBEDTLS_DIR=$MBEDTLS_PATH CST_DIR=$CST_DIR_PATH \
+ BOOT_MODE=<platform_supported_boot_mode> \
+ RCW=$RCW_BIN \
+ BL32=$TEE_BIN SPD=opteed\
+ BL33=$UBOOT_SECURE_BIN \
+ pbl \
+ fip
+
+Additional FIP_DDR Image (For NXP platforms like lx2160a)
+ .. code:: shell
+
+ make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 MBEDTLS_DIR=$MBEDTLS_PATH fip_ddr
+
+ Note: make target 'fip_ddr' should never be combine with other make target 'fip', 'pbl' & 'bl2'.
+
+-------------------------------------------------------------------------
+Option 2: CoT using NXP CSF headers.
+-------------------------------------------------------------------------
+
+- This option is automatically selected when TRUSTED_BOARD_BOOT is set but MBEDTLS_DIR path is not specified.
+
+- CSF header is embedded to each of the BL31, BL32 and BL33 image.
+
+- To generate CSF header, path of CST repository needs to be specified as CST_DIR
+
+- Default input files for CSF header generation is added in this repo.
+
+- Default input file requires user to generate RSA key pair named
+ -- srk.pri, and
+ -- srk.pub, and add them in ATF repo.
+ -- These keys can be generated using gen_keys tool of CST.
+
+- To change the input file , user can use the options BL33_INPUT_FILE, BL32_INPUT_FILE, BL31_INPUT_FILE
+
+- There are 2 paths in secure boot flow :
+ -- Development Mode (sb_en in RCW = 1, SFP->OSPR, ITS = 0)
+
+ --- In this flow , even on ROTPK comparison failure, flow would continue.
+ --- However SNVS is transitioned to non-secure state
+
+ -- Production mode (SFP->OSPR, ITS = 1)
+
+ --- Any failure is fatal failure
+
+- Compilation steps:
+
+All Images
+ .. code:: shell
+
+ make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH \
+ BOOT_MODE=<platform_supported_boot_mode> \
+ RCW=$RCW_BIN \
+ BL32=$TEE_BIN SPD=opteed\
+ BL33=$UBOOT_SECURE_BIN \
+ pbl \
+ fip
+
+Additional FIP_DDR Image (For NXP platforms like lx2160a)
+ .. code:: shell
+
+ make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH fip_ddr
+
+- Compilation Steps with build option for generic image processing filters to prepend CSF header:
+ -- Generic image processing filters to prepend CSF header
+
+ BL32_INPUT_FILE = < file name>
+ BL33_INPUT_FILE = <file name>
+
+ .. code:: shell
+
+ make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH \
+ BOOT_MODE=<platform_supported_boot_mode> \
+ RCW=$RCW_BIN \
+ BL32=$TEE_BIN SPD=opteed\
+ BL33=$UBOOT_SECURE_BIN \
+ BL33_INPUT_FILE = <ip file> \
+ BL32_INPUT_FILE = <ip_file> \
+ BL31_INPUT_FILE = <ip file> \
+ pbl \
+ fip
+
+
+Deploy ATF Images
+=================
+Same steps as mentioned in the readme "nxp-layerscape.rst".
+
+
+
+Verification to check if Secure state is achieved:
+==================================================
+
++---+----------------+-----------------+------------------------+----------------------------------+-------------------------------+
+| | Platform | SNVS_HPSR_REG | SYS_SECURE_BIT(=value) | SYSTEM_SECURE_CONFIG_BIT(=value) | SSM_STATE |
++===+================+=================+========================+==================================+===============================+
+| 1.| lx2160ardb or | 0x01E90014 | 15 | 14-12 | 11-8 |
+| | lx2160aqds or | | ( = 1, BootROM Booted) | ( = 010 means Intent to Secure, | (=1111 means secure boot) |
+| | lx2162aqds | | | ( = 000 Unsecure) | (=1011 means Non-secure Boot) |
++---+----------------+-----------------+------------------------+----------------------------------+-------------------------------+
+
+- Production mode (SFP->OSPR, ITS = 1)
+ -- Linux prompt will successfully come. if the TBBR is successful.
+
+ --- Else, Linux boot will be successful.
+
+ -- For secure-boot status, read SNVS Register $SNVS_HPSR_REG from u-boot prompt:
+
+ .. code:: shell
+
+ md $SNVS_HPSR_REG
+
+ Command Output:
+ 1e90014: 8000AF00
+
+ In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap).
+ +0 +4 +8 +C
+ [0x01E90014] 8000AF00
+
+
+- Development Mode (sb_en in RCW = 1, SFP->OSPR, ITS = 0)
+ -- Refer the SoC specific table to read the register to interpret whether the secure boot is achieved or not.
+ -- Using JTAG (in development environment only, using CW tap):
+
+ --- For secure-boot status, read SNVS Register $SNVS_HPSR_REG
+
+ .. code:: shell
+
+ ccs::display_regs 86 0x01E90014 4 0 1
+
+ Command Output:
+ Using the SAP chain position number 86, following is the output.
+
+ +0 +4 +8 +C
+ [0x01E90014] 8000AF00
+
+ Note: Chain position number will vary from one SoC to other SoC.
+
+- Interpretation of the value:
+
+ -- 0xA indicates BootROM booted, with intent to secure.
+ -- 0xF = secure boot, as SSM_STATE.
diff --git a/docs/plat/qti.rst b/docs/plat/qti.rst
index 814e672..1d483e7 100644
--- a/docs/plat/qti.rst
+++ b/docs/plat/qti.rst
@@ -1,8 +1,8 @@
Qualcomm Technologies, Inc.
===========================
-Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180.
-
+Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180,
+SC7280.
Boot Trace
-------------
@@ -38,4 +38,6 @@
added to satisfy compilation.
QTISELIB for SC7180 is available at
-`link <https://review.coreboot.org/cgit/qc_blobs.git/plain/sc7180/qtiseclib/libqtisec.a>`__
+`link <https://github.com/coreboot/qc_blobs/blob/master/sc7180/qtiseclib/libqtisec.a?raw=true>`__
+QTISELIB for SC7280 is available at
+`link <https://github.com/coreboot/qc_blobs/blob/master/sc7280/qtiseclib/libqtisec.a?raw=true>`__
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index 0ef2923..17f7a86 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -37,6 +37,17 @@
for ROM code is able to load this image.
Tool stm32image can be used to prepend this header to the generated TF-A binary.
+Boot with FIP
+~~~~~~~~~~~~~
+The use of FIP is now the recommended way to boot STM32MP1 platform.
+Only BL2 (with STM32 header) is loaded by ROM code. The other binaries are
+inside the FIP binary: BL32 (SP_min or OP-TEE), U-Boot and their respective
+device tree blobs.
+
+STM32IMAGE bootchain
+~~~~~~~~~~~~~~~~~~~~
+Although still supported, this way of booting is not recommended.
+Pease use FIP instead.
At compilation step, BL2, BL32 and DTB file are linked together in a single
binary. The stm32image tool is also generated and the header is added to TF-A
binary. This binary file with header is named tf-a-stm32mp157c-ev1.stm32.
@@ -55,15 +66,17 @@
| ... |
| |
0x2FFC0000 +-----------------+ \
- | | |
- | ... | |
- | | |
- 0x2FFD8000 +-----------------+ |
- | TF-A DTB | | Embedded SRAM
- 0x2FFDC000 +-----------------+ |
- | BL2 | |
- 0x2FFEF000 +-----------------+ |
+ | BL32 DTB | |
+ 0x2FFC5000 +-----------------+ |
| BL32 | |
+ 0x2FFDF000 +-----------------+ |
+ | ... | |
+ 0x2FFE3000 +-----------------+ |
+ | BL2 DTB | | Embedded SRAM
+ 0x2FFEA000 +-----------------+ |
+ | BL2 | |
+ 0x2FFFF000 +-----------------+ |
+ | SCMI mailbox | |
0x30000000 +-----------------+ /
| |
| ... |
@@ -102,23 +115,110 @@
- ``STM32MP_SPI_NAND``
- ``STM32MP_SPI_NOR``
-To build with SP_min and support for all bootable devices:
+Boot with FIP
+~~~~~~~~~~~~~
+You need to build BL2, BL32 (SP_min or OP-TEE) and BL33 (U-Boot) before building FIP binary.
+
+U-Boot
+______
.. code:: bash
- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1
- STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb
cd <u-boot_directory>
make stm32mp15_trusted_defconfig
make DEVICE_TREE=stm32mp157c-ev1 all
-To build TF-A with OP-TEE support for all bootable devices:
+OP-TEE (optional)
+_________________
.. code:: bash
- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb
cd <optee_directory>
- make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts
+ make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 \
+ CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts
+
+
+TF-A BL32 (SP_min)
+__________________
+If you choose not to use OP-TEE, you can use TF-A SP_min.
+To build TF-A BL32, and its device tree file:
+
+.. code:: bash
+
+ make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+ AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-ev1.dtb bl32 dtbs
+
+TF-A BL2
+________
+To build TF-A BL2 with its STM32 header for SD-card boot:
+
+.. code:: bash
+
+ make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+ DTB_FILE_NAME=stm32mp157c-ev1.dtb STM32MP_SDMMC=1
+
+For other boot devices, you have to replace STM32MP_SDMMC in the previous command
+with the desired device flag.
+
+This BL2 is independent of the BL32 used (SP_min or OP-TEE)
+
+
+FIP
+___
+With BL32 SP_min:
+
+.. code:: bash
+
+ make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+ AARCH32_SP=sp_min \
+ DTB_FILE_NAME=stm32mp157c-ev1.dtb \
+ BL33=<u-boot_directory>/u-boot-nodtb.bin \
+ BL33_CFG=<u-boot_directory>/u-boot.dtb \
+ fip
+
+With OP-TEE:
+
+.. code:: bash
+
+ make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+ DTB_FILE_NAME=stm32mp157c-ev1.dtb \
+ BL33=<u-boot_directory>/u-boot-nodtb.bin \
+ BL33_CFG=<u-boot_directory>/u-boot.dtb \
+ BL32=<optee_directory>/tee-header_v2.bin \
+ BL32_EXTRA1=<optee_directory>/tee-pager_v2.bin
+ BL32_EXTRA2=<optee_directory>/tee-pageable_v2.bin
+ fip
+
+
+STM32IMAGE bootchain
+~~~~~~~~~~~~~~~~~~~~
+You need to add the following flag to the make command:
+``STM32MP_USE_STM32IMAGE=1``
+
+To build with SP_min and support for SD-card boot:
+
+.. code:: bash
+
+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+ AARCH32_SP=sp_min STM32MP_SDMMC=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb \
+ STM32MP_USE_STM32IMAGE=1
+
+ cd <u-boot_directory>
+ make stm32mp15_trusted_defconfig
+ make DEVICE_TREE=stm32mp157c-ev1 all
+
+To build TF-A with OP-TEE support for SD-card boot:
+
+.. code:: bash
+
+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+ AARCH32_SP=optee STM32MP_SDMMC=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb \
+ STM32MP_USE_STM32IMAGE=1
+
+ cd <optee_directory>
+ make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 \
+ CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts
+
cd <u-boot_directory>
make stm32mp15_trusted_defconfig
make DEVICE_TREE=stm32mp157c-ev1 all
@@ -132,7 +232,19 @@
Populate SD-card
----------------
-The SD-card has to be formated with GPT.
+Boot with FIP
+~~~~~~~~~~~~~
+The SD-card has to be formatted with GPT.
+It should contain at least those partitions:
+
+- fsbl: to copy the tf-a-stm32mp157c-ev1.stm32 binary (BL2)
+- fip: which contains the FIP binary
+
+Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl.
+
+STM32IMAGE bootchain
+~~~~~~~~~~~~~~~~~~~~
+The SD-card has to be formatted with GPT.
It should contain at least those partitions:
- fsbl: to copy the tf-a-stm32mp157c-ev1.stm32 binary
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index c91903a..aa050da 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -209,6 +209,65 @@
revert your patches and ask you to resubmit a reworked version of them or
they may ask you to provide a fix-up patch.
+Add Build Configurations
+------------------------
+
+- TF-A uses Jenkins tool for Continuous Integration and testing activities.
+ Various CI Jobs are deployed which run tests on every patch before being
+ merged. So each of your patches go through a series of checks before they
+ get merged on to the master branch.
+
+- ``Coverity Scan analysis`` is one of the tests we perform on our source code
+ at regular intervals. We maintain a build script ``tf-cov-make`` which contains the
+ build configurations of various platforms in order to cover the entire source
+ code being analysed by Coverity.
+
+- When you submit your patches for review containing new source files, please
+ ensure to include them for the ``Coverity Scan analysis`` by adding the
+ respective build configurations in the ``tf-cov-make`` build script.
+
+- In this section you find the details on how to append your new build
+ configurations for Coverity Scan analysis:
+
+#. We maintain a separate repository named `tf-a-ci-scripts repository`_
+ for placing all the test scripts which will be executed by the CI Jobs.
+
+#. In this repository, ``tf-cov-make`` script is located at
+ ``tf-a-ci-scripts/script/tf-coverity/tf-cov-make``
+
+#. Edit `tf-cov-make`_ script by appending all the possible build configurations with
+ the specific ``build-flags`` relevant to your platform, so that newly added
+ source files get built and analysed by Coverity.
+
+#. For better understanding follow the below specified examples listed in the
+ ``tf-cov-make`` script.
+
+.. code:: shell
+
+ Example 1:
+ #Intel
+ make PLAT=stratix10 $(common_flags) all
+ make PLAT=agilex $(common_flags) all
+
+- In the above example there are two different SoCs ``stratix`` and ``agilex``
+ under the Intel platform and the build configurations has been added suitably
+ to include most of their source files.
+
+.. code:: shell
+
+ Example 2:
+ #Hikey
+ make PLAT=hikey $(common_flags) ${TBB_OPTIONS} ENABLE_PMF=1 all
+ make PLAT=hikey960 $(common_flags) ${TBB_OPTIONS} all
+ make PLAT=poplar $(common_flags) all
+
+- In this case for ``Hikey`` boards additional ``build-flags`` has been included
+ along with the ``commom_flags`` to cover most of the files relevant to it.
+
+- Similar to this you can still find many other different build configurations
+ of various other platforms listed in the ``tf-cov-make`` script. Kindly refer
+ them and append your build configurations respectively.
+
Binary Components
-----------------
@@ -228,7 +287,7 @@
--------------
-*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.*
.. _Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0
.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
@@ -243,3 +302,5 @@
.. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries
.. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst
.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _tf-a-ci-scripts repository: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/
+.. _tf-cov-make: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/script/tf-coverity/tf-cov-make
diff --git a/docs/threat_model/threat_model_spm.rst b/docs/threat_model/threat_model_spm.rst
index 96d33a2..82f9916 100644
--- a/docs/threat_model/threat_model_spm.rst
+++ b/docs/threat_model/threat_model_spm.rst
@@ -8,7 +8,7 @@
(SPM) implementation or more generally the S-EL2 reference firmware running on
systems implementing the FEAT_SEL2 (formerly Armv8.4 Secure EL2) architecture
extension. The SPM implementation is based on the `Arm Firmware Framework for
-Armv8-A`_ specification.
+Arm A-profile`_ specification.
In brief, the broad FF-A specification and S-EL2 firmware implementation
provide:
@@ -611,7 +611,7 @@
*Copyright (c) 2021, Arm Limited. All rights reserved.*
-.. _Arm Firmware Framework for Armv8-A: https://developer.arm.com/docs/den0077/latest
+.. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
.. _Secure Partition Manager: ../components/secure-partition-manager.html
.. _Generic TF-A threat model: ./threat_model.html#threat-analysis
.. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index 299d07c..60364cd 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.c
@@ -14,11 +14,10 @@
#include <lib/mmio.h>
#include <plat/arm/common/fconf_ethosn_getter.h>
-/* Arm Ethos-N NPU (NPU) status */
-#define ETHOSN_STATUS \
- FCONF_GET_PROPERTY(hw_config, ethosn_config, status)
-
-/* Number of NPU cores available */
+/*
+ * Number of Arm Ethos-N NPU (NPU) cores available for a
+ * particular parent device
+ */
#define ETHOSN_NUM_CORES \
FCONF_GET_PROPERTY(hw_config, ethosn_config, num_cores)
@@ -51,6 +50,17 @@
#define SEC_SYSCTRL0_SOFT_RESET U(3U << 29)
#define SEC_SYSCTRL0_HARD_RESET U(1U << 31)
+static bool ethosn_is_core_addr_valid(uintptr_t core_addr)
+{
+ for (uint32_t core_idx = 0U; core_idx < ETHOSN_NUM_CORES; core_idx++) {
+ if (ETHOSN_CORE_ADDR(core_idx) == core_addr) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
static void ethosn_delegate_to_ns(uintptr_t core_addr)
{
mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SECCTLR_REG),
@@ -66,9 +76,9 @@
SEC_DEL_ADDR_EXT_VAL);
}
-static int ethosn_is_sec(void)
+static int ethosn_is_sec(uintptr_t core_addr)
{
- if ((mmio_read_32(ETHOSN_CORE_SEC_REG(ETHOSN_CORE_ADDR(0), SEC_DEL_REG))
+ if ((mmio_read_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_REG))
& SEC_DEL_EXCC_MASK) != 0U) {
return 0;
}
@@ -101,7 +111,7 @@
}
uintptr_t ethosn_smc_handler(uint32_t smc_fid,
- u_register_t core_idx,
+ u_register_t core_addr,
u_register_t x2,
u_register_t x3,
u_register_t x4,
@@ -109,8 +119,8 @@
void *handle,
u_register_t flags)
{
- uintptr_t core_addr;
int hard_reset = 0;
+ const uint32_t fid = smc_fid & FUNCID_NUM_MASK;
/* Only SiP fast calls are expected */
if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) ||
@@ -120,7 +130,7 @@
/* Truncate parameters to 32-bits for SMC32 */
if (GET_SMC_CC(smc_fid) == SMC_32) {
- core_idx &= 0xFFFFFFFF;
+ core_addr &= 0xFFFFFFFF;
x2 &= 0xFFFFFFFF;
x3 &= 0xFFFFFFFF;
x4 &= 0xFFFFFFFF;
@@ -130,33 +140,29 @@
SMC_RET1(handle, SMC_UNK);
}
- if (ETHOSN_STATUS == ETHOSN_STATUS_DISABLED) {
- WARN("ETHOSN: Arm Ethos-N NPU not available\n");
- SMC_RET1(handle, ETHOSN_NOT_SUPPORTED);
- }
-
- switch (smc_fid & FUNCID_NUM_MASK) {
+ /* Commands that do not require a valid core address */
+ switch (fid) {
case ETHOSN_FNUM_VERSION:
SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR);
+ }
+
+ if (!ethosn_is_core_addr_valid(core_addr)) {
+ WARN("ETHOSN: Unknown core address given to SMC call.\n");
+ SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS);
+ }
+
+ /* Commands that require a valid addr */
+ switch (fid) {
case ETHOSN_FNUM_IS_SEC:
- SMC_RET1(handle, ethosn_is_sec());
+ SMC_RET1(handle, ethosn_is_sec(core_addr));
case ETHOSN_FNUM_HARD_RESET:
hard_reset = 1;
/* Fallthrough */
case ETHOSN_FNUM_SOFT_RESET:
- if (core_idx >= ETHOSN_NUM_CORES) {
- WARN("ETHOSN: core index out of range\n");
- SMC_RET1(handle, ETHOSN_CORE_IDX_OUT_OF_RANGE);
- }
-
- core_addr = ETHOSN_CORE_ADDR(core_idx);
-
if (!ethosn_reset(core_addr, hard_reset)) {
SMC_RET1(handle, ETHOSN_FAILURE);
}
-
ethosn_delegate_to_ns(core_addr);
-
SMC_RET1(handle, ETHOSN_SUCCESS);
default:
SMC_RET1(handle, SMC_UNK);
diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c
index 6e106ba..aaef485 100644
--- a/drivers/arm/gic/v3/gic-x00.c
+++ b/drivers/arm/gic/v3/gic-x00.c
@@ -16,15 +16,13 @@
#include <assert.h>
#include <arch_helpers.h>
+#include <drivers/arm/arm_gicv3_common.h>
#include <drivers/arm/gicv3.h>
#include "gicv3_private.h"
/* GIC-600 specific register offsets */
#define GICR_PWRR 0x24U
-#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b)
-#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b)
-#define IIDR_MODEL_ARM_GIC_CLAYTON U(0x0400043b)
/* GICR_PWRR fields */
#define PWRR_RDPD_SHIFT 0
@@ -46,7 +44,7 @@
#if GICV3_SUPPORT_GIC600
-/* GIC-600/Clayton specific accessor functions */
+/* GIC-600/700 specific accessor functions */
static void gicr_write_pwrr(uintptr_t base, unsigned int val)
{
mmio_write_32(base + GICR_PWRR, val);
@@ -123,12 +121,12 @@
uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR);
/*
- * The Arm GIC-600 and GIC-Clayton models have their redistributors
+ * The Arm GIC-600 and GIC-700 models have their redistributors
* powered down at reset.
*/
return (((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) ||
((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600AE) ||
- ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_CLAYTON));
+ ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700));
}
#endif /* GICV3_SUPPORT_GIC600 */
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index ca7c43b..fd3d8c2 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -11,6 +11,7 @@
#include <assert.h>
#include <common/debug.h>
+#include <drivers/arm/arm_gicv3_common.h>
#include <drivers/arm/gic600_multichip.h>
#include <drivers/arm/gicv3.h>
@@ -73,6 +74,7 @@
unsigned int spi_id_max)
{
unsigned int spi_block_min, spi_blocks;
+ unsigned int gicd_iidr_val = gicd_read_iidr(base);
uint64_t chipr_n_val;
/*
@@ -100,8 +102,24 @@
spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
- chipr_n_val = (GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks)) |
- GICD_CHIPRx_SOCKET_STATE;
+ switch ((gicd_iidr_val & IIDR_MODEL_MASK)) {
+ case IIDR_MODEL_ARM_GIC_600:
+ chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr,
+ spi_block_min,
+ spi_blocks);
+ break;
+ case IIDR_MODEL_ARM_GIC_700:
+ chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr,
+ spi_block_min,
+ spi_blocks);
+ break;
+ default:
+ ERROR("Unsupported GIC model 0x%x for multichip setup.\n",
+ gicd_iidr_val);
+ panic();
+ break;
+ }
+ chipr_n_val |= GICD_CHIPRx_SOCKET_STATE;
/*
* Wait for DCHIPR.PUP to be zero before commencing writes to
diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h
index fe4134c..5d1ff6a 100644
--- a/drivers/arm/gic/v3/gic600_multichip_private.h
+++ b/drivers/arm/gic/v3/gic600_multichip_private.h
@@ -27,17 +27,11 @@
#define GICD_CHIPSR_RTS_SHIFT 4
#define GICD_DCHIPR_RT_OWNER_SHIFT 4
-/*
- * If GIC v4 extension is enabled, then use SPI macros specific to GIC-Clayton.
- * Other shifts and mask remains same between GIC-600 and GIC-Clayton.
- */
-#if GIC_ENABLE_V4_EXTN
-#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 9
-#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 3
-#else
-#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 10
-#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 5
-#endif
+/* Other shifts and masks remain the same between GIC-600 and GIC-700. */
+#define GIC_700_SPI_BLOCK_MIN_SHIFT 9
+#define GIC_700_SPI_BLOCKS_SHIFT 3
+#define GIC_600_SPI_BLOCK_MIN_SHIFT 10
+#define GIC_600_SPI_BLOCKS_SHIFT 5
#define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0)
#define GICD_CHIPSR_RTS_STATE_UPDATING U(1)
@@ -59,10 +53,14 @@
#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
(((spi_id_max) - (spi_id_min) + 1) / \
GIC600_SPI_ID_MIN)
-#define GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks) \
+#define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \
(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
- ((spi_block_min) << GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT) | \
- ((spi_blocks) << GICD_CHIPRx_SPI_BLOCKS_SHIFT))
+ ((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \
+ ((spi_blocks) << GIC_700_SPI_BLOCKS_SHIFT))
+#define GICD_CHIPR_VALUE_GIC_600(chip_addr, spi_block_min, spi_blocks) \
+ (((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
+ ((spi_block_min) << GIC_600_SPI_BLOCK_MIN_SHIFT) | \
+ ((spi_blocks) << GIC_600_SPI_BLOCKS_SHIFT))
/*
* Multichip data assertion macros
diff --git a/drivers/arm/gic/v3/gic600ae_fmu.c b/drivers/arm/gic/v3/gic600ae_fmu.c
new file mode 100644
index 0000000..13979fa
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600ae_fmu.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Driver for GIC-600AE Fault Management Unit
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gic600ae_fmu.h>
+#include <drivers/arm/gicv3.h>
+
+/* GIC-600 AE FMU specific register offsets */
+
+/* GIC-600 AE FMU specific macros */
+#define FMU_ERRIDR_NUM U(44)
+#define FMU_ERRIDR_NUM_MASK U(0xFFFF)
+
+/* Safety mechanisms for GICD block */
+static char *gicd_sm_info[] = {
+ "Reserved",
+ "GICD dual lockstep error",
+ "GICD AXI4 slave interface error",
+ "GICD-PPI AXI4-Stream interface error",
+ "GICD-ITS AXI4-Stream interface error",
+ "GICD-SPI-Collator AXI4-Stream interface error",
+ "GICD AXI4 master interface error",
+ "SPI RAM DED error",
+ "SGI RAM DED error",
+ "Reserved",
+ "LPI RAM DED error",
+ "GICD-remote-GICD AXI4-Stream interface error",
+ "GICD Q-Channel interface error",
+ "GICD P-Channel interface error",
+ "SPI RAM address decode error",
+ "SGI RAM address decode error",
+ "Reserved",
+ "LPI RAM address decode error",
+ "FMU dual lockstep error",
+ "FMU ping ACK error",
+ "FMU APB parity error",
+ "GICD-Wake AXI4-Stream interface error",
+ "GICD PageOffset or Chip ID error",
+ "MBIST REQ error",
+ "SPI RAM SEC error",
+ "SGI RAM SEC error",
+ "Reserved",
+ "LPI RAM SEC error",
+ "User custom SM0 error",
+ "User custom SM1 error",
+ "GICD-ITS Monolithic switch error",
+ "GICD-ITS Q-Channel interface error",
+ "GICD-ITS Monolithic interface error",
+ "GICD FMU ClkGate override"
+};
+
+/* Safety mechanisms for PPI block */
+static char *ppi_sm_info[] = {
+ "Reserved",
+ "PPI dual lockstep error",
+ "PPI-GICD AXI4-Stream interface error",
+ "PPI-CPU-IF AXI4-Stream interface error",
+ "PPI Q-Channel interface error",
+ "PPI RAM DED error",
+ "PPI RAM address decode error",
+ "PPI RAM SEC error",
+ "PPI User0 SM",
+ "PPI User1 SM",
+ "MBIST REQ error",
+ "PPI interrupt parity protection error",
+ "PPI FMU ClkGate override"
+};
+
+/* Safety mechanisms for ITS block */
+static char *its_sm_info[] = {
+ "Reserved",
+ "ITS dual lockstep error",
+ "ITS-GICD AXI4-Stream interface error",
+ "ITS AXI4 slave interface error",
+ "ITS AXI4 master interface error",
+ "ITS Q-Channel interface error",
+ "ITS RAM DED error",
+ "ITS RAM address decode error",
+ "Bypass ACE switch error",
+ "ITS RAM SEC error",
+ "ITS User0 SM",
+ "ITS User1 SM",
+ "ITS-GICD Monolithic interface error",
+ "MBIST REQ error",
+ "ITS FMU ClkGate override"
+};
+
+/* Safety mechanisms for SPI Collator block */
+static char *spicol_sm_info[] = {
+ "Reserved",
+ "SPI Collator dual lockstep error",
+ "SPI-Collator-GICD AXI4-Stream interface error",
+ "SPI Collator Q-Channel interface error",
+ "SPI Collator Q-Channel clock error",
+ "SPI interrupt parity error"
+};
+
+/* Safety mechanisms for Wake Request block */
+static char *wkrqst_sm_info[] = {
+ "Reserved",
+ "Wake dual lockstep error",
+ "Wake-GICD AXI4-Stream interface error"
+};
+
+/*
+ * Initialization sequence for the FMU
+ *
+ * 1. enable error detection for error records that are passed in the blk_present_mask
+ * 2. enable MBIST REQ and FMU Clk Gate override safety mechanisms for error records
+ * that are present on the platform
+ *
+ * The platforms are expected to pass `errctlr_ce_en` and `errctlr_ue_en`.
+ */
+void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask,
+ bool errctlr_ce_en, bool errctlr_ue_en)
+{
+ unsigned int num_blk = gic_fmu_read_erridr(base) & FMU_ERRIDR_NUM_MASK;
+ uint64_t errctlr;
+ uint32_t smen;
+
+ INFO("GIC600-AE FMU supports %d error records\n", num_blk);
+
+ assert(num_blk == FMU_ERRIDR_NUM);
+
+ /* sanitize block present mask */
+ blk_present_mask &= FMU_BLK_PRESENT_MASK;
+
+ /* Enable error detection for all error records */
+ for (unsigned int i = 0U; i < num_blk; i++) {
+
+ /* Skip next steps if the block is not present */
+ if ((blk_present_mask & BIT(i)) == 0U) {
+ continue;
+ }
+
+ /* Read the error record control register */
+ errctlr = gic_fmu_read_errctlr(base, i);
+
+ /* Enable error reporting and logging, if it is disabled */
+ if ((errctlr & FMU_ERRCTLR_ED_BIT) == 0U) {
+ errctlr |= FMU_ERRCTLR_ED_BIT;
+ }
+
+ /* Enable client provided ERRCTLR settings */
+ errctlr |= (errctlr_ce_en ? (FMU_ERRCTLR_CI_BIT | FMU_ERRCTLR_CE_EN_BIT) : 0);
+ errctlr |= (errctlr_ue_en ? FMU_ERRCTLR_UI_BIT : 0U);
+
+ gic_fmu_write_errctlr(base, i, errctlr);
+ }
+
+ /*
+ * Enable MBIST REQ error and FMU CLK gate override safety mechanisms for
+ * all blocks
+ *
+ * GICD, SMID 23 and SMID 33
+ * PPI, SMID 10 and SMID 12
+ * ITS, SMID 13 and SMID 14
+ */
+ if ((blk_present_mask & BIT(FMU_BLK_GICD)) != 0U) {
+ smen = (GICD_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+
+ smen = (GICD_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+ }
+
+ for (unsigned int i = FMU_BLK_PPI0; i < FMU_BLK_PPI31; i++) {
+ if ((blk_present_mask & BIT(i)) != 0U) {
+ smen = (PPI_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (i << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+
+ smen = (PPI_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (i << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+ }
+ }
+
+ for (unsigned int i = FMU_BLK_ITS0; i < FMU_BLK_ITS7; i++) {
+ if ((blk_present_mask & BIT(i)) != 0U) {
+ smen = (ITS_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (i << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+
+ smen = (ITS_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (i << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+ }
+ }
+}
+
+/*
+ * This function enable the GICD background ping engine. The GICD sends ping
+ * messages to each remote GIC block, and expects a PING_ACK back within the
+ * specified timeout. Pings need to be enabled after programming the timeout
+ * value.
+ */
+void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask,
+ unsigned int timeout_val, unsigned int interval_diff)
+{
+ /*
+ * Populate the PING Mask to skip a specific block while generating
+ * background ping messages and enable the ping mechanism.
+ */
+ gic_fmu_write_pingmask(base, ~blk_present_mask);
+ gic_fmu_write_pingctlr(base, (interval_diff << FMU_PINGCTLR_INTDIFF_SHIFT) |
+ (timeout_val << FMU_PINGCTLR_TIMEOUTVAL_SHIFT) | FMU_PINGCTLR_EN_BIT);
+}
+
+/* Print the safety mechanism description for a given block */
+void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid)
+{
+ if (blk == FMU_BLK_GICD && smid <= FMU_SMID_GICD_MAX) {
+ INFO("GICD, SMID %d: %s\n", smid, gicd_sm_info[smid]);
+ }
+
+ if (blk == FMU_BLK_SPICOL && smid <= FMU_SMID_SPICOL_MAX) {
+ INFO("SPI Collator, SMID %d: %s\n", smid, spicol_sm_info[smid]);
+ }
+
+ if (blk == FMU_BLK_WAKERQ && (smid <= FMU_SMID_WAKERQ_MAX)) {
+ INFO("Wake Request, SMID %d: %s\n", smid, wkrqst_sm_info[smid]);
+ }
+
+ if (((blk >= FMU_BLK_ITS0) && (blk <= FMU_BLK_ITS7)) && (smid <= FMU_SMID_ITS_MAX)) {
+ INFO("ITS, SMID %d: %s\n", smid, its_sm_info[smid]);
+ }
+
+ if (((blk >= FMU_BLK_PPI0) && (blk <= FMU_BLK_PPI31)) && (smid <= FMU_SMID_PPI_MAX)) {
+ INFO("PPI, SMID %d: %s\n", smid, ppi_sm_info[smid]);
+ }
+}
diff --git a/drivers/arm/gic/v3/gic600ae_fmu_helpers.c b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
new file mode 100644
index 0000000..84f7292
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <drivers/arm/gic600ae_fmu.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#define GICFMU_IDLE_TIMEOUT_US U(2000000)
+
+/* Macro to write 32-bit FMU registers */
+#define GIC_FMU_WRITE_32(base, reg, val) \
+ do { \
+ /* \
+ * This register receives the unlock key that is required for \
+ * writes to FMU registers to be successful. \
+ */ \
+ mmio_write_32(base + GICFMU_KEY, 0xBE); \
+ /* Perform the actual write */ \
+ mmio_write_32((base) + (reg), (val)); \
+ } while (false)
+
+/* Macro to write 64-bit FMU registers */
+#define GIC_FMU_WRITE_64(base, reg, n, val) \
+ do { \
+ /* \
+ * This register receives the unlock key that is required for \
+ * writes to FMU registers to be successful. \
+ */ \
+ mmio_write_32(base + GICFMU_KEY, 0xBE); \
+ /* \
+ * APB bus is 32-bit wide; so split the 64-bit write into \
+ * two 32-bit writes \
+ */ \
+ mmio_write_32((base) + reg##_LO + (n * 64), (val)); \
+ mmio_write_32((base) + reg##_HI + (n * 64), (val)); \
+ } while (false)
+
+/* Helper function to wait until FMU is ready to accept the next command */
+static void wait_until_fmu_is_idle(uintptr_t base)
+{
+ uint64_t timeout_ref = timeout_init_us(GICFMU_IDLE_TIMEOUT_US);
+ uint64_t status;
+
+ /* wait until status is 'busy' */
+ do {
+ status = (gic_fmu_read_status(base) & BIT(0));
+
+ if (timeout_elapsed(timeout_ref)) {
+ ERROR("GIC600 AE FMU is not responding\n");
+ panic();
+ }
+ } while (status == U(0));
+}
+
+#define GIC_FMU_WRITE_ON_IDLE_32(base, reg, val) \
+ do { \
+ /* Wait until FMU is ready */ \
+ wait_until_fmu_is_idle(base); \
+ /* Actual register write */ \
+ GIC_FMU_WRITE_32(base, reg, val); \
+ /* Wait until FMU is ready */ \
+ wait_until_fmu_is_idle(base); \
+ } while (false)
+
+#define GIC_FMU_WRITE_ON_IDLE_64(base, reg, n, val) \
+ do { \
+ /* Wait until FMU is ready */ \
+ wait_until_fmu_is_idle(base); \
+ /* Actual register write */ \
+ GIC_FMU_WRITE_64(base, reg, n, val); \
+ /* Wait until FMU is ready */ \
+ wait_until_fmu_is_idle(base); \
+ } while (false)
+
+/*******************************************************************************
+ * GIC FMU functions for accessing the Fault Management Unit registers
+ ******************************************************************************/
+
+/*
+ * Accessors to read the Error Record Feature Register bits corresponding
+ * to an error record 'n'
+ */
+uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRFR_LO + n * 64U);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRFR_HI + n * 64U) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the Error Record Control Register bits corresponding
+ * to an error record 'n'
+ */
+uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_LO + n * 64U);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_HI + n * 64U) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the Error Record Primary Status Register bits
+ * corresponding to an error record 'n'
+ */
+uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_LO + n * 64U);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_HI + n * 64U) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the Error Group Status Register
+ */
+uint64_t gic_fmu_read_errgsr(uintptr_t base)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRGSR_LO);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRGSR_HI) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the Ping Control Register
+ */
+uint32_t gic_fmu_read_pingctlr(uintptr_t base)
+{
+ return mmio_read_32(base + GICFMU_PINGCTLR);
+}
+
+/*
+ * Accessors to read the Ping Now Register
+ */
+uint32_t gic_fmu_read_pingnow(uintptr_t base)
+{
+ return mmio_read_32(base + GICFMU_PINGNOW);
+}
+
+/*
+ * Accessors to read the Ping Mask Register
+ */
+uint64_t gic_fmu_read_pingmask(uintptr_t base)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_PINGMASK_LO);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_PINGMASK_HI) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the FMU Status Register
+ */
+uint32_t gic_fmu_read_status(uintptr_t base)
+{
+ return mmio_read_32(base + GICFMU_STATUS);
+}
+
+/*
+ * Accessors to read the Error Record ID Register
+ */
+uint32_t gic_fmu_read_erridr(uintptr_t base)
+{
+ return mmio_read_32(base + GICFMU_ERRIDR);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Error Record Control Register
+ */
+void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val)
+{
+ GIC_FMU_WRITE_64(base, GICFMU_ERRCTLR, n, val);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Error Record Primary Status
+ * Register
+ */
+void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val)
+{
+ /* Wait until FMU is ready before writing */
+ GIC_FMU_WRITE_ON_IDLE_64(base, GICFMU_ERRSTATUS, n, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Ping Control Register
+ */
+void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val)
+{
+ GIC_FMU_WRITE_32(base, GICFMU_PINGCTLR, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Ping Now Register
+ */
+void gic_fmu_write_pingnow(uintptr_t base, uint32_t val)
+{
+ /* Wait until FMU is ready before writing */
+ GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_PINGNOW, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Safety Mechanism Enable Register
+ */
+void gic_fmu_write_smen(uintptr_t base, uint32_t val)
+{
+ /* Wait until FMU is ready before writing */
+ GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMEN, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Safety Mechanism Inject Error
+ * Register
+ */
+void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val)
+{
+ /* Wait until FMU is ready before writing */
+ GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMINJERR, val);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Ping Mask Register
+ */
+void gic_fmu_write_pingmask(uintptr_t base, uint64_t val)
+{
+ GIC_FMU_WRITE_64(base, GICFMU_PINGMASK, 0, val);
+}
diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk
index a2fc16f..d7e3536 100644
--- a/drivers/arm/gic/v3/gicv3.mk
+++ b/drivers/arm/gic/v3/gicv3.mk
@@ -1,11 +1,13 @@
#
# Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# Default configuration values
GICV3_SUPPORT_GIC600 ?= 0
+GICV3_SUPPORT_GIC600AE_FMU ?= 0
GICV3_IMPL_GIC600_MULTICHIP ?= 0
GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0
GIC_ENABLE_V4_EXTN ?= 0
@@ -16,6 +18,11 @@
drivers/arm/gic/v3/gicdv3_helpers.c \
drivers/arm/gic/v3/gicrv3_helpers.c
+ifeq (${GICV3_SUPPORT_GIC600AE_FMU}, 1)
+GICV3_SOURCES += drivers/arm/gic/v3/gic600ae_fmu.c \
+ drivers/arm/gic/v3/gic600ae_fmu_helpers.c
+endif
+
ifeq (${GICV3_OVERRIDE_DISTIF_PWR_OPS}, 0)
GICV3_SOURCES += drivers/arm/gic/v3/arm_gicv3_common.c
endif
@@ -29,6 +36,10 @@
$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600))
$(eval $(call add_define,GICV3_SUPPORT_GIC600))
+# Set GIC-600AE FMU support
+$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600AE_FMU))
+$(eval $(call add_define,GICV3_SUPPORT_GIC600AE_FMU))
+
# Set GICv4 extension
$(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN))
$(eval $(call add_define,GIC_ENABLE_V4_EXTN))
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index a0f44e9..d752013 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -86,8 +86,7 @@
if (proc_num < rdistif_num) {
rdistif_base_addrs[proc_num] = rdistif_base;
}
-
- rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
+ rdistif_base += gicv3_redist_size(typer_val);
} while ((typer_val & TYPER_LAST_BIT) == 0U);
}
@@ -383,11 +382,13 @@
uintptr_t rdistif_base = gicr_frame;
unsigned int count;
- for (count = 1; count < PLATFORM_CORE_COUNT; count++) {
- if ((gicr_read_typer(rdistif_base) & TYPER_LAST_BIT) != 0U) {
+ for (count = 1U; count < PLATFORM_CORE_COUNT; count++) {
+ uint64_t typer_val = gicr_read_typer(rdistif_base);
+
+ if ((typer_val & TYPER_LAST_BIT) != 0U) {
break;
}
- rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
+ rdistif_base += gicv3_redist_size(typer_val);
}
return count;
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index b1139b5..53a8fae 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -123,13 +123,7 @@
gic_version &= PIDR2_ARCH_REV_MASK;
/* Check GIC version */
-#if GIC_ENABLE_V4_EXTN
- assert(gic_version == ARCH_REV_GICV4);
-
- /* GICv4 supports Direct Virtual LPI injection */
- assert((gicd_read_typer(plat_driver_data->gicd_base)
- & TYPER_DVIS) != 0);
-#else
+#if !GIC_ENABLE_V4_EXTN
assert(gic_version == ARCH_REV_GICV3);
#endif
/*
@@ -1298,7 +1292,7 @@
gicr_frame_found = true;
break;
}
- rdistif_base += (uintptr_t)(ULL(1) << GICR_PCPUBASE_SHIFT);
+ rdistif_base += gicv3_redist_size(typer_val);
} while ((typer_val & TYPER_LAST_BIT) == 0U);
if (!gicr_frame_found) {
diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c
index 9fc1578..e4fc8c9 100644
--- a/drivers/arm/tzc/tzc400.c
+++ b/drivers/arm/tzc/tzc400.c
@@ -68,6 +68,7 @@
DEFINE_TZC_COMMON_WRITE_REGION_TOP(400, 400)
DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(400, 400)
DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(400, 400)
+DEFINE_TZC_COMMON_UPDATE_FILTERS(400, 400)
DEFINE_TZC_COMMON_CONFIGURE_REGION0(400)
DEFINE_TZC_COMMON_CONFIGURE_REGION(400)
@@ -271,6 +272,15 @@
sec_attr, nsaid_permissions);
}
+void tzc400_update_filters(unsigned int region, unsigned int filters)
+{
+ /* Do range checks on filters and regions. */
+ assert(((filters >> tzc400.num_filters) == 0U) &&
+ (region < tzc400.num_regions));
+
+ _tzc400_update_filters(tzc400.base, region, tzc400.num_filters, filters);
+}
+
void tzc400_enable_filters(void)
{
unsigned int state;
@@ -281,6 +291,11 @@
for (filter = 0U; filter < tzc400.num_filters; filter++) {
state = _tzc400_get_gate_keeper(tzc400.base, filter);
if (state != 0U) {
+ /* Filter 0 is special and cannot be disabled.
+ * So here we allow it being already enabled. */
+ if (filter == 0U) {
+ continue;
+ }
/*
* The TZC filter is already configured. Changing the
* programmer's view in an active system can cause
@@ -302,14 +317,17 @@
void tzc400_disable_filters(void)
{
unsigned int filter;
+ unsigned int state;
+ unsigned int start = 0U;
assert(tzc400.base != 0U);
- /*
- * We don't do the same state check as above as the Gatekeepers are
- * disabled after reset.
- */
- for (filter = 0; filter < tzc400.num_filters; filter++)
+ /* Filter 0 is special and cannot be disabled. */
+ state = _tzc400_get_gate_keeper(tzc400.base, 0);
+ if (state != 0U) {
+ start++;
+ }
+ for (filter = start; filter < tzc400.num_filters; filter++)
_tzc400_set_gate_keeper(tzc400.base, filter, 0);
}
diff --git a/drivers/arm/tzc/tzc_common_private.h b/drivers/arm/tzc/tzc_common_private.h
index 1d99077..2090944 100644
--- a/drivers/arm/tzc/tzc_common_private.h
+++ b/drivers/arm/tzc/tzc_common_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -90,6 +90,27 @@
}
/*
+ * It is used to modify the filters status for a defined region.
+ */
+#define DEFINE_TZC_COMMON_UPDATE_FILTERS(fn_name, macro_name) \
+ static inline void _tzc##fn_name##_update_filters( \
+ uintptr_t base, \
+ unsigned int region_no, \
+ unsigned int nbfilters, \
+ unsigned int filters) \
+ { \
+ uint32_t filters_mask = GENMASK(nbfilters - 1U, 0); \
+ \
+ mmio_clrsetbits_32(base + \
+ TZC_REGION_OFFSET( \
+ TZC_##macro_name##_REGION_SIZE, \
+ region_no) + \
+ TZC_##macro_name##_REGION_ATTR_0_OFFSET, \
+ filters_mask << TZC_REGION_ATTR_F_EN_SHIFT, \
+ filters << TZC_REGION_ATTR_F_EN_SHIFT); \
+ }
+
+/*
* It is used to program region 0 ATTRIBUTES and ACCESS register.
*/
#define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1_r64.c b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
new file mode 100644
index 0000000..e8e017c
--- /dev/null
+++ b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <drivers/auth/auth_mod.h>
+#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include <drivers/auth/tbbr_cot_common.h>
+
+#if USE_TBBR_DEFS
+#include <tools_share/tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+#include <platform_def.h>
+
+
+static unsigned char trusted_world_pk_buf[PK_DER_LEN];
+static unsigned char non_trusted_world_pk_buf[PK_DER_LEN];
+static unsigned char content_pk_buf[PK_DER_LEN];
+static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+
+static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
+static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID);
+static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID);
+static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
+static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
+/*
+ * Trusted key certificate
+ */
+static const auth_img_desc_t trusted_key_cert = {
+ .img_id = TRUSTED_KEY_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = NULL,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &subject_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &trusted_world_pk,
+ .data = {
+ .ptr = (void *)trusted_world_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &non_trusted_world_pk,
+ .data = {
+ .ptr = (void *)non_trusted_world_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ }
+ }
+};
+/*
+ * Non-Trusted Firmware
+ */
+static const auth_img_desc_t non_trusted_fw_key_cert = {
+ .img_id = NON_TRUSTED_FW_KEY_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &trusted_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &non_trusted_world_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &nt_fw_content_pk,
+ .data = {
+ .ptr = (void *)content_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ }
+ }
+};
+static const auth_img_desc_t non_trusted_fw_content_cert = {
+ .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &non_trusted_fw_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &nt_fw_content_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &nt_world_bl_hash,
+ .data = {
+ .ptr = (void *)nt_world_bl_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &nt_fw_config_hash,
+ .data = {
+ .ptr = (void *)nt_fw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ }
+ }
+};
+static const auth_img_desc_t bl33_image = {
+ .img_id = BL33_IMAGE_ID,
+ .img_type = IMG_RAW,
+ .parent = &non_trusted_fw_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &nt_world_bl_hash
+ }
+ }
+ }
+};
+
+static const auth_img_desc_t * const cot_desc[] = {
+ [TRUSTED_KEY_CERT_ID] = &trusted_key_cert,
+ [NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert,
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert,
+ [BL33_IMAGE_ID] = &bl33_image,
+};
+
+/* Register the CoT in the authentication module */
+REGISTER_COT(cot_desc);
diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h
index 9b10619..af5c715 100644
--- a/drivers/marvell/comphy/comphy-cp110.h
+++ b/drivers/marvell/comphy/comphy-cp110.h
@@ -54,7 +54,7 @@
#define COMMON_SELECTOR_PIPE_COMPHY_USBH 0x1
#define COMMON_SELECTOR_PIPE_COMPHY_USBD 0x2
-/* SGMII/HS-SGMII/SFI/RXAUI */
+/* SGMII/Base-X/SFI/RXAUI */
#define COMMON_SELECTOR_COMPHY0_1_2_NETWORK 0x1
#define COMMON_SELECTOR_COMPHY3_RXAUI 0x1
#define COMMON_SELECTOR_COMPHY3_SGMII 0x2
diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c
index 7377e5e..0ad14a8 100644
--- a/drivers/marvell/comphy/phy-comphy-3700.c
+++ b/drivers/marvell/comphy/phy-comphy-3700.c
@@ -118,7 +118,7 @@
};
/* PHY selector configures with corresponding modes */
-static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index,
+static int mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index,
uint32_t comphy_mode)
{
uint32_t reg;
@@ -135,7 +135,7 @@
break;
case (COMPHY_SGMII_MODE):
- case (COMPHY_HS_SGMII_MODE):
+ case (COMPHY_2500BASEX_MODE):
if (comphy_index == COMPHY_LANE0)
reg &= ~COMPHY_SELECTOR_USB3_GBE1_SEL_BIT;
else if (comphy_index == COMPHY_LANE1)
@@ -168,9 +168,10 @@
}
mmio_write_32(MVEBU_COMPHY_REG_BASE + COMPHY_SELECTOR_PHY_REG, reg);
- return;
+ return 0;
error:
ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
+ return -EINVAL;
}
/*
@@ -183,7 +184,7 @@
* with COMPHY_USB3D_MODE or COMPHY_USB3H_MODE. (The usb3 phy initialization
* code does not differentiate between these modes.)
* Also it returns COMPHY_SGMII_MODE even if the phy was configures with
- * COMPHY_HS_SGMII_MODE. (The sgmii phy initialization code does differentiate
+ * COMPHY_2500BASEX_MODE. (The sgmii phy initialization code does differentiate
* between these modes, but it is irrelevant when powering the phy off.)
*/
static int mvebu_a3700_comphy_get_mode(uint8_t comphy_index)
@@ -214,7 +215,7 @@
/* It is only used for SATA and USB3 on comphy lane2. */
static void comphy_set_indirect(uintptr_t addr, uint32_t offset, uint16_t data,
- uint16_t mask, int mode)
+ uint16_t mask, bool is_sata)
{
/*
* When Lane 2 PHY is for USB3, access the PHY registers
@@ -224,27 +225,38 @@
* within the SATA Host Controller registers, Lane 2 base register
* offset is 0x200
*/
- if (mode == COMPHY_UNUSED)
- return;
-
- if (mode == COMPHY_SATA_MODE)
+ if (is_sata) {
mmio_write_32(addr + COMPHY_LANE2_INDIR_ADDR_OFFSET, offset);
- else
+ } else {
mmio_write_32(addr + COMPHY_LANE2_INDIR_ADDR_OFFSET,
offset + USB3PHY_LANE2_REG_BASE_OFFSET);
+ }
reg_set(addr + COMPHY_LANE2_INDIR_DATA_OFFSET, data, mask);
}
-/* It is only used USB3 direct access not on comphy lane2. */
+/* It is only used for SATA on comphy lane2. */
+static void comphy_sata_set_indirect(uintptr_t addr, uint32_t reg_offset,
+ uint16_t data, uint16_t mask)
+{
+ comphy_set_indirect(addr, reg_offset, data, mask, true);
+}
+
+/* It is only used for USB3 indirect access on comphy lane2. */
+static void comphy_usb3_set_indirect(uintptr_t addr, uint32_t reg_offset,
+ uint16_t data, uint16_t mask)
+{
+ comphy_set_indirect(addr, reg_offset, data, mask, false);
+}
+
+/* It is only used for USB3 direct access not on comphy lane2. */
static void comphy_usb3_set_direct(uintptr_t addr, uint32_t reg_offset,
- uint16_t data, uint16_t mask, int mode)
+ uint16_t data, uint16_t mask)
{
reg_set16((reg_offset * PHY_SHFT(USB3) + addr), data, mask);
}
-static void comphy_sgmii_phy_init(uint32_t comphy_index, uint32_t mode,
- uintptr_t sd_ip_addr)
+static void comphy_sgmii_phy_init(uintptr_t sd_ip_addr, bool is_1gbps)
{
const int fix_arr_sz = ARRAY_SIZE(sgmii_phy_init_fix);
int addr, fix_idx;
@@ -259,8 +271,7 @@
* comparison to 3.125 Gbps values. These register values are
* stored in "sgmii_phy_init_fix" array.
*/
- if ((mode != COMPHY_SGMII_MODE) &&
- (sgmii_phy_init_fix[fix_idx].addr == addr)) {
+ if (!is_1gbps && sgmii_phy_init_fix[fix_idx].addr == addr) {
/* Use new value */
val = sgmii_phy_init_fix[fix_idx].value;
if (fix_idx < fix_arr_sz)
@@ -276,21 +287,22 @@
static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index,
uint32_t comphy_mode)
{
- int ret = 0;
+ int ret;
uint32_t offset, data = 0, ref_clk;
uintptr_t comphy_indir_regs = COMPHY_INDIRECT_REG;
- int mode = COMPHY_GET_MODE(comphy_mode);
int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode);
debug_enter();
/* Configure phy selector for SATA */
- mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ if (ret) {
+ return ret;
+ }
/* Clear phy isolation mode to make it work in normal mode */
offset = COMPHY_ISOLATION_CTRL_REG + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, 0, PHY_ISOLATE_MODE,
- mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, 0, PHY_ISOLATE_MODE);
/* 0. Check the Polarity invert bits */
if (invert & COMPHY_POLARITY_TXD_INVERT)
@@ -299,13 +311,13 @@
data |= RXD_INVERT_BIT;
offset = COMPHY_SYNC_PATTERN_REG + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, data, TXD_INVERT_BIT |
- RXD_INVERT_BIT, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, data, TXD_INVERT_BIT |
+ RXD_INVERT_BIT);
/* 1. Select 40-bit data width width */
offset = COMPHY_LOOPBACK_REG0 + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, DATA_WIDTH_40BIT,
- SEL_DATA_WIDTH_MASK, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, DATA_WIDTH_40BIT,
+ SEL_DATA_WIDTH_MASK);
/* 2. Select reference clock(25M) and PHY mode (SATA) */
offset = COMPHY_POWER_PLL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET;
@@ -314,17 +326,17 @@
else
ref_clk = REF_CLOCK_SPEED_25M;
- comphy_set_indirect(comphy_indir_regs, offset, ref_clk | PHY_MODE_SATA,
- REF_FREF_SEL_MASK | PHY_MODE_MASK, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, ref_clk | PHY_MODE_SATA,
+ REF_FREF_SEL_MASK | PHY_MODE_MASK);
/* 3. Use maximum PLL rate (no power save) */
offset = COMPHY_KVCO_CAL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, USE_MAX_PLL_RATE_BIT,
- USE_MAX_PLL_RATE_BIT, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, USE_MAX_PLL_RATE_BIT,
+ USE_MAX_PLL_RATE_BIT);
/* 4. Reset reserved bit */
- comphy_set_indirect(comphy_indir_regs, COMPHY_RESERVED_REG, 0,
- PHYCTRL_FRM_PIN_BIT, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, COMPHY_RESERVED_REG, 0,
+ PHYCTRL_FRM_PIN_BIT);
/* 5. Set vendor-specific configuration (It is done in sata driver) */
/* XXX: in U-Boot below sequence was executed in this place, in Linux
@@ -346,17 +358,21 @@
COMPHY_LANE2_INDIR_DATA_OFFSET,
PLL_READY_TX_BIT, PLL_READY_TX_BIT,
COMPHY_PLL_TIMEOUT, REG_32BIT);
+ if (ret) {
+ return -ETIMEDOUT;
+ }
debug_exit();
- return ret;
+ return 0;
}
static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index,
uint32_t comphy_mode)
{
- int ret = 0;
- uint32_t mask, data, offset;
+ int ret;
+ uint32_t mask, data;
+ uintptr_t offset;
uintptr_t sd_ip_addr;
int mode = COMPHY_GET_MODE(comphy_mode);
int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode);
@@ -364,7 +380,10 @@
debug_enter();
/* Set selector */
- mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ if (ret) {
+ return ret;
+ }
/* Serdes IP Base address
* COMPHY Lane0 -- USB3/GBE1
@@ -401,8 +420,8 @@
/* SGMII 1G, SerDes speed 1.25G */
data |= SD_SPEED_1_25_G << GEN_RX_SEL_OFFSET;
data |= SD_SPEED_1_25_G << GEN_TX_SEL_OFFSET;
- } else if (mode == COMPHY_HS_SGMII_MODE) {
- /* HS SGMII (2.5G), SerDes speed 3.125G */
+ } else if (mode == COMPHY_2500BASEX_MODE) {
+ /* 2500Base-X, SerDes speed 3.125G */
data |= SD_SPEED_2_5_G << GEN_RX_SEL_OFFSET;
data |= SD_SPEED_2_5_G << GEN_TX_SEL_OFFSET;
} else {
@@ -479,9 +498,9 @@
* 25 MHz the default values stored in PHY registers are OK.
*/
debug("Running C-DPI phy init %s mode\n",
- mode == COMPHY_HS_SGMII_MODE ? "2G5" : "1G");
+ mode == COMPHY_2500BASEX_MODE ? "2G5" : "1G");
if (get_ref_clk() == 40)
- comphy_sgmii_phy_init(comphy_index, mode, sd_ip_addr);
+ comphy_sgmii_phy_init(sd_ip_addr, mode != COMPHY_2500BASEX_MODE);
/*
* 14. [Simulation Only] should not be used for real chip.
@@ -525,8 +544,10 @@
PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT,
PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT,
COMPHY_PLL_TIMEOUT, REG_32BIT);
- if (ret)
+ if (ret) {
ERROR("Failed to lock PLL for SGMII PHY %d\n", comphy_index);
+ return -ETIMEDOUT;
+ }
/*
* 19. Set COMPHY input port PIN_TX_IDLE=0
@@ -549,26 +570,29 @@
PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT,
PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT,
COMPHY_PLL_TIMEOUT, REG_32BIT);
- if (ret)
+ if (ret) {
ERROR("Failed to lock PLL for SGMII PHY %d\n", comphy_index);
-
+ return -ETIMEDOUT;
+ }
ret = polling_with_timeout(MVEBU_COMPHY_REG_BASE +
COMPHY_PHY_STATUS_OFFSET(comphy_index),
PHY_RX_INIT_DONE_BIT, PHY_RX_INIT_DONE_BIT,
COMPHY_PLL_TIMEOUT, REG_32BIT);
- if (ret)
+ if (ret) {
ERROR("Failed to init RX of SGMII PHY %d\n", comphy_index);
+ return -ETIMEDOUT;
+ }
debug_exit();
- return ret;
+ return 0;
}
static int mvebu_a3700_comphy_sgmii_power_off(uint8_t comphy_index)
{
- int ret = 0;
- uint32_t mask, data, offset;
+ uintptr_t offset;
+ uint32_t mask, data;
debug_enter();
@@ -579,28 +603,31 @@
debug_exit();
- return ret;
+ return 0;
}
static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
uint32_t comphy_mode)
{
- int ret = 0;
+ int ret;
uintptr_t reg_base = 0;
- uint32_t mask, data, addr, cfg, ref_clk;
+ uintptr_t addr;
+ uint32_t mask, data, cfg, ref_clk;
void (*usb3_reg_set)(uintptr_t addr, uint32_t reg_offset, uint16_t data,
- uint16_t mask, int mode);
- int mode = COMPHY_GET_MODE(comphy_mode);
+ uint16_t mask);
int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode);
debug_enter();
/* Set phy seclector */
- mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ if (ret) {
+ return ret;
+ }
/* Set usb3 reg access func, Lane2 is indirect access */
if (comphy_index == COMPHY_LANE2) {
- usb3_reg_set = &comphy_set_indirect;
+ usb3_reg_set = &comphy_usb3_set_indirect;
reg_base = COMPHY_INDIRECT_REG;
} else {
/* Get the direct access register resource and map */
@@ -619,7 +646,7 @@
mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK |
CFG_TX_ALIGN_POS_MASK;
usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG0_ADDR, PRD_TXDEEMPH0_MASK,
- mask, mode);
+ mask);
/*
* 2. Set BIT0: enable transmitter in high impedance mode
@@ -631,20 +658,20 @@
mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK |
TX_ELEC_IDLE_MODE_EN;
data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN;
- usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG1_ADDR, data, mask, mode);
+ usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG1_ADDR, data, mask);
/*
* 3. Set Spread Spectrum Clock Enabled
*/
usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG4_ADDR,
- SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN, mode);
+ SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN);
/*
* 4. Set Override Margining Controls From the MAC:
* Use margining signals from lane configuration
*/
usb3_reg_set(reg_base, COMPHY_REG_TEST_MODE_CTRL_ADDR,
- MODE_MARGIN_OVERRIDE, REG_16_BIT_MASK, mode);
+ MODE_MARGIN_OVERRIDE, REG_16_BIT_MASK);
/*
* 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles
@@ -652,13 +679,13 @@
*/
usb3_reg_set(reg_base, COMPHY_REG_GLOB_CLK_SRC_LO_ADDR, 0x0,
(MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE |
- BUNDLE_SAMPLE_CTRL | PLL_READY_DLY), mode);
+ BUNDLE_SAMPLE_CTRL | PLL_READY_DLY));
/*
* 6. Set G2 Spread Spectrum Clock Amplitude at 4K
*/
usb3_reg_set(reg_base, COMPHY_REG_GEN2_SET_2,
- G2_TX_SSC_AMP_VALUE_20, G2_TX_SSC_AMP_MASK, mode);
+ G2_TX_SSC_AMP_VALUE_20, G2_TX_SSC_AMP_MASK);
/*
* 7. Unset G3 Spread Spectrum Clock Amplitude
@@ -667,7 +694,7 @@
mask = G3_TX_SSC_AMP_MASK | G3_VREG_RXTX_MAS_ISET_MASK |
RSVD_PH03FH_6_0_MASK;
usb3_reg_set(reg_base, COMPHY_REG_GEN2_SET_3,
- G3_VREG_RXTX_MAS_ISET_60U, mask, mode);
+ G3_VREG_RXTX_MAS_ISET_60U, mask);
/*
* 8. Check crystal jumper setting and program the Power and PLL Control
@@ -688,39 +715,37 @@
REF_FREF_SEL_MASK;
data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |
PU_TX_INTP_BIT | PU_DFE_BIT | PHY_MODE_USB3 | ref_clk;
- usb3_reg_set(reg_base, COMPHY_POWER_PLL_CTRL, data, mask, mode);
+ usb3_reg_set(reg_base, COMPHY_POWER_PLL_CTRL, data, mask);
mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK |
CFG_PM_RXDLOZ_WAIT_MASK;
data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg;
- usb3_reg_set(reg_base, COMPHY_REG_PWR_MGM_TIM1_ADDR, data, mask, mode);
+ usb3_reg_set(reg_base, COMPHY_REG_PWR_MGM_TIM1_ADDR, data, mask);
/*
* 9. Enable idle sync
*/
data = UNIT_CTRL_DEFAULT_VALUE | IDLE_SYNC_EN;
- usb3_reg_set(reg_base, COMPHY_REG_UNIT_CTRL_ADDR, data, REG_16_BIT_MASK,
- mode);
+ usb3_reg_set(reg_base, COMPHY_REG_UNIT_CTRL_ADDR, data, REG_16_BIT_MASK);
/*
* 10. Enable the output of 500M clock
*/
data = MISC_REG0_DEFAULT_VALUE | CLK500M_EN;
- usb3_reg_set(reg_base, COMPHY_MISC_REG0_ADDR, data, REG_16_BIT_MASK,
- mode);
+ usb3_reg_set(reg_base, COMPHY_MISC_REG0_ADDR, data, REG_16_BIT_MASK);
/*
* 11. Set 20-bit data width
*/
usb3_reg_set(reg_base, COMPHY_LOOPBACK_REG0, DATA_WIDTH_20BIT,
- REG_16_BIT_MASK, mode);
+ REG_16_BIT_MASK);
/*
* 12. Override Speed_PLL value and use MAC PLL
*/
usb3_reg_set(reg_base, COMPHY_KVCO_CAL_CTRL,
(SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT),
- REG_16_BIT_MASK, mode);
+ REG_16_BIT_MASK);
/*
* 13. Check the Polarity invert bit
@@ -733,27 +758,26 @@
data |= RXD_INVERT_BIT;
}
mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
- usb3_reg_set(reg_base, COMPHY_SYNC_PATTERN_REG, data, mask, mode);
+ usb3_reg_set(reg_base, COMPHY_SYNC_PATTERN_REG, data, mask);
/*
* 14. Set max speed generation to USB3.0 5Gbps
*/
usb3_reg_set(reg_base, COMPHY_SYNC_MASK_GEN_REG, PHY_GEN_USB3_5G,
- PHY_GEN_MAX_MASK, mode);
+ PHY_GEN_MAX_MASK);
/*
* 15. Set capacitor value for FFE gain peaking to 0xF
*/
usb3_reg_set(reg_base, COMPHY_REG_GEN3_SETTINGS_3,
- COMPHY_GEN_FFE_CAP_SEL_VALUE, COMPHY_GEN_FFE_CAP_SEL_MASK,
- mode);
+ COMPHY_GEN_FFE_CAP_SEL_VALUE, COMPHY_GEN_FFE_CAP_SEL_MASK);
/*
* 16. Release SW reset
*/
data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4;
usb3_reg_set(reg_base, COMPHY_REG_GLOB_PHY_CTRL0_ADDR, data,
- REG_16_BIT_MASK, mode);
+ REG_16_BIT_MASK);
/* Wait for > 55 us to allow PCLK be enabled */
udelay(PLL_SET_DELAY_US);
@@ -771,12 +795,14 @@
TXDCLK_PCLK_EN, TXDCLK_PCLK_EN,
COMPHY_PLL_TIMEOUT, REG_16BIT);
}
- if (ret)
+ if (ret) {
ERROR("Failed to lock USB3 PLL\n");
+ return -ETIMEDOUT;
+ }
debug_exit();
- return ret;
+ return 0;
}
static int mvebu_a3700_comphy_pcie_power_on(uint8_t comphy_index,
@@ -862,12 +888,14 @@
ret = polling_with_timeout(LANE_STATUS1_ADDR(PCIE) + COMPHY_SD_ADDR,
TXDCLK_PCLK_EN, TXDCLK_PCLK_EN,
COMPHY_PLL_TIMEOUT, REG_16BIT);
- if (ret)
+ if (ret) {
ERROR("Failed to lock PCIE PLL\n");
+ return -ETIMEDOUT;
+ }
debug_exit();
- return ret;
+ return 0;
}
int mvebu_3700_comphy_power_on(uint8_t comphy_index, uint32_t comphy_mode)
@@ -883,7 +911,7 @@
comphy_mode);
break;
case(COMPHY_SGMII_MODE):
- case(COMPHY_HS_SGMII_MODE):
+ case(COMPHY_2500BASEX_MODE):
ret = mvebu_a3700_comphy_sgmii_power_on(comphy_index,
comphy_mode);
break;
@@ -919,23 +947,22 @@
return 0;
}
-static int mvebu_a3700_comphy_sata_power_off(uint32_t comphy_mode)
+static int mvebu_a3700_comphy_sata_power_off(void)
{
uintptr_t comphy_indir_regs = COMPHY_INDIRECT_REG;
- int mode = COMPHY_GET_MODE(comphy_mode);
uint32_t offset;
debug_enter();
/* Set phy isolation mode */
offset = COMPHY_ISOLATION_CTRL_REG + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, PHY_ISOLATE_MODE,
- PHY_ISOLATE_MODE, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, PHY_ISOLATE_MODE,
+ PHY_ISOLATE_MODE);
/* Power off PLL, Tx, Rx */
offset = COMPHY_POWER_PLL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, 0,
- PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, 0,
+ PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);
debug_exit();
@@ -960,7 +987,7 @@
switch (mode) {
case(COMPHY_SGMII_MODE):
- case(COMPHY_HS_SGMII_MODE):
+ case(COMPHY_2500BASEX_MODE):
err = mvebu_a3700_comphy_sgmii_power_off(comphy_index);
break;
case (COMPHY_USB3_MODE):
@@ -968,7 +995,7 @@
err = mvebu_a3700_comphy_usb3_power_off();
break;
case (COMPHY_SATA_MODE):
- err = mvebu_a3700_comphy_sata_power_off(comphy_mode);
+ err = mvebu_a3700_comphy_sata_power_off();
break;
default:
diff --git a/drivers/marvell/comphy/phy-comphy-common.h b/drivers/marvell/comphy/phy-comphy-common.h
index e3b430a..c599437 100644
--- a/drivers/marvell/comphy/phy-comphy-common.h
+++ b/drivers/marvell/comphy/phy-comphy-common.h
@@ -87,7 +87,7 @@
#define COMPHY_SATA_MODE 0x1
#define COMPHY_SGMII_MODE 0x2 /* SGMII 1G */
-#define COMPHY_HS_SGMII_MODE 0x3 /* SGMII 2.5G */
+#define COMPHY_2500BASEX_MODE 0x3 /* 2500Base-X */
#define COMPHY_USB3H_MODE 0x4
#define COMPHY_USB3D_MODE 0x5
#define COMPHY_PCIE_MODE 0x6
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c
index 86f4c77..e7cde75 100644
--- a/drivers/marvell/comphy/phy-comphy-cp110.c
+++ b/drivers/marvell/comphy/phy-comphy-cp110.c
@@ -30,7 +30,7 @@
/* COMPHY speed macro */
#define COMPHY_SPEED_1_25G 0 /* SGMII 1G */
#define COMPHY_SPEED_2_5G 1
-#define COMPHY_SPEED_3_125G 2 /* SGMII 2.5G */
+#define COMPHY_SPEED_3_125G 2 /* 2500Base-X */
#define COMPHY_SPEED_5G 3
#define COMPHY_SPEED_5_15625G 4 /* XFI 5G */
#define COMPHY_SPEED_6G 5
@@ -191,7 +191,7 @@
case(3):
/* For comphy 3:
* 0x1 = RXAUI_Lane1
- * 0x2 = SGMII/HS-SGMII Port1
+ * 0x2 = SGMII/Base-X Port1
*/
if (mode == COMPHY_RXAUI_MODE)
reg |= COMMON_SELECTOR_COMPHY3_RXAUI <<
@@ -202,20 +202,20 @@
break;
case(4):
/* For comphy 4:
- * 0x1 = SGMII/HS-SGMII Port1, XFI1/SFI1
- * 0x2 = SGMII/HS-SGMII Port0: XFI0/SFI0, RXAUI_Lane0
+ * 0x1 = SGMII/Base-X Port1, XFI1/SFI1
+ * 0x2 = SGMII/Base-X Port0: XFI0/SFI0, RXAUI_Lane0
*
- * We want to check if SGMII1/HS_SGMII1 is the
+ * We want to check if SGMII1 is the
* requested mode in order to determine which value
* should be set (all other modes use the same value)
* so we need to strip the mode, and check the ID
- * because we might handle SGMII0/HS_SGMII0 too.
+ * because we might handle SGMII0 too.
*/
/* TODO: need to distinguish between CP110 and CP115
* as SFI1/XFI1 available only for CP115.
*/
if ((mode == COMPHY_SGMII_MODE ||
- mode == COMPHY_HS_SGMII_MODE ||
+ mode == COMPHY_2500BASEX_MODE ||
mode == COMPHY_SFI_MODE ||
mode == COMPHY_XFI_MODE ||
mode == COMPHY_AP_MODE)
@@ -228,7 +228,7 @@
break;
case(5):
/* For comphy 5:
- * 0x1 = SGMII/HS-SGMII Port2
+ * 0x1 = SGMII/Base-X Port2
* 0x2 = RXAUI Lane1
*/
if (mode == COMPHY_RXAUI_MODE)
@@ -713,7 +713,7 @@
data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
} else if (sgmii_speed == COMPHY_SPEED_3_125G) {
- /* HS SGMII (2.5G), SerDes speed 3.125G */
+ /* 2500Base-X, SerDes speed 3.125G */
data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
} else {
@@ -1730,11 +1730,13 @@
HPIPE_LANE_STATUS1_REG;
data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
mask = data;
- ret = polling_with_timeout(addr, data, mask,
+ data = polling_with_timeout(addr, data, mask,
PLL_LOCK_TIMEOUT,
REG_32BIT);
- if (ret)
+ if (data) {
ERROR("Failed to lock PCIE PLL\n");
+ ret = -ETIMEDOUT;
+ }
}
}
@@ -2343,7 +2345,7 @@
switch (mode) {
case (COMPHY_SGMII_MODE):
- case (COMPHY_HS_SGMII_MODE):
+ case (COMPHY_2500BASEX_MODE):
case (COMPHY_XFI_MODE):
case (COMPHY_SFI_MODE):
case (COMPHY_RXAUI_MODE):
@@ -2378,7 +2380,7 @@
comphy_mode);
break;
case(COMPHY_SGMII_MODE):
- case(COMPHY_HS_SGMII_MODE):
+ case(COMPHY_2500BASEX_MODE):
err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
comphy_index,
comphy_mode);
diff --git a/drivers/mtd/nand/spi_nand.c b/drivers/mtd/nand/spi_nand.c
index d01a119..abb524d 100644
--- a/drivers/mtd/nand/spi_nand.c
+++ b/drivers/mtd/nand/spi_nand.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -286,6 +286,10 @@
return -EINVAL;
}
+ assert((spinand_dev.nand_dev->page_size != 0U) &&
+ (spinand_dev.nand_dev->block_size != 0U) &&
+ (spinand_dev.nand_dev->size != 0U));
+
ret = spi_nand_reset();
if (ret != 0) {
return ret;
@@ -301,12 +305,12 @@
return ret;
}
- ret = spi_nand_quad_enable(id[0]);
+ ret = spi_nand_quad_enable(id[1]);
if (ret != 0) {
return ret;
}
- VERBOSE("SPI_NAND Detected ID 0x%x 0x%x\n", id[0], id[1]);
+ VERBOSE("SPI_NAND Detected ID 0x%x\n", id[1]);
VERBOSE("Page size %i, Block size %i, size %lli\n",
spinand_dev.nand_dev->page_size,
diff --git a/drivers/nxp/dcfg/dcfg.c b/drivers/nxp/dcfg/dcfg.c
index 2e813e7..a988c5d 100644
--- a/drivers/nxp/dcfg/dcfg.c
+++ b/drivers/nxp/dcfg/dcfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 NXP
+ * Copyright 2020-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -43,20 +43,12 @@
reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_SVR_OFFSET);
- soc_info.mfr_id = (reg & SVR_MFR_ID_MASK) >> SVR_MFR_ID_SHIFT;
-#if defined(CONFIG_CHASSIS_3_2)
- soc_info.family = (reg & SVR_FAMILY_MASK) >> SVR_FAMILY_SHIFT;
- soc_info.dev_id = (reg & SVR_DEV_ID_MASK) >> SVR_DEV_ID_SHIFT;
-#endif
+ soc_info.svr_reg.val = reg;
+
/* zero means SEC enabled. */
soc_info.sec_enabled =
(((reg & SVR_SEC_MASK) >> SVR_SEC_SHIFT) == 0) ? true : false;
- soc_info.personality = (reg & SVR_PERSONALITY_MASK)
- >> SVR_PERSONALITY_SHIFT;
- soc_info.maj_ver = (reg & SVR_MAJ_VER_MASK) >> SVR_MAJ_VER_SHIFT;
- soc_info.min_ver = reg & SVR_MIN_VER_MASK;
-
soc_info.is_populated = true;
return (const soc_info_t *) &soc_info;
}
diff --git a/drivers/nxp/ddr/phy-gen2/phy.c b/drivers/nxp/ddr/phy-gen2/phy.c
index 97de1ae..9c84b00 100644
--- a/drivers/nxp/ddr/phy-gen2/phy.c
+++ b/drivers/nxp/ddr/phy-gen2/phy.c
@@ -672,7 +672,7 @@
#ifdef DDR_PLL_FIX
soc_info = get_soc_info();
- if (soc_info->maj_ver == 1) {
+ if (soc_info->svr_reg.bf.maj_ver == 1) {
ps_count[0] = 0x520; /* seq0bdly0 */
ps_count[1] = 0xa41; /* seq0bdly1 */
ps_count[2] = 0x668a; /* seq0bdly2 */
@@ -1093,8 +1093,8 @@
#ifdef ERRATA_DDR_A011396
/* Only apply to DDRC 5.05.00 */
- soc_info = get_soc_info(NXP_DCFG_ADDR);
- if ((soc_info->maj_ver == 1U) && (ip_rev == U(0x50500))) {
+ soc_info = get_soc_info();
+ if ((soc_info->svr_reg.bf.maj_ver == 1U) && (ip_rev == U(0x50500))) {
phy_io_write16(phy,
t_master | csr_dfi_rd_data_cs_dest_map_addr,
0U);
@@ -1890,8 +1890,8 @@
prog_pll_ctrl2(phy, input);
#ifdef DDR_PLL_FIX
soc_info = get_soc_info();
- debug("SOC_SI_REV = %x\n", soc_info->maj_ver);
- if (soc_info->maj_ver == 1) {
+ debug("SOC_SI_REV = %x\n", soc_info->svr_reg.bf.maj_ver);
+ if (soc_info->svr_reg.bf.maj_ver == 1) {
prog_pll_pwr_dn(phy, input);
/*Enable FFE aka TxEqualizationMode for rev1 SI*/
@@ -2601,8 +2601,8 @@
}
#ifdef NXP_APPLY_MAX_CDD
- soc_info = get_soc_info(NXP_DCFG_ADDR);
- if (soc_info->maj_ver == 2) {
+ soc_info = get_soc_info();
+ if (soc_info->svr_reg.bf.maj_ver == 2) {
tcfg0 = regs->timing_cfg[0];
tcfg4 = regs->timing_cfg[4];
rank = findrank(conf->cs_in_use);
diff --git a/drivers/renesas/common/console/rcar_console.S b/drivers/renesas/common/console/rcar_console.S
index 29baa67..b683d7b 100644
--- a/drivers/renesas/common/console/rcar_console.S
+++ b/drivers/renesas/common/console/rcar_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -63,7 +63,7 @@
* ---------------------------------------------
*/
func console_rcar_init
- mov w0, #0
+ mov w0, #1
ret
endfunc console_rcar_init
diff --git a/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c b/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c
index a49510e..f0113f1 100644
--- a/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c
+++ b/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +11,11 @@
#include "rcar_def.h"
#include "../ddr_regs.h"
-#define RCAR_DDR_VERSION "rev.0.01"
+#define RCAR_DDR_VERSION "rev.0.02"
+
+/* Average periodic refresh interval[ns]. Support 3900,7800 */
+#define REFRESH_RATE 3900
+
#if RCAR_LSI != RCAR_D3
#error "Don't have DDR initialize routine."
@@ -44,7 +48,7 @@
mmio_write_32(DBSC_DBTR16, 0x09210507);
mmio_write_32(DBSC_DBTR17, 0x040E0000);
mmio_write_32(DBSC_DBTR18, 0x00000200);
- mmio_write_32(DBSC_DBTR19, 0x012B004B);
+ mmio_write_32(DBSC_DBTR19, 0x0129004B);
mmio_write_32(DBSC_DBTR20, 0x020000FB);
mmio_write_32(DBSC_DBTR21, 0x00040004);
mmio_write_32(DBSC_DBBL, 0x00000000);
@@ -54,8 +58,8 @@
mmio_write_32(DBSC_DBDFICNT_0, 0x00000010);
mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
mmio_write_32(DBSC_DBSCHRW1, 0x00000046);
- mmio_write_32(DBSC_SCFCTST0, 0x0D020D04);
- mmio_write_32(DBSC_SCFCTST1, 0x0306040C);
+ mmio_write_32(DBSC_SCFCTST0, 0x0C050B03);
+ mmio_write_32(DBSC_SCFCTST1, 0x0305030C);
mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A);
mmio_write_32(DBSC_DBCMD, 0x01000001);
@@ -101,7 +105,9 @@
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000004);
- mmio_write_32(DBSC_DBPDRGD_0, 0x0A206F89);
+ mmio_write_32(DBSC_DBPDRGD_0,
+ (uint32_t) (REFRESH_RATE * 928 / 125) - 400
+ + 0x0A300000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000022);
mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000023);
@@ -117,7 +123,11 @@
mmio_write_32(DBSC_DBPDRGA_0, 0x00000028);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000046);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000029);
- mmio_write_32(DBSC_DBPDRGD_0, 0x000000A0);
+ if (REFRESH_RATE > 3900) {
+ mmio_write_32(DBSC_DBPDRGD_0, 0x00000020);
+ } else {
+ mmio_write_32(DBSC_DBPDRGD_0, 0x000000A0);
+ }
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003047);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000020);
@@ -225,8 +235,10 @@
mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
+ mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
+ mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
@@ -296,8 +308,10 @@
mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E);
mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
- mmio_write_32(DBSC_DBCALCNF, 0x0100401B);
- mmio_write_32(DBSC_DBRFCNF1, 0x00080E23);
+ mmio_write_32(DBSC_DBCALCNF,
+ (uint32_t) (64000000 / REFRESH_RATE) + 0x01000000);
+ mmio_write_32(DBSC_DBRFCNF1,
+ (uint32_t) (REFRESH_RATE * 116 / 125) + 0x00080000);
mmio_write_32(DBSC_DBRFCNF2, 0x00010000);
mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001);
mmio_write_32(DBSC_DBRFEN, 0x00000001);
@@ -346,6 +360,19 @@
{
uint32_t i, r2, r3, r5, r6, r7, r12;
+ mmio_write_32(CPG_CPGWPR, 0x5A5AFFFF);
+ mmio_write_32(CPG_CPGWPCR, 0xA5A50000);
+
+ mmio_write_32(CPG_SRCR4, 0x20000000);
+
+ mmio_write_32(0xE61500DC, 0xe2200000);
+ while (!(mmio_read_32(CPG_PLLECR) & BIT(11)))
+ ;
+
+ mmio_write_32(CPG_SRSTCLR4, 0x20000000);
+
+ mmio_write_32(CPG_CPGWPCR, 0xA5A50001);
+
mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
mmio_write_32(DBSC_DBKIND, 0x00000007);
mmio_write_32(DBSC_DBMEMCONF_0_0, 0x0f030a01);
@@ -363,14 +390,14 @@
mmio_write_32(DBSC_DBTR10, 0x0000000C);
mmio_write_32(DBSC_DBTR11, 0x0000000A);
mmio_write_32(DBSC_DBTR12, 0x00120012);
- mmio_write_32(DBSC_DBTR13, 0x000000D0);
+ mmio_write_32(DBSC_DBTR13, 0x000000CE);
mmio_write_32(DBSC_DBTR14, 0x00140005);
mmio_write_32(DBSC_DBTR15, 0x00050004);
mmio_write_32(DBSC_DBTR16, 0x071F0305);
mmio_write_32(DBSC_DBTR17, 0x040C0000);
mmio_write_32(DBSC_DBTR18, 0x00000200);
mmio_write_32(DBSC_DBTR19, 0x01000040);
- mmio_write_32(DBSC_DBTR20, 0x020000D8);
+ mmio_write_32(DBSC_DBTR20, 0x020000D6);
mmio_write_32(DBSC_DBTR21, 0x00040004);
mmio_write_32(DBSC_DBBL, 0x00000000);
mmio_write_32(DBSC_DBODT0, 0x00000001);
@@ -379,8 +406,8 @@
mmio_write_32(DBSC_DBDFICNT_0, 0x00000010);
mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
mmio_write_32(DBSC_DBSCHRW1, 0x00000046);
- mmio_write_32(DBSC_SCFCTST0, 0x0D020C04);
- mmio_write_32(DBSC_SCFCTST1, 0x0305040C);
+ mmio_write_32(DBSC_SCFCTST0, 0x0D050B03);
+ mmio_write_32(DBSC_SCFCTST1, 0x0306030C);
mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A);
mmio_write_32(DBSC_DBCMD, 0x01000001);
@@ -426,13 +453,14 @@
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000004);
- mmio_write_32(DBSC_DBPDRGD_0, 0x08C05FF0);
+ mmio_write_32(DBSC_DBPDRGD_0,
+ (uint32_t) (REFRESH_RATE * 792 / 125) - 400 + 0x08B00000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000022);
mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000023);
mmio_write_32(DBSC_DBPDRGD_0, 0x2D9C0B66);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000024);
- mmio_write_32(DBSC_DBPDRGD_0, 0x2A88C400);
+ mmio_write_32(DBSC_DBPDRGD_0, 0x2A88B400);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000025);
mmio_write_32(DBSC_DBPDRGD_0, 0x30005200);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000026);
@@ -442,7 +470,11 @@
mmio_write_32(DBSC_DBPDRGA_0, 0x00000028);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000046);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000029);
- mmio_write_32(DBSC_DBPDRGD_0, 0x00000098);
+ if (REFRESH_RATE > 3900) {
+ mmio_write_32(DBSC_DBPDRGD_0, 0x00000018);
+ } else {
+ mmio_write_32(DBSC_DBPDRGD_0, 0x00000098);
+ }
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003047);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000020);
@@ -549,9 +581,11 @@
mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
+ mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
+ mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
@@ -620,8 +654,10 @@
mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E);
mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
- mmio_write_32(DBSC_DBCALCNF, 0x0100401B);
- mmio_write_32(DBSC_DBRFCNF1, 0x00080C30);
+ mmio_write_32(DBSC_DBCALCNF,
+ (uint32_t) (64000000 / REFRESH_RATE) + 0x01000000);
+ mmio_write_32(DBSC_DBRFCNF1,
+ (uint32_t) (REFRESH_RATE * 99 / 125) + 0x00080000);
mmio_write_32(DBSC_DBRFCNF2, 0x00010000);
mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001);
mmio_write_32(DBSC_DBRFEN, 0x00000001);
@@ -693,7 +729,7 @@
ddr_mbps = 1600;
}
- NOTICE("BL2: DDR%d\n", ddr_mbps);
+ NOTICE("BL2: DDR%d(%s)\n", ddr_mbps, RCAR_DDR_VERSION);
return 0;
}
diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c
index c3e8319..17d7aaa 100644
--- a/drivers/renesas/common/io/io_rcar.c
+++ b/drivers/renesas/common/io/io_rcar.c
@@ -151,6 +151,9 @@
return -EINVAL;
}
+#define MFISBTSTSR (0xE6260604U)
+#define MFISBTSTSR_BOOT_PARTITION (0x00000010U)
+
static int32_t file_to_offset(const int32_t name, uintptr_t *offset,
uint32_t *cert, uint32_t *no_load,
uintptr_t *partition)
@@ -169,6 +172,9 @@
}
*offset = rcar_image_header[addr];
+
+ if (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)
+ *offset += 0x800000;
*cert = RCAR_CERT_SIZE;
*cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr);
*cert += RCAR_SDRAM_certESS;
diff --git a/drivers/renesas/common/pwrc/pwrc.c b/drivers/renesas/common/pwrc/pwrc.c
index 3f60fe6..4ebf049 100644
--- a/drivers/renesas/common/pwrc/pwrc.c
+++ b/drivers/renesas/common/pwrc/pwrc.c
@@ -44,6 +44,7 @@
#define CPU_PWR_OFF (0x00000003U)
#define RCAR_PSTR_MASK (0x00000003U)
#define ST_ALL_STANDBY (0x00003333U)
+#define SYSCEXTMASK_EXTMSK0 (0x00000001U)
/* Suspend to ram */
#define DBSC4_REG_BASE (0xE6790000U)
#define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U)
@@ -191,6 +192,8 @@
{
uintptr_t reg_pwrsr, reg_cpumcr, reg_pwron, reg_pwrer;
uint32_t c, sysc_reg_bit;
+ uint32_t lsi_product;
+ uint32_t lsi_cut;
c = rcar_pwrc_get_mpidr_cluster(mpidr);
reg_cpumcr = IS_CA57(c) ? RCAR_CA57CPUCMCR : RCAR_CA53CPUCMCR;
@@ -205,6 +208,17 @@
if (mmio_read_32(reg_cpumcr) != 0)
mmio_write_32(reg_cpumcr, 0);
+ lsi_product = mmio_read_32((uintptr_t)RCAR_PRR);
+ lsi_cut = lsi_product & PRR_CUT_MASK;
+ lsi_product &= PRR_PRODUCT_MASK;
+
+ if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) ||
+ lsi_product == PRR_PRODUCT_H3 ||
+ lsi_product == PRR_PRODUCT_M3N ||
+ lsi_product == PRR_PRODUCT_E3) {
+ mmio_setbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0);
+ }
+
mmio_setbits_32(RCAR_SYSCIER, sysc_reg_bit);
mmio_setbits_32(RCAR_SYSCIMR, sysc_reg_bit);
@@ -216,7 +230,15 @@
while ((mmio_read_32(RCAR_SYSCISR) & sysc_reg_bit) == 0)
;
- mmio_write_32(RCAR_SYSCISR, sysc_reg_bit);
+ mmio_write_32(RCAR_SYSCISCR, sysc_reg_bit);
+
+ if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) ||
+ lsi_product == PRR_PRODUCT_H3 ||
+ lsi_product == PRR_PRODUCT_M3N ||
+ lsi_product == PRR_PRODUCT_E3) {
+ mmio_clrbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0);
+ }
+
while ((mmio_read_32(reg_pwrsr) & STATUS_PWRUP) == 0)
;
}
diff --git a/drivers/renesas/common/scif/scif.S b/drivers/renesas/common/scif/scif.S
index beb8dd8..72b5b4b 100644
--- a/drivers/renesas/common/scif/scif.S
+++ b/drivers/renesas/common/scif/scif.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -79,7 +79,7 @@
SCSMR_STOP_1 + \
SCSMR_CKS_DIV1)
#define SCBRR_115200BPS (17)
-#define SCBRR_115200BPSON (16)
+#define SCBRR_115200BPS_D3_SSCG (16)
#define SCBRR_115200BPS_E3_SSCG (15)
#define SCBRR_230400BPS (8)
@@ -216,26 +216,38 @@
and w1, w1, #PRR_PRODUCT_MASK
mov w2, #PRR_PRODUCT_D3
cmp w1, w2
- beq 4f
+ beq 5f
and w1, w1, #PRR_PRODUCT_MASK
mov w2, #PRR_PRODUCT_E3
cmp w1, w2
- bne 5f
+ bne 4f
+ /* When SSCG(MD12) on (E3) */
ldr x1, =RST_MODEMR
ldr w1, [x1]
and w1, w1, #MODEMR_MD12
mov w2, #MODEMR_MD12
cmp w1, w2
- bne 5f
+ bne 4f
+ /* When SSCG(MD12) on (E3) */
mov w1, #SCBRR_115200BPS_E3_SSCG
b 2f
5:
- mov w1, #SCBRR_115200BPS
+ /* In case of D3 */
+ ldr x1, =RST_MODEMR
+ ldr w1, [x1]
+ and w1, w1, #MODEMR_MD12
+ mov w2, #MODEMR_MD12
+ cmp w1, w2
+ bne 4f
+
+ /* When SSCG(MD12) on (D3) */
+ mov w1, #SCBRR_115200BPS_D3_SSCG
b 2f
4:
- mov w1, #SCBRR_115200BPSON
+ /* In case of H3/M3/M3N or when SSCG(MD12) is off in E3/D3 */
+ mov w1, #SCBRR_115200BPS
b 2f
3:
mov w1, #SCBRR_230400BPS
diff --git a/drivers/renesas/common/watchdog/swdt.c b/drivers/renesas/common/watchdog/swdt.c
index 1a351ca..29ef6f4 100644
--- a/drivers/renesas/common/watchdog/swdt.c
+++ b/drivers/renesas/common/watchdog/swdt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -78,7 +78,7 @@
void rcar_swdt_init(void)
{
uint32_t rmsk, sr;
-#if (RCAR_LSI != RCAR_E3) && (RCAR_LSI != RZ_G2E)
+#if (RCAR_LSI != RCAR_E3) && (RCAR_LSI != RCAR_D3) && (RCAR_LSI != RZ_G2E)
uint32_t reg, val, product_cut, chk_data;
reg = mmio_read_32(RCAR_PRR);
@@ -96,6 +96,8 @@
#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2E)
mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_7p81k);
+#elif (RCAR_LSI == RCAR_D3)
+ mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_8p13k);
#else
val = WTCNT_UPPER_BYTE;
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index 6ada96a..80b6408 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -56,6 +56,7 @@
_HSI_KER = NB_OSC,
_HSE_KER,
_HSE_KER_DIV2,
+ _HSE_RTC,
_CSI_KER,
_PLL1_P,
_PLL1_Q,
@@ -107,7 +108,7 @@
_USBPHY_SEL,
_USBO_SEL,
_MPU_SEL,
- _PER_SEL,
+ _CKPER_SEL,
_RTC_SEL,
_PARENT_SEL_NB,
_UNKNOWN_SEL = 0xff,
@@ -125,6 +126,7 @@
[_HSI_KER] = CK_HSI,
[_HSE_KER] = CK_HSE,
[_HSE_KER_DIV2] = CK_HSE_DIV2,
+ [_HSE_RTC] = _UNKNOWN_ID,
[_CSI_KER] = CK_CSI,
[_PLL1_P] = PLL1_P,
[_PLL1_Q] = PLL1_Q,
@@ -490,7 +492,7 @@
};
static const uint8_t rtc_parents[] = {
- _UNKNOWN_ID, _LSE, _LSI, _HSE
+ _UNKNOWN_ID, _LSE, _LSI, _HSE_RTC
};
static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
@@ -502,7 +504,7 @@
_CLK_PARENT_SEL(UART1, RCC_UART1CKSELR, usart1_parents),
_CLK_PARENT_SEL(RNG1, RCC_RNG1CKSELR, rng1_parents),
_CLK_PARENT_SEL(MPU, RCC_MPCKSELR, mpu_parents),
- _CLK_PARENT_SEL(PER, RCC_CPERCKSELR, per_parents),
+ _CLK_PARENT_SEL(CKPER, RCC_CPERCKSELR, per_parents),
_CLK_PARENT_SEL(RTC, RCC_BDCR, rtc_parents),
_CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents),
_CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents),
@@ -587,6 +589,7 @@
[_HSI_KER] = "HSI_KER",
[_HSE_KER] = "HSE_KER",
[_HSE_KER_DIV2] = "HSE_KER_DIV2",
+ [_HSE_RTC] = "HSE_RTC",
[_CSI_KER] = "CSI_KER",
[_PLL1_P] = "PLL1_P",
[_PLL1_Q] = "PLL1_Q",
@@ -969,6 +972,10 @@
case _HSE_KER_DIV2:
clock = stm32mp1_clk_get_fixed(_HSE) >> 1;
break;
+ case _HSE_RTC:
+ clock = stm32mp1_clk_get_fixed(_HSE);
+ clock /= (mmio_read_32(rcc_base + RCC_RTCDIVR) & RCC_DIVR_DIV_MASK) + 1U;
+ break;
case _LSI:
clock = stm32mp1_clk_get_fixed(_LSI);
break;
@@ -1652,7 +1659,7 @@
(clksrc != (uint32_t)CLK_RTC_DISABLED)) {
mmio_clrsetbits_32(address,
RCC_BDCR_RTCSRC_MASK,
- clksrc << RCC_BDCR_RTCSRC_SHIFT);
+ (clksrc & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT);
mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
}
@@ -2152,6 +2159,7 @@
case _HSE:
case _HSE_KER:
case _HSE_KER_DIV2:
+ case _HSE_RTC:
case _LSE:
break;
@@ -2210,6 +2218,7 @@
DDRC2, DDRC2LP,
DDRCAPB, DDRPHYCAPB, DDRPHYCAPBLP,
DDRPHYC, DDRPHYCLP,
+ RTCAPB,
TZC1, TZC2,
TZPC,
STGEN_K,
@@ -2218,10 +2227,6 @@
for (idx = 0U; idx < ARRAY_SIZE(secure_enable); idx++) {
stm32mp_clk_enable(secure_enable[idx]);
}
-
- if (!stm32mp_is_single_core()) {
- stm32mp1_clk_enable_secure(RTCAPB);
- }
}
int stm32mp1_clk_probe(void)
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index 8333f6d..2101171 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -161,7 +161,7 @@
* @param fdt: Device tree reference
* @return: Node offset or a negative value on error
*/
-int fdt_get_rcc_node(void *fdt)
+static int fdt_get_rcc_node(void *fdt)
{
return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
}
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index 686b18b..2b8879a 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -45,7 +45,12 @@
/* Check the input base address */
cmp r0, #0
beq core_init_fail
-#if defined(IMAGE_BL2)
+#if !defined(IMAGE_BL2)
+ /* Skip UART initialization if it is already enabled */
+ ldr r3, [r0, #USART_CR1]
+ ands r3, r3, #USART_CR1_UE
+ bne 1f
+#endif /* IMAGE_BL2 */
/* Check baud rate and uart clock for sanity */
cmp r1, #0
beq core_init_fail
@@ -78,7 +83,7 @@
ldr r3, [r0, #USART_ISR]
tst r3, #USART_ISR_TEACK
beq teack_loop
-#endif /* IMAGE_BL2 */
+1:
mov r0, #1
bx lr
core_init_fail:
diff --git a/fdts/juno-ethosn.dtsi b/fdts/juno-ethosn.dtsi
index 87ab378..e2f3355 100644
--- a/fdts/juno-ethosn.dtsi
+++ b/fdts/juno-ethosn.dtsi
@@ -4,19 +4,21 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/*
+ * For examples of multi-core and multi-device NPU, refer to the examples given in the
+ * Arm Ethos-N NPU driver stack.
+ * https://github.com/ARM-software/ethos-n-driver-stack
+ */
+
/ {
#address-cells = <2>;
#size-cells = <2>;
- ethosn: ethosn@6f300000 {
+ ethosn0: ethosn@6f300000 {
compatible = "ethosn";
reg = <0 0x6f300000 0 0x00100000>;
status = "okay";
- /*
- * Single-core NPU. For multi-core NPU, additional core nodes
- * and reg values must be added.
- */
core0 {
compatible = "ethosn-core";
status = "okay";
diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi
new file mode 100644
index 0000000..da95b25
--- /dev/null
+++ b/fdts/stm32mp15-bl2.dtsi
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2020-2021 - All Rights Reserved
+ */
+
+/ {
+ cpus {
+ /delete-node/ cpu@1;
+ };
+
+ /delete-node/ psci;
+
+ soc {
+ /delete-node/ timer@40006000;
+ /delete-node/ timer@44006000;
+ /delete-node/ pwr_mcu@50001014;
+ /delete-node/ cryp@54001000;
+ /delete-node/ rng@54003000;
+ /delete-node/ spi@5c001000;
+ /delete-node/ rtc@5c004000;
+ /delete-node/ etzpc@5c007000;
+ /delete-node/ stgen@5c008000;
+ /delete-node/ i2c@5c009000;
+ /delete-node/ tamp@5c00a000;
+
+ pin-controller@50002000 {
+ /delete-node/ rtc-out2-rmp-pins-0;
+ };
+ };
+
+#if !STM32MP_USE_STM32IMAGE
+ /*
+ * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in
+ * network order (big endian)
+ */
+
+ st-io_policies {
+ fip-handles {
+ compatible = "st,io-fip-handle";
+ fw_cfg_uuid = "5807e16a-8459-47be-8ed5-648e8dddab0e";
+ bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
+ bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288";
+ bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
+ bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
+ hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
+ tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
+ nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+ };
+ };
+#endif /* !STM32MP_USE_STM32IMAGE */
+};
diff --git a/fdts/stm32mp15-bl32.dtsi b/fdts/stm32mp15-bl32.dtsi
new file mode 100644
index 0000000..f005d56
--- /dev/null
+++ b/fdts/stm32mp15-bl32.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2020-2021 - All Rights Reserved
+ */
+
+/ {
+ aliases {
+ /delete-property/ mmc0;
+ /delete-property/ mmc1;
+ };
+
+ cpus {
+ /delete-node/ cpu@1;
+ };
+
+ /delete-node/ psci;
+
+ soc {
+ /delete-node/ usb-otg@49000000;
+ /delete-node/ hash@54002000;
+ /delete-node/ memory-controller@58002000;
+ /delete-node/ spi@58003000;
+ /delete-node/ sdmmc@58005000;
+ /delete-node/ sdmmc@58007000;
+ /delete-node/ usbphyc@5a006000;
+ /delete-node/ spi@5c001000;
+ /delete-node/ stgen@5c008000;
+ /delete-node/ i2c@5c009000;
+
+ pin-controller@50002000 {
+ /delete-node/ fmc-0;
+ /delete-node/ qspi-clk-0;
+ /delete-node/ qspi-bk1-0;
+ /delete-node/ qspi-bk2-0;
+ /delete-node/ sdmmc1-b4-0;
+ /delete-node/ sdmmc1-dir-0;
+ /delete-node/ sdmmc2-b4-0;
+ /delete-node/ sdmmc2-b4-1;
+ /delete-node/ sdmmc2-d47-0;
+ /delete-node/ usbotg_hs-0;
+ /delete-node/ usbotg-fs-dp-dm-0;
+ };
+ };
+};
diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi
new file mode 100644
index 0000000..8aece28
--- /dev/null
+++ b/fdts/stm32mp15-fw-config.dtsi
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+#include <dt-bindings/soc/stm32mp15-tzc400.h>
+
+#include <platform_def.h>
+
+#ifndef DDR_SIZE
+#error "DDR_SIZE is not defined"
+#endif
+
+#define DDR_NS_BASE STM32MP_DDR_BASE
+#ifdef AARCH32_SP_OPTEE
+/* OP-TEE reserved shared memory: located at DDR top */
+#define DDR_SHARE_SIZE STM32MP_DDR_SHMEM_SIZE
+#define DDR_SHARE_BASE (STM32MP_DDR_BASE + (DDR_SIZE - DDR_SHARE_SIZE))
+/* OP-TEE secure memory: located right below OP-TEE reserved shared memory */
+#define DDR_SEC_SIZE STM32MP_DDR_S_SIZE
+#define DDR_SEC_BASE (DDR_SHARE_BASE - DDR_SEC_SIZE)
+#define DDR_NS_SIZE (DDR_SEC_BASE - DDR_NS_BASE)
+#else /* !AARCH32_SP_OPTEE */
+#define DDR_NS_SIZE DDR_SIZE
+#endif /* AARCH32_SP_OPTEE */
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ hw-config {
+ load-address = <0x0 STM32MP_HW_CONFIG_BASE>;
+ max-size = <STM32MP_HW_CONFIG_MAX_SIZE>;
+ id = <HW_CONFIG_ID>;
+ };
+
+ nt_fw {
+ load-address = <0x0 STM32MP_BL33_BASE>;
+ max-size = <STM32MP_BL33_MAX_SIZE>;
+ id = <BL33_IMAGE_ID>;
+ };
+
+#ifdef AARCH32_SP_OPTEE
+ tos_fw {
+ load-address = <0x0 STM32MP_OPTEE_BASE>;
+ max-size = <STM32MP_OPTEE_SIZE>;
+ id = <BL32_IMAGE_ID>;
+ };
+#else
+ tos_fw {
+ load-address = <0x0 STM32MP_BL32_BASE>;
+ max-size = <STM32MP_BL32_SIZE>;
+ id = <BL32_IMAGE_ID>;
+ };
+
+ tos_fw-config {
+ load-address = <0x0 STM32MP_BL32_DTB_BASE>;
+ max-size = <STM32MP_BL32_DTB_SIZE>;
+ id = <TOS_FW_CONFIG_ID>;
+ };
+#endif
+ };
+
+ st-mem-firewall {
+ compatible = "st,mem-firewall";
+#ifdef AARCH32_SP_OPTEE
+ memory-ranges = <
+ DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
+ DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0
+ DDR_SHARE_BASE DDR_SHARE_SIZE TZC_REGION_S_NONE
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)>;
+#else
+ memory-ranges = <
+ DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR>;
+#endif
+ };
+};
diff --git a/fdts/stm32mp157a-avenger96-fw-config.dts b/fdts/stm32mp157a-avenger96-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157a-avenger96-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157a-dk1-fw-config.dts b/fdts/stm32mp157a-dk1-fw-config.dts
new file mode 100644
index 0000000..83116d1
--- /dev/null
+++ b/fdts/stm32mp157a-dk1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x20000000 /* 512MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157a-ed1-fw-config.dts b/fdts/stm32mp157a-ed1-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157a-ed1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157a-ev1-fw-config.dts b/fdts/stm32mp157a-ev1-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157a-ev1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-dk2-fw-config.dts b/fdts/stm32mp157c-dk2-fw-config.dts
new file mode 100644
index 0000000..83116d1
--- /dev/null
+++ b/fdts/stm32mp157c-dk2-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x20000000 /* 512MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-ed1-fw-config.dts b/fdts/stm32mp157c-ed1-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157c-ed1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-ev1-fw-config.dts b/fdts/stm32mp157c-ev1-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157c-ev1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-lxa-mc1-fw-config.dts b/fdts/stm32mp157c-lxa-mc1-fw-config.dts
new file mode 100644
index 0000000..9ee09e9
--- /dev/null
+++ b/fdts/stm32mp157c-lxa-mc1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x20000000 /* 512MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-odyssey-fw-config.dts b/fdts/stm32mp157c-odyssey-fw-config.dts
new file mode 100644
index 0000000..9ee09e9
--- /dev/null
+++ b/fdts/stm32mp157c-odyssey-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x20000000 /* 512MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157d-dk1-fw-config.dts b/fdts/stm32mp157d-dk1-fw-config.dts
new file mode 100644
index 0000000..83116d1
--- /dev/null
+++ b/fdts/stm32mp157d-dk1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x20000000 /* 512MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157d-ed1-fw-config.dts b/fdts/stm32mp157d-ed1-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157d-ed1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157d-ev1-fw-config.dts b/fdts/stm32mp157d-ev1-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157d-ev1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157f-dk2-fw-config.dts b/fdts/stm32mp157f-dk2-fw-config.dts
new file mode 100644
index 0000000..83116d1
--- /dev/null
+++ b/fdts/stm32mp157f-dk2-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x20000000 /* 512MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157f-ed1-fw-config.dts b/fdts/stm32mp157f-ed1-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157f-ed1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157f-ev1-fw-config.dts b/fdts/stm32mp157f-ev1-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157f-ev1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index 54ec009..7221b62 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -102,6 +102,16 @@
/* CSSELR definitions */
#define LEVEL_SHIFT U(1)
+/* ID_DFR0_EL1 definitions */
+#define ID_DFR0_COPTRC_SHIFT U(12)
+#define ID_DFR0_COPTRC_MASK U(0xf)
+#define ID_DFR0_COPTRC_SUPPORTED U(1)
+#define ID_DFR0_COPTRC_LENGTH U(4)
+#define ID_DFR0_TRACEFILT_SHIFT U(28)
+#define ID_DFR0_TRACEFILT_MASK U(0xf)
+#define ID_DFR0_TRACEFILT_SUPPORTED U(1)
+#define ID_DFR0_TRACEFILT_LENGTH U(4)
+
/* ID_DFR1_EL1 definitions */
#define ID_DFR1_MTPMU_SHIFT U(0)
#define ID_DFR1_MTPMU_MASK U(0xf)
@@ -173,6 +183,7 @@
#define SDCR_SPD_DISABLE U(0x2)
#define SDCR_SPD_ENABLE U(0x3)
#define SDCR_SCCD_BIT (U(1) << 23)
+#define SDCR_TTRF_BIT (U(1) << 19)
#define SDCR_SPME_BIT (U(1) << 17)
#define SDCR_RESET_VAL U(0x0)
#define SDCR_MTPME_BIT (U(1) << 28)
@@ -516,6 +527,7 @@
#define CTR p15, 0, c0, c0, 1
#define CNTFRQ p15, 0, c14, c0, 0
#define ID_MMFR4 p15, 0, c0, c2, 6
+#define ID_DFR0 p15, 0, c0, c1, 2
#define ID_DFR1 p15, 0, c0, c3, 5
#define ID_PFR0 p15, 0, c0, c1, 0
#define ID_PFR1 p15, 0, c0, c1, 1
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index 726baf5..0330989 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -217,6 +217,7 @@
DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
DEFINE_COPROCR_READ_FUNC(midr, MIDR)
DEFINE_COPROCR_READ_FUNC(id_mmfr4, ID_MMFR4)
+DEFINE_COPROCR_READ_FUNC(id_dfr0, ID_DFR0)
DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
DEFINE_COPROCR_READ_FUNC(isr, ISR)
@@ -282,6 +283,7 @@
DEFINE_COPROCR_RW_FUNCS_64(icc_sgi0r_el1, ICC_SGI0R_EL1_64)
DEFINE_COPROCR_WRITE_FUNC_64(icc_sgi1r, ICC_SGI1R_EL1_64)
+DEFINE_COPROCR_RW_FUNCS(sdcr, SDCR)
DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index 7fff4c7..65f9a8e 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -63,11 +63,23 @@
* cp11 field is ignored, but is set to same value as cp10. The cp10
* field is set to allow access to Advanced SIMD and floating point
* features from both Security states.
+ *
+ * NSACR.NSTRCDIS: When system register trace implemented, Set to one
+ * so that NS System register accesses to all implemented trace
+ * registers are disabled.
+ * When system register trace is not implemented, this bit is RES0 and
+ * hence set to zero.
* ---------------------------------------------------------------------
*/
ldcopr r0, NSACR
and r0, r0, #NSACR_IMP_DEF_MASK
orr r0, r0, #(NSACR_RESET_VAL | NSACR_ENABLE_FP_ACCESS)
+ ldcopr r1, ID_DFR0
+ ubfx r1, r1, #ID_DFR0_COPTRC_SHIFT, #ID_DFR0_COPTRC_LENGTH
+ cmp r1, #ID_DFR0_COPTRC_SUPPORTED
+ bne 1f
+ orr r0, r0, #NSTRCDIS_BIT
+1:
stcopr r0, NSACR
isb
@@ -119,9 +131,22 @@
* in Secure state. This bit is RES0 in versions of the architecture
* earlier than ARMv8.5, setting it to 1 doesn't have any effect on
* them.
+ *
+ * SDCR.TTRF: Set to one so that access to trace filter control
+ * registers in non-monitor mode generate Monitor trap exception,
+ * unless the access generates a higher priority exception when
+ * trace filter control(FEAT_TRF) is implemented.
+ * When FEAT_TRF is not implemented, this bit is RES0.
* ---------------------------------------------------------------------
*/
- ldr r0, =(SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE) | SDCR_SCCD_BIT)
+ ldr r0, =((SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE) | \
+ SDCR_SCCD_BIT) & ~SDCR_TTRF_BIT)
+ ldcopr r1, ID_DFR0
+ ubfx r1, r1, #ID_DFR0_TRACEFILT_SHIFT, #ID_DFR0_TRACEFILT_LENGTH
+ cmp r1, #ID_DFR0_TRACEFILT_SUPPORTED
+ bne 1f
+ orr r0, r0, #SDCR_TTRF_BIT
+1:
stcopr r0, SDCR
/* ---------------------------------------------------------------------
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index c12dbc4..1b3ae02 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -188,10 +188,25 @@
#define EL_IMPL_A64ONLY ULL(1)
#define EL_IMPL_A64_A32 ULL(2)
+/* ID_AA64DFR0_EL1.TraceVer definitions */
+#define ID_AA64DFR0_TRACEVER_SHIFT U(4)
+#define ID_AA64DFR0_TRACEVER_MASK ULL(0xf)
+#define ID_AA64DFR0_TRACEVER_SUPPORTED ULL(1)
+#define ID_AA64DFR0_TRACEVER_LENGTH U(4)
+#define ID_AA64DFR0_TRACEFILT_SHIFT U(40)
+#define ID_AA64DFR0_TRACEFILT_MASK U(0xf)
+#define ID_AA64DFR0_TRACEFILT_SUPPORTED U(1)
+#define ID_AA64DFR0_TRACEFILT_LENGTH U(4)
+
/* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
#define ID_AA64DFR0_PMS_SHIFT U(32)
#define ID_AA64DFR0_PMS_MASK ULL(0xf)
+/* ID_AA64DFR0_EL1.TraceBuffer definitions */
+#define ID_AA64DFR0_TRACEBUFFER_SHIFT U(44)
+#define ID_AA64DFR0_TRACEBUFFER_MASK ULL(0xf)
+#define ID_AA64DFR0_TRACEBUFFER_SUPPORTED ULL(1)
+
/* ID_AA64DFR0_EL1.MTPMU definitions (for ARMv8.6+) */
#define ID_AA64DFR0_MTPMU_SHIFT U(48)
#define ID_AA64DFR0_MTPMU_MASK ULL(0xf)
@@ -266,6 +281,11 @@
#define ID_AA64MMFR1_EL1_VHE_SHIFT U(8)
#define ID_AA64MMFR1_EL1_VHE_MASK ULL(0xf)
+#define ID_AA64MMFR1_EL1_HCX_SHIFT U(40)
+#define ID_AA64MMFR1_EL1_HCX_MASK ULL(0xf)
+#define ID_AA64MMFR1_EL1_HCX_SUPPORTED ULL(0x1)
+#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED ULL(0x0)
+
/* ID_AA64MMFR2_EL1 definitions */
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
@@ -414,6 +434,7 @@
#define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5))
#define SCR_TWEDEL_SHIFT U(30)
#define SCR_TWEDEL_MASK ULL(0xf)
+#define SCR_HXEn_BIT (UL(1) << 38)
#define SCR_AMVOFFEN_BIT (UL(1) << 35)
#define SCR_TWEDEn_BIT (UL(1) << 29)
#define SCR_ECVEN_BIT (UL(1) << 28)
@@ -442,6 +463,9 @@
#define MDCR_EnPMSN_BIT (ULL(1) << 36)
#define MDCR_MPMX_BIT (ULL(1) << 35)
#define MDCR_MCCD_BIT (ULL(1) << 34)
+#define MDCR_NSTB(x) ((x) << 24)
+#define MDCR_NSTB_EL1 ULL(0x3)
+#define MDCR_NSTBE (ULL(1) << 26)
#define MDCR_MTPME_BIT (ULL(1) << 28)
#define MDCR_TDCC_BIT (ULL(1) << 27)
#define MDCR_SCCD_BIT (ULL(1) << 23)
@@ -465,6 +489,8 @@
/* MDCR_EL2 definitions */
#define MDCR_EL2_MTPME (U(1) << 28)
#define MDCR_EL2_HLP (U(1) << 26)
+#define MDCR_EL2_E2TB(x) ((x) << 24)
+#define MDCR_EL2_E2TB_EL1 U(0x3)
#define MDCR_EL2_HCCD (U(1) << 23)
#define MDCR_EL2_TTRF (U(1) << 19)
#define MDCR_EL2_HPMD (U(1) << 17)
@@ -496,13 +522,18 @@
#define VTTBR_BADDR_SHIFT U(0)
/* HCR definitions */
+#define HCR_RESET_VAL ULL(0x0)
#define HCR_AMVOFFEN_BIT (ULL(1) << 51)
+#define HCR_TEA_BIT (ULL(1) << 47)
#define HCR_API_BIT (ULL(1) << 41)
#define HCR_APK_BIT (ULL(1) << 40)
#define HCR_E2H_BIT (ULL(1) << 34)
+#define HCR_HCD_BIT (ULL(1) << 29)
#define HCR_TGE_BIT (ULL(1) << 27)
#define HCR_RW_SHIFT U(31)
#define HCR_RW_BIT (ULL(1) << HCR_RW_SHIFT)
+#define HCR_TWE_BIT (ULL(1) << 14)
+#define HCR_TWI_BIT (ULL(1) << 13)
#define HCR_AMO_BIT (ULL(1) << 5)
#define HCR_IMO_BIT (ULL(1) << 4)
#define HCR_FMO_BIT (ULL(1) << 3)
@@ -1124,6 +1155,16 @@
#define GCR_EL1 S3_0_C1_C0_6
/*******************************************************************************
+ * FEAT_HCX - Extended Hypervisor Configuration Register
+ ******************************************************************************/
+#define HCRX_EL2 S3_4_C1_C2_2
+#define HCRX_EL2_FGTnXS_BIT (UL(1) << 4)
+#define HCRX_EL2_FnXS_BIT (UL(1) << 3)
+#define HCRX_EL2_EnASR_BIT (UL(1) << 2)
+#define HCRX_EL2_EnALS_BIT (UL(1) << 1)
+#define HCRX_EL2_EnAS0_BIT (UL(1) << 0)
+
+/*******************************************************************************
* Definitions for DynamicIQ Shared Unit registers
******************************************************************************/
#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index dc0b7f3..3ff67e5 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -117,4 +117,10 @@
ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
}
+static inline bool is_feat_hcx_present(void)
+{
+ return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) &
+ ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED);
+}
+
#endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index a41b325..72b87c8 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -233,8 +233,10 @@
void disable_mmu_el1(void);
void disable_mmu_el3(void);
+void disable_mpu_el2(void);
void disable_mmu_icache_el1(void);
void disable_mmu_icache_el3(void);
+void disable_mpu_icache_el2(void);
/*******************************************************************************
* Misc. accessor prototypes
@@ -532,6 +534,9 @@
DEFINE_SYSREG_READ_FUNC(rndr)
DEFINE_SYSREG_READ_FUNC(rndrrs)
+/* FEAT_HCX Register */
+DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
+
/* DynamIQ Shared Unit power management */
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S
new file mode 100644
index 0000000..c57a1ec
--- /dev/null
+++ b/include/arch/aarch64/el2_common_macros.S
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EL2_COMMON_MACROS_S
+#define EL2_COMMON_MACROS_S
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <context.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+#include <platform_def.h>
+
+ /*
+ * Helper macro to initialise system registers at EL2.
+ */
+ .macro el2_arch_init_common
+
+ /* ---------------------------------------------------------------------
+ * SCTLR_EL2 has already been initialised - read current value before
+ * modifying.
+ *
+ * SCTLR_EL2.I: Enable the instruction cache.
+ *
+ * SCTLR_EL2.SA: Enable Stack Alignment check. A SP alignment fault
+ * exception is generated if a load or store instruction executed at
+ * EL2 uses the SP as the base address and the SP is not aligned to a
+ * 16-byte boundary.
+ *
+ * SCTLR_EL2.A: Enable Alignment fault checking. All instructions that
+ * load or store one or more registers have an alignment check that the
+ * address being accessed is aligned to the size of the data element(s)
+ * being accessed.
+ * ---------------------------------------------------------------------
+ */
+ mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+ mrs x0, sctlr_el2
+ orr x0, x0, x1
+ msr sctlr_el2, x0
+ isb
+
+ /* ---------------------------------------------------------------------
+ * Initialise HCR_EL2, setting all fields rather than relying on HW.
+ * All fields are architecturally UNKNOWN on reset. The following fields
+ * do not change during the TF lifetime. The remaining fields are set to
+ * zero here but are updated ahead of transitioning to a lower EL in the
+ * function cm_init_context_common().
+ *
+ * HCR_EL2.TWE: Set to zero so that execution of WFE instructions at
+ * EL2, EL1 and EL0 are not trapped to EL2.
+ *
+ * HCR_EL2.TWI: Set to zero so that execution of WFI instructions at
+ * EL2, EL1 and EL0 are not trapped to EL2.
+ *
+ * HCR_EL2.HCD: Set to zero to enable HVC calls at EL1 and above,
+ * from both Security states and both Execution states.
+ *
+ * HCR_EL2.TEA: Set to one to route External Aborts and SError
+ * Interrupts to EL2 when executing at any EL.
+ *
+ * HCR_EL2.{API,APK}: For Armv8.3 pointer authentication feature,
+ * disable traps to EL2 when accessing key registers or using
+ * pointer authentication instructions from lower ELs.
+ * ---------------------------------------------------------------------
+ */
+ mov_imm x0, ((HCR_RESET_VAL | HCR_TEA_BIT) \
+ & ~(HCR_TWE_BIT | HCR_TWI_BIT | HCR_HCD_BIT))
+#if CTX_INCLUDE_PAUTH_REGS
+ /*
+ * If the pointer authentication registers are saved during world
+ * switches, enable pointer authentication everywhere, as it is safe to
+ * do so.
+ */
+ orr x0, x0, #(HCR_API_BIT | HCR_APK_BIT)
+#endif /* CTX_INCLUDE_PAUTH_REGS */
+ msr hcr_el2, x0
+
+ /* ---------------------------------------------------------------------
+ * Initialise MDCR_EL2, setting all fields rather than relying on
+ * hw. Some fields are architecturally UNKNOWN on reset.
+ *
+ * MDCR_EL2.SDD: Set to one to disable AArch64 Secure self-hosted
+ * debug. Debug exceptions, other than Breakpoint Instruction
+ * exceptions, are disabled from all ELs in Secure state.
+ *
+ * MDCR_EL2.TDOSA: Set to zero so that EL2 and EL2 System register
+ * access to the powerdown debug registers do not trap to EL2.
+ *
+ * MDCR_EL2.TDA: Set to zero to allow EL0, EL1 and EL2 access to the
+ * debug registers, other than those registers that are controlled by
+ * MDCR_EL2.TDOSA.
+ *
+ * MDCR_EL2.TPM: Set to zero so that EL0, EL1, and EL2 System
+ * register accesses to all Performance Monitors registers do not trap
+ * to EL2.
+ *
+ * MDCR_EL2.SCCD: Set to one so that cycle counting by PMCCNTR_EL0
+ * is prohibited in Secure state. This bit is RES0 in versions of the
+ * architecture with FEAT_PMUv3p5 not implemented, setting it to 1
+ * doesn't have any effect on them.
+ *
+ * MDCR_EL2.MCCD: Set to one so that cycle counting by PMCCNTR_EL0
+ * is prohibited in EL2. This bit is RES0 in versions of the
+ * architecture with FEAT_PMUv3p7 not implemented, setting it to 1
+ * doesn't have any effect on them.
+ *
+ * MDCR_EL2.SPME: Set to zero so that event counting by the program-
+ * mable counters PMEVCNTR<n>_EL0 is prohibited in Secure state. If
+ * ARMv8.2 Debug is not implemented this bit does not have any effect
+ * on the counters unless there is support for the implementation
+ * defined authentication interface
+ * ExternalSecureNoninvasiveDebugEnabled().
+ * ---------------------------------------------------------------------
+ */
+ mov_imm x0, ((MDCR_EL2_RESET_VAL | MDCR_SDD_BIT | \
+ MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \
+ MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \
+ MDCR_TDA_BIT | MDCR_TPM_BIT))
+
+ msr mdcr_el2, x0
+
+ /* ---------------------------------------------------------------------
+ * Initialise PMCR_EL0 setting all fields rather than relying
+ * on hw. Some fields are architecturally UNKNOWN on reset.
+ *
+ * PMCR_EL0.LP: Set to one so that event counter overflow, that
+ * is recorded in PMOVSCLR_EL0[0-30], occurs on the increment
+ * that changes PMEVCNTR<n>_EL0[63] from 1 to 0, when ARMv8.5-PMU
+ * is implemented. This bit is RES0 in versions of the architecture
+ * earlier than ARMv8.5, setting it to 1 doesn't have any effect
+ * on them.
+ *
+ * PMCR_EL0.LC: Set to one so that cycle counter overflow, that
+ * is recorded in PMOVSCLR_EL0[31], occurs on the increment
+ * that changes PMCCNTR_EL0[63] from 1 to 0.
+ *
+ * PMCR_EL0.DP: Set to one so that the cycle counter,
+ * PMCCNTR_EL0 does not count when event counting is prohibited.
+ *
+ * PMCR_EL0.X: Set to zero to disable export of events.
+ *
+ * PMCR_EL0.D: Set to zero so that, when enabled, PMCCNTR_EL0
+ * counts on every clock cycle.
+ * ---------------------------------------------------------------------
+ */
+ mov_imm x0, ((PMCR_EL0_RESET_VAL | PMCR_EL0_LP_BIT | \
+ PMCR_EL0_LC_BIT | PMCR_EL0_DP_BIT) & \
+ ~(PMCR_EL0_X_BIT | PMCR_EL0_D_BIT))
+
+ msr pmcr_el0, x0
+
+ /* ---------------------------------------------------------------------
+ * Enable External Aborts and SError Interrupts now that the exception
+ * vectors have been setup.
+ * ---------------------------------------------------------------------
+ */
+ msr daifclr, #DAIF_ABT_BIT
+
+ /* ---------------------------------------------------------------------
+ * Initialise CPTR_EL2, setting all fields rather than relying on hw.
+ * All fields are architecturally UNKNOWN on reset.
+ *
+ * CPTR_EL2.TCPAC: Set to zero so that any accesses to CPACR_EL1 do
+ * not trap to EL2.
+ *
+ * CPTR_EL2.TTA: Set to zero so that System register accesses to the
+ * trace registers do not trap to EL2.
+ *
+ * CPTR_EL2.TFP: Set to zero so that accesses to the V- or Z- registers
+ * by Advanced SIMD, floating-point or SVE instructions (if implemented)
+ * do not trap to EL2.
+ */
+
+ mov_imm x0, (CPTR_EL2_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
+ msr cptr_el2, x0
+
+ /*
+ * If Data Independent Timing (DIT) functionality is implemented,
+ * always enable DIT in EL2
+ */
+ mrs x0, id_aa64pfr0_el1
+ ubfx x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
+ cmp x0, #ID_AA64PFR0_DIT_SUPPORTED
+ bne 1f
+ mov x0, #DIT_BIT
+ msr DIT, x0
+1:
+ .endm
+
+/* -----------------------------------------------------------------------------
+ * This is the super set of actions that need to be performed during a cold boot
+ * or a warm boot in EL2. This code is shared by BL1 and BL31.
+ *
+ * This macro will always perform reset handling, architectural initialisations
+ * and stack setup. The rest of the actions are optional because they might not
+ * be needed, depending on the context in which this macro is called. This is
+ * why this macro is parameterised ; each parameter allows to enable/disable
+ * some actions.
+ *
+ * _init_sctlr:
+ * Whether the macro needs to initialise SCTLR_EL2, including configuring
+ * the endianness of data accesses.
+ *
+ * _warm_boot_mailbox:
+ * Whether the macro needs to detect the type of boot (cold/warm). The
+ * detection is based on the platform entrypoint address : if it is zero
+ * then it is a cold boot, otherwise it is a warm boot. In the latter case,
+ * this macro jumps on the platform entrypoint address.
+ *
+ * _secondary_cold_boot:
+ * Whether the macro needs to identify the CPU that is calling it: primary
+ * CPU or secondary CPU. The primary CPU will be allowed to carry on with
+ * the platform initialisations, while the secondaries will be put in a
+ * platform-specific state in the meantime.
+ *
+ * If the caller knows this macro will only be called by the primary CPU
+ * then this parameter can be defined to 0 to skip this step.
+ *
+ * _init_memory:
+ * Whether the macro needs to initialise the memory.
+ *
+ * _init_c_runtime:
+ * Whether the macro needs to initialise the C runtime environment.
+ *
+ * _exception_vectors:
+ * Address of the exception vectors to program in the VBAR_EL2 register.
+ *
+ * _pie_fixup_size:
+ * Size of memory region to fixup Global Descriptor Table (GDT).
+ *
+ * A non-zero value is expected when firmware needs GDT to be fixed-up.
+ *
+ * -----------------------------------------------------------------------------
+ */
+ .macro el2_entrypoint_common \
+ _init_sctlr, _warm_boot_mailbox, _secondary_cold_boot, \
+ _init_memory, _init_c_runtime, _exception_vectors, \
+ _pie_fixup_size
+
+ .if \_init_sctlr
+ /* -------------------------------------------------------------
+ * This is the initialisation of SCTLR_EL2 and so must ensure
+ * that all fields are explicitly set rather than relying on hw.
+ * Some fields reset to an IMPLEMENTATION DEFINED value and
+ * others are architecturally UNKNOWN on reset.
+ *
+ * SCTLR.EE: Set the CPU endianness before doing anything that
+ * might involve memory reads or writes. Set to zero to select
+ * Little Endian.
+ *
+ * SCTLR_EL2.WXN: For the EL2 translation regime, this field can
+ * force all memory regions that are writeable to be treated as
+ * XN (Execute-never). Set to zero so that this control has no
+ * effect on memory access permissions.
+ *
+ * SCTLR_EL2.SA: Set to zero to disable Stack Alignment check.
+ *
+ * SCTLR_EL2.A: Set to zero to disable Alignment fault checking.
+ *
+ * SCTLR.DSSBS: Set to zero to disable speculation store bypass
+ * safe behaviour upon exception entry to EL2.
+ * -------------------------------------------------------------
+ */
+ mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \
+ | SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT))
+ msr sctlr_el2, x0
+ isb
+ .endif /* _init_sctlr */
+
+#if DISABLE_MTPMU
+ bl mtpmu_disable
+#endif
+
+ .if \_warm_boot_mailbox
+ /* -------------------------------------------------------------
+ * This code will be executed for both warm and cold resets.
+ * Now is the time to distinguish between the two.
+ * Query the platform entrypoint address and if it is not zero
+ * then it means it is a warm boot so jump to this address.
+ * -------------------------------------------------------------
+ */
+ bl plat_get_my_entrypoint
+ cbz x0, do_cold_boot
+ br x0
+
+ do_cold_boot:
+ .endif /* _warm_boot_mailbox */
+
+ .if \_pie_fixup_size
+#if ENABLE_PIE
+ /*
+ * ------------------------------------------------------------
+ * If PIE is enabled fixup the Global descriptor Table only
+ * once during primary core cold boot path.
+ *
+ * Compile time base address, required for fixup, is calculated
+ * using "pie_fixup" label present within first page.
+ * ------------------------------------------------------------
+ */
+ pie_fixup:
+ ldr x0, =pie_fixup
+ and x0, x0, #~(PAGE_SIZE_MASK)
+ mov_imm x1, \_pie_fixup_size
+ add x1, x1, x0
+ bl fixup_gdt_reloc
+#endif /* ENABLE_PIE */
+ .endif /* _pie_fixup_size */
+
+ /* ---------------------------------------------------------------------
+ * Set the exception vectors.
+ * ---------------------------------------------------------------------
+ */
+ adr x0, \_exception_vectors
+ msr vbar_el2, x0
+ isb
+
+ /* ---------------------------------------------------------------------
+ * It is a cold boot.
+ * Perform any processor specific actions upon reset e.g. cache, TLB
+ * invalidations etc.
+ * ---------------------------------------------------------------------
+ */
+ bl reset_handler
+
+ el2_arch_init_common
+
+ .if \_secondary_cold_boot
+ /* -------------------------------------------------------------
+ * Check if this is a primary or secondary CPU cold boot.
+ * The primary CPU will set up the platform while the
+ * secondaries are placed in a platform-specific state until the
+ * primary CPU performs the necessary actions to bring them out
+ * of that state and allows entry into the OS.
+ * -------------------------------------------------------------
+ */
+ bl plat_is_my_cpu_primary
+ cbnz w0, do_primary_cold_boot
+
+ /* This is a cold boot on a secondary CPU */
+ bl plat_secondary_cold_boot_setup
+ /* plat_secondary_cold_boot_setup() is not supposed to return */
+ bl el2_panic
+ do_primary_cold_boot:
+ .endif /* _secondary_cold_boot */
+
+ /* ---------------------------------------------------------------------
+ * Initialize memory now. Secondary CPU initialization won't get to this
+ * point.
+ * ---------------------------------------------------------------------
+ */
+
+ .if \_init_memory
+ bl platform_mem_init
+ .endif /* _init_memory */
+
+ /* ---------------------------------------------------------------------
+ * Init C runtime environment:
+ * - Zero-initialise the NOBITS sections. There are 2 of them:
+ * - the .bss section;
+ * - the coherent memory section (if any).
+ * - Relocate the data section from ROM to RAM, if required.
+ * ---------------------------------------------------------------------
+ */
+ .if \_init_c_runtime
+ adrp x0, __BSS_START__
+ add x0, x0, :lo12:__BSS_START__
+
+ adrp x1, __BSS_END__
+ add x1, x1, :lo12:__BSS_END__
+ sub x1, x1, x0
+ bl zeromem
+
+#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM)
+ adrp x0, __DATA_RAM_START__
+ add x0, x0, :lo12:__DATA_RAM_START__
+ adrp x1, __DATA_ROM_START__
+ add x1, x1, :lo12:__DATA_ROM_START__
+ adrp x2, __DATA_RAM_END__
+ add x2, x2, :lo12:__DATA_RAM_END__
+ sub x2, x2, x0
+ bl memcpy16
+#endif
+ .endif /* _init_c_runtime */
+
+ /* ---------------------------------------------------------------------
+ * Use SP_EL0 for the C runtime stack.
+ * ---------------------------------------------------------------------
+ */
+ msr spsel, #0
+
+ /* ---------------------------------------------------------------------
+ * Allocate a stack whose memory will be marked as Normal-IS-WBWA when
+ * the MMU is enabled. There is no risk of reading stale stack memory
+ * after enabling the MMU as only the primary CPU is running at the
+ * moment.
+ * ---------------------------------------------------------------------
+ */
+ bl plat_set_my_stack
+
+#if STACK_PROTECTOR_ENABLED
+ .if \_init_c_runtime
+ bl update_stack_protector_canary
+ .endif /* _init_c_runtime */
+#endif
+ .endm
+
+ .macro apply_at_speculative_wa
+#if ERRATA_SPECULATIVE_AT
+ /*
+ * Explicitly save x30 so as to free up a register and to enable
+ * branching and also, save x29 which will be used in the called
+ * function
+ */
+ stp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+ bl save_and_update_ptw_el1_sys_regs
+ ldp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+#endif
+ .endm
+
+ .macro restore_ptw_el1_sys_regs
+#if ERRATA_SPECULATIVE_AT
+ /* -----------------------------------------------------------
+ * In case of ERRATA_SPECULATIVE_AT, must follow below order
+ * to ensure that page table walk is not enabled until
+ * restoration of all EL1 system registers. TCR_EL1 register
+ * should be updated at the end which restores previous page
+ * table walk setting of stage1 i.e.(TCR_EL1.EPDx) bits. ISB
+ * ensures that CPU does below steps in order.
+ *
+ * 1. Ensure all other system registers are written before
+ * updating SCTLR_EL1 using ISB.
+ * 2. Restore SCTLR_EL1 register.
+ * 3. Ensure SCTLR_EL1 written successfully using ISB.
+ * 4. Restore TCR_EL1 register.
+ * -----------------------------------------------------------
+ */
+ isb
+ ldp x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1]
+ msr sctlr_el1, x28
+ isb
+ msr tcr_el1, x29
+#endif
+ .endm
+
+#endif /* EL2_COMMON_MACROS_S */
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 9734335..d496584 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -126,13 +126,31 @@
* Debug is not implemented this bit does not have any effect on the
* counters unless there is support for the implementation defined
* authentication interface ExternalSecureNoninvasiveDebugEnabled().
+ *
+ * MDCR_EL3.NSTB, MDCR_EL3.NSTBE: Set to zero so that Trace Buffer
+ * owning security state is Secure state. If FEAT_TRBE is implemented,
+ * accesses to Trace Buffer control registers at EL2 and EL1 in any
+ * security state generates trap exceptions to EL3.
+ * If FEAT_TRBE is not implemented, these bits are RES0.
+ *
+ * MDCR_EL3.TTRF: Set to one so that access to trace filter control
+ * registers in non-monitor mode generate EL3 trap exception,
+ * unless the access generates a higher priority exception when trace
+ * filter control(FEAT_TRF) is implemented.
+ * When FEAT_TRF is not implemented, this bit is RES0.
* ---------------------------------------------------------------------
*/
mov_imm x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \
MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \
- MDCR_TDA_BIT | MDCR_TPM_BIT))
+ MDCR_TDA_BIT | MDCR_TPM_BIT | MDCR_NSTB(MDCR_NSTB_EL1) | \
+ MDCR_NSTBE | MDCR_TTRF_BIT))
+ mrs x1, id_aa64dfr0_el1
+ ubfx x1, x1, #ID_AA64DFR0_TRACEFILT_SHIFT, #ID_AA64DFR0_TRACEFILT_LENGTH
+ cbz x1, 1f
+ orr x0, x0, #MDCR_TTRF_BIT
+1:
msr mdcr_el3, x0
/* ---------------------------------------------------------------------
@@ -179,6 +197,12 @@
* CPTR_EL3.TCPAC: Set to zero so that any accesses to CPACR_EL1,
* CPTR_EL2, CPACR, or HCPTR do not trap to EL3.
*
+ * CPTR_EL3.TTA: Set to one so that accesses to the trace system
+ * registers trap to EL3 from all exception levels and security
+ * states when system register trace is implemented.
+ * When system register trace is not implemented, this bit is RES0 and
+ * hence set to zero.
+ *
* CPTR_EL3.TTA: Set to zero so that System register accesses to the
* trace registers do not trap to EL3.
*
@@ -194,6 +218,11 @@
*/
mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
+ mrs x1, id_aa64dfr0_el1
+ ubfx x1, x1, #ID_AA64DFR0_TRACEVER_SHIFT, #ID_AA64DFR0_TRACEVER_LENGTH
+ cbz x1, 1f
+ orr x0, x0, #TTA_BIT
+1:
msr cptr_el3, x0
/*
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index e8b3933..98e7a3e 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -48,4 +48,9 @@
return fdt32_to_cpu(dtb_header[1]);
}
+#define fdt_for_each_compatible_node(dtb, node, compatible_str) \
+for (node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); \
+ node >= 0; \
+ node = fdt_node_offset_by_compatible(dtb, node, compatible_str))
+
#endif /* FDT_WRAPPERS_H */
diff --git a/include/drivers/arm/arm_gicv3_common.h b/include/drivers/arm/arm_gicv3_common.h
index b88b59f..e5df311 100644
--- a/include/drivers/arm/arm_gicv3_common.h
+++ b/include/drivers/arm/arm_gicv3_common.h
@@ -17,4 +17,8 @@
#define WAKER_SL_BIT (1U << WAKER_SL_SHIFT)
#define WAKER_QSC_BIT (1U << WAKER_QSC_SHIFT)
+#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b)
+#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b)
+#define IIDR_MODEL_ARM_GIC_700 U(0x0400043b)
+
#endif /* ARM_GICV3_COMMON_H */
diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h
index 6de2abb..9310733 100644
--- a/include/drivers/arm/ethosn.h
+++ b/include/drivers/arm/ethosn.h
@@ -38,8 +38,8 @@
#define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE)
/* Service version */
-#define ETHOSN_VERSION_MAJOR U(0)
-#define ETHOSN_VERSION_MINOR U(1)
+#define ETHOSN_VERSION_MAJOR U(1)
+#define ETHOSN_VERSION_MINOR U(0)
/* Return codes for function calls */
#define ETHOSN_SUCCESS 0
@@ -47,10 +47,10 @@
/* -2 Reserved for NOT_REQUIRED */
/* -3 Reserved for INVALID_PARAMETER */
#define ETHOSN_FAILURE -4
-#define ETHOSN_CORE_IDX_OUT_OF_RANGE -5
+#define ETHOSN_UNKNOWN_CORE_ADDRESS -5
uintptr_t ethosn_smc_handler(uint32_t smc_fid,
- u_register_t core_idx,
+ u_register_t core_addr,
u_register_t x2,
u_register_t x3,
u_register_t x4,
diff --git a/include/drivers/arm/gic600ae_fmu.h b/include/drivers/arm/gic600ae_fmu.h
new file mode 100644
index 0000000..691ffc7
--- /dev/null
+++ b/include/drivers/arm/gic600ae_fmu.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GIC600AE_FMU_H
+#define GIC600AE_FMU_H
+
+/*******************************************************************************
+ * GIC600-AE FMU register offsets and constants
+ ******************************************************************************/
+#define GICFMU_ERRFR_LO U(0x000)
+#define GICFMU_ERRFR_HI U(0x004)
+#define GICFMU_ERRCTLR_LO U(0x008)
+#define GICFMU_ERRCTLR_HI U(0x00C)
+#define GICFMU_ERRSTATUS_LO U(0x010)
+#define GICFMU_ERRSTATUS_HI U(0x014)
+#define GICFMU_ERRGSR_LO U(0xE00)
+#define GICFMU_ERRGSR_HI U(0xE04)
+#define GICFMU_KEY U(0xEA0)
+#define GICFMU_PINGCTLR U(0xEA4)
+#define GICFMU_PINGNOW U(0xEA8)
+#define GICFMU_SMEN U(0xEB0)
+#define GICFMU_SMINJERR U(0xEB4)
+#define GICFMU_PINGMASK_LO U(0xEC0)
+#define GICFMU_PINGMASK_HI U(0xEC4)
+#define GICFMU_STATUS U(0xF00)
+#define GICFMU_ERRIDR U(0xFC8)
+
+/* ERRCTLR bits */
+#define FMU_ERRCTLR_ED_BIT BIT(0)
+#define FMU_ERRCTLR_CE_EN_BIT BIT(1)
+#define FMU_ERRCTLR_UI_BIT BIT(2)
+#define FMU_ERRCTLR_CI_BIT BIT(3)
+
+/* SMEN constants */
+#define FMU_SMEN_BLK_SHIFT U(8)
+#define FMU_SMEN_SMID_SHIFT U(24)
+
+/* Error record IDs */
+#define FMU_BLK_GICD U(0)
+#define FMU_BLK_SPICOL U(1)
+#define FMU_BLK_WAKERQ U(2)
+#define FMU_BLK_ITS0 U(4)
+#define FMU_BLK_ITS1 U(5)
+#define FMU_BLK_ITS2 U(6)
+#define FMU_BLK_ITS3 U(7)
+#define FMU_BLK_ITS4 U(8)
+#define FMU_BLK_ITS5 U(9)
+#define FMU_BLK_ITS6 U(10)
+#define FMU_BLK_ITS7 U(11)
+#define FMU_BLK_PPI0 U(12)
+#define FMU_BLK_PPI1 U(13)
+#define FMU_BLK_PPI2 U(14)
+#define FMU_BLK_PPI3 U(15)
+#define FMU_BLK_PPI4 U(16)
+#define FMU_BLK_PPI5 U(17)
+#define FMU_BLK_PPI6 U(18)
+#define FMU_BLK_PPI7 U(19)
+#define FMU_BLK_PPI8 U(20)
+#define FMU_BLK_PPI9 U(21)
+#define FMU_BLK_PPI10 U(22)
+#define FMU_BLK_PPI11 U(23)
+#define FMU_BLK_PPI12 U(24)
+#define FMU_BLK_PPI13 U(25)
+#define FMU_BLK_PPI14 U(26)
+#define FMU_BLK_PPI15 U(27)
+#define FMU_BLK_PPI16 U(28)
+#define FMU_BLK_PPI17 U(29)
+#define FMU_BLK_PPI18 U(30)
+#define FMU_BLK_PPI19 U(31)
+#define FMU_BLK_PPI20 U(32)
+#define FMU_BLK_PPI21 U(33)
+#define FMU_BLK_PPI22 U(34)
+#define FMU_BLK_PPI23 U(35)
+#define FMU_BLK_PPI24 U(36)
+#define FMU_BLK_PPI25 U(37)
+#define FMU_BLK_PPI26 U(38)
+#define FMU_BLK_PPI27 U(39)
+#define FMU_BLK_PPI28 U(40)
+#define FMU_BLK_PPI29 U(41)
+#define FMU_BLK_PPI30 U(42)
+#define FMU_BLK_PPI31 U(43)
+#define FMU_BLK_PRESENT_MASK U(0xFFFFFFFFFFF)
+
+/* Safety Mechamism limit */
+#define FMU_SMID_GICD_MAX U(33)
+#define FMU_SMID_SPICOL_MAX U(5)
+#define FMU_SMID_WAKERQ_MAX U(2)
+#define FMU_SMID_ITS_MAX U(14)
+#define FMU_SMID_PPI_MAX U(12)
+
+/* MBIST Safety Mechanism ID */
+#define GICD_MBIST_REQ_ERROR U(23)
+#define GICD_FMU_CLKGATE_ERROR U(33)
+#define PPI_MBIST_REQ_ERROR U(10)
+#define PPI_FMU_CLKGATE_ERROR U(12)
+#define ITS_MBIST_REQ_ERROR U(13)
+#define ITS_FMU_CLKGATE_ERROR U(14)
+
+/* ERRSTATUS bits */
+#define FMU_ERRSTATUS_V_BIT BIT(30)
+#define FMU_ERRSTATUS_UE_BIT BIT(29)
+#define FMU_ERRSTATUS_OV_BIT BIT(27)
+#define FMU_ERRSTATUS_CE_BITS (BIT(25) | BIT(24))
+#define FMU_ERRSTATUS_CLEAR (FMU_ERRSTATUS_V_BIT | FMU_ERRSTATUS_UE_BIT | \
+ FMU_ERRSTATUS_OV_BIT | FMU_ERRSTATUS_CE_BITS)
+
+/* PINGCTLR constants */
+#define FMU_PINGCTLR_INTDIFF_SHIFT U(16)
+#define FMU_PINGCTLR_TIMEOUTVAL_SHIFT U(4)
+#define FMU_PINGCTLR_EN_BIT BIT(0)
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+
+/*******************************************************************************
+ * GIC600 FMU EL3 driver API
+ ******************************************************************************/
+uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n);
+uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n);
+uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n);
+uint64_t gic_fmu_read_errgsr(uintptr_t base);
+uint32_t gic_fmu_read_pingctlr(uintptr_t base);
+uint32_t gic_fmu_read_pingnow(uintptr_t base);
+uint64_t gic_fmu_read_pingmask(uintptr_t base);
+uint32_t gic_fmu_read_status(uintptr_t base);
+uint32_t gic_fmu_read_erridr(uintptr_t base);
+void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val);
+void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val);
+void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val);
+void gic_fmu_write_pingnow(uintptr_t base, uint32_t val);
+void gic_fmu_write_smen(uintptr_t base, uint32_t val);
+void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val);
+void gic_fmu_write_pingmask(uintptr_t base, uint64_t val);
+
+void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask, bool errctlr_ce_en, bool errctlr_ue_en);
+void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask,
+ unsigned int timeout_val, unsigned int interval_diff);
+void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* GIC600AE_FMU_H */
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index d8ac4cb..fa8946b 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -153,11 +153,8 @@
/*******************************************************************************
* Common GIC Redistributor interface registers & constants
******************************************************************************/
-#if GIC_ENABLE_V4_EXTN
-#define GICR_PCPUBASE_SHIFT 0x12
-#else
-#define GICR_PCPUBASE_SHIFT 0x11
-#endif
+#define GICR_V4_PCPUBASE_SHIFT 0x12
+#define GICR_V3_PCPUBASE_SHIFT 0x11
#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */
#define GICR_CTLR U(0x0)
#define GICR_IIDR U(0x04)
@@ -212,12 +209,14 @@
#define TYPER_AFF_VAL_SHIFT 32
#define TYPER_PROC_NUM_SHIFT 8
#define TYPER_LAST_SHIFT 4
+#define TYPER_VLPI_SHIFT 1
#define TYPER_AFF_VAL_MASK U(0xffffffff)
#define TYPER_PROC_NUM_MASK U(0xffff)
#define TYPER_LAST_MASK U(0x1)
#define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT)
+#define TYPER_VLPI_BIT BIT_32(TYPER_VLPI_SHIFT)
#define TYPER_PPI_NUM_SHIFT U(27)
#define TYPER_PPI_NUM_MASK U(0x1f)
@@ -312,6 +311,19 @@
#include <drivers/arm/gic_common.h>
#include <lib/utils_def.h>
+static inline uintptr_t gicv3_redist_size(uint64_t typer_val)
+{
+#if GIC_ENABLE_V4_EXTN
+ if ((typer_val & TYPER_VLPI_BIT) != 0U) {
+ return 1U << GICR_V4_PCPUBASE_SHIFT;
+ } else {
+ return 1U << GICR_V3_PCPUBASE_SHIFT;
+ }
+#else
+ return 1U << GICR_V3_PCPUBASE_SHIFT;
+#endif
+}
+
static inline bool gicv3_is_intr_id_special_identifier(unsigned int id)
{
return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT);
diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h
index 5f8a48f..765c130 100644
--- a/include/drivers/arm/tzc400.h
+++ b/include/drivers/arm/tzc400.h
@@ -109,6 +109,7 @@
unsigned long long region_top,
unsigned int sec_attr,
unsigned int nsaid_permissions);
+void tzc400_update_filters(unsigned int region, unsigned int filters);
void tzc400_set_action(unsigned int action);
void tzc400_enable_filters(void);
void tzc400_disable_filters(void);
diff --git a/include/drivers/nxp/dcfg/dcfg.h b/include/drivers/nxp/dcfg/dcfg.h
index 3f4855a..524450a 100644
--- a/include/drivers/nxp/dcfg/dcfg.h
+++ b/include/drivers/nxp/dcfg/dcfg.h
@@ -27,23 +27,41 @@
#endif
typedef struct {
- bool is_populated;
- uint8_t mfr_id;
-#if defined(CONFIG_CHASSIS_3_2)
- uint8_t family;
- uint8_t dev_id;
+ union {
+ uint32_t val;
+ struct {
+ uint32_t min_ver:4;
+ uint32_t maj_ver:4;
+#if defined(CONFIG_CHASSIS_3) || defined(CONFIG_CHASSIS_3_2)
+ uint32_t personality:6;
+ uint32_t rsv1:2;
+#elif defined(CONFIG_CHASSIS_2)
+ uint32_t personality:8;
+
#endif
- uint8_t personality;
+#if defined(CONFIG_CHASSIS_3) || defined(CONFIG_CHASSIS_3_2)
+ uint32_t dev_id:6;
+ uint32_t rsv2:2;
+ uint32_t family:4;
+#elif defined(CONFIG_CHASSIS_2)
+ uint32_t dev_id:12;
+#endif
+ uint32_t mfr_id;
+ } __packed bf;
+ struct {
+ uint32_t maj_min:8;
+ uint32_t version; /* SoC version without major and minor info */
+ } __packed bf_ver;
+ } __packed svr_reg;
bool sec_enabled;
- uint8_t maj_ver;
- uint8_t min_ver;
+ bool is_populated;
} soc_info_t;
typedef struct {
bool is_populated;
uint8_t ocram_present;
uint8_t ddrc1_present;
-#if defined(CONFIG_CHASSIS_3_2)
+#if defined(CONFIG_CHASSIS_3) || defined(CONFIG_CHASSIS_3_2)
uint8_t ddrc2_present;
#endif
} devdisr5_info_t;
diff --git a/include/drivers/nxp/dcfg/dcfg_lsch2.h b/include/drivers/nxp/dcfg/dcfg_lsch2.h
index 2838aca..1e56729 100644
--- a/include/drivers/nxp/dcfg/dcfg_lsch2.h
+++ b/include/drivers/nxp/dcfg/dcfg_lsch2.h
@@ -34,12 +34,10 @@
#define SVR_MFR_ID_MASK 0xF0000000
#define SVR_MFR_ID_SHIFT 28
-#define SVR_FAMILY_MASK 0xF000000
-#define SVR_FAMILY_SHIFT 24
-#define SVR_DEV_ID_MASK 0x3F0000
+#define SVR_DEV_ID_MASK 0xFFF0000
#define SVR_DEV_ID_SHIFT 16
-#define SVR_PERSONALITY_MASK 0x3E00
-#define SVR_PERSONALITY_SHIFT 9
+#define SVR_PERSONALITY_MASK 0xFF00
+#define SVR_PERSONALITY_SHIFT 8
#define SVR_SEC_MASK 0x100
#define SVR_SEC_SHIFT 8
#define SVR_MAJ_VER_MASK 0xF0
diff --git a/include/drivers/nxp/dcfg/dcfg_lsch3.h b/include/drivers/nxp/dcfg/dcfg_lsch3.h
index 40f02c1..cde86fe 100644
--- a/include/drivers/nxp/dcfg/dcfg_lsch3.h
+++ b/include/drivers/nxp/dcfg/dcfg_lsch3.h
@@ -74,4 +74,7 @@
#define DCFG_BOOTLOCPTRH_OFFSET 0x404
#define DCFG_COREDISABLEDSR_OFFSET 0x990
+/* Reset module bit field */
+#define RSTCR_RESET_REQ 0x2
+
#endif /* DCFG_LSCH3_H */
diff --git a/include/drivers/nxp/flexspi/flash_info.h b/include/drivers/nxp/flexspi/flash_info.h
index 6df79c9..94c9f02 100644
--- a/include/drivers/nxp/flexspi/flash_info.h
+++ b/include/drivers/nxp/flexspi/flash_info.h
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
- * Copyright 2020 NXP
+ * Copyright 2020-2021 NXP
*/
/**
@@ -53,6 +53,16 @@
#define F_SECTOR_ERASE_SZ F_SECTOR_4K
#endif
+#elif defined(CONFIG_MT35XU02G)
+#define F_SECTOR_128K 0x20000U
+#define F_PAGE_256 0x100U
+#define F_SECTOR_4K 0x1000U
+#define F_FLASH_SIZE_BYTES 0x10000000U
+#define F_SECTOR_ERASE_SZ F_SECTOR_128K
+#ifdef CONFIG_FSPI_4K_ERASE
+#define F_SECTOR_ERASE_SZ F_SECTOR_4K
+#endif
+
#ifdef NXP_WARM_BOOT
#define FLASH_WR_COMP_WAIT_BY_NOP_COUNT 0x20000
#endif
diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h
index 2ffc3b2..14f93fd 100644
--- a/include/drivers/st/stm32mp1_rcc.h
+++ b/include/drivers/st/stm32mp1_rcc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2021, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,488 +9,397 @@
#include <lib/utils_def.h>
-#define RCC_TZCR U(0x00)
-#define RCC_OCENSETR U(0x0C)
-#define RCC_OCENCLRR U(0x10)
-#define RCC_HSICFGR U(0x18)
-#define RCC_CSICFGR U(0x1C)
-#define RCC_MPCKSELR U(0x20)
-#define RCC_ASSCKSELR U(0x24)
-#define RCC_RCK12SELR U(0x28)
-#define RCC_MPCKDIVR U(0x2C)
-#define RCC_AXIDIVR U(0x30)
-#define RCC_APB4DIVR U(0x3C)
-#define RCC_APB5DIVR U(0x40)
-#define RCC_RTCDIVR U(0x44)
-#define RCC_MSSCKSELR U(0x48)
-#define RCC_PLL1CR U(0x80)
-#define RCC_PLL1CFGR1 U(0x84)
-#define RCC_PLL1CFGR2 U(0x88)
-#define RCC_PLL1FRACR U(0x8C)
-#define RCC_PLL1CSGR U(0x90)
-#define RCC_PLL2CR U(0x94)
-#define RCC_PLL2CFGR1 U(0x98)
-#define RCC_PLL2CFGR2 U(0x9C)
-#define RCC_PLL2FRACR U(0xA0)
-#define RCC_PLL2CSGR U(0xA4)
-#define RCC_I2C46CKSELR U(0xC0)
-#define RCC_SPI6CKSELR U(0xC4)
-#define RCC_UART1CKSELR U(0xC8)
-#define RCC_RNG1CKSELR U(0xCC)
-#define RCC_CPERCKSELR U(0xD0)
-#define RCC_STGENCKSELR U(0xD4)
-#define RCC_DDRITFCR U(0xD8)
-#define RCC_MP_BOOTCR U(0x100)
-#define RCC_MP_SREQSETR U(0x104)
-#define RCC_MP_SREQCLRR U(0x108)
-#define RCC_MP_GCR U(0x10C)
-#define RCC_MP_APRSTCR U(0x110)
-#define RCC_MP_APRSTSR U(0x114)
-#define RCC_BDCR U(0x140)
-#define RCC_RDLSICR U(0x144)
-#define RCC_APB4RSTSETR U(0x180)
-#define RCC_APB4RSTCLRR U(0x184)
-#define RCC_APB5RSTSETR U(0x188)
-#define RCC_APB5RSTCLRR U(0x18C)
-#define RCC_AHB5RSTSETR U(0x190)
-#define RCC_AHB5RSTCLRR U(0x194)
-#define RCC_AHB6RSTSETR U(0x198)
-#define RCC_AHB6RSTCLRR U(0x19C)
-#define RCC_TZAHB6RSTSETR U(0x1A0)
-#define RCC_TZAHB6RSTCLRR U(0x1A4)
-#define RCC_MP_APB4ENSETR U(0x200)
-#define RCC_MP_APB4ENCLRR U(0x204)
-#define RCC_MP_APB5ENSETR U(0x208)
-#define RCC_MP_APB5ENCLRR U(0x20C)
-#define RCC_MP_AHB5ENSETR U(0x210)
-#define RCC_MP_AHB5ENCLRR U(0x214)
-#define RCC_MP_AHB6ENSETR U(0x218)
-#define RCC_MP_AHB6ENCLRR U(0x21C)
-#define RCC_MP_TZAHB6ENSETR U(0x220)
-#define RCC_MP_TZAHB6ENCLRR U(0x224)
-#define RCC_MC_APB4ENSETR U(0x280)
-#define RCC_MC_APB4ENCLRR U(0x284)
-#define RCC_MC_APB5ENSETR U(0x288)
-#define RCC_MC_APB5ENCLRR U(0x28C)
-#define RCC_MC_AHB5ENSETR U(0x290)
-#define RCC_MC_AHB5ENCLRR U(0x294)
-#define RCC_MC_AHB6ENSETR U(0x298)
-#define RCC_MC_AHB6ENCLRR U(0x29C)
-#define RCC_MP_APB4LPENSETR U(0x300)
-#define RCC_MP_APB4LPENCLRR U(0x304)
-#define RCC_MP_APB5LPENSETR U(0x308)
-#define RCC_MP_APB5LPENCLRR U(0x30C)
-#define RCC_MP_AHB5LPENSETR U(0x310)
-#define RCC_MP_AHB5LPENCLRR U(0x314)
-#define RCC_MP_AHB6LPENSETR U(0x318)
-#define RCC_MP_AHB6LPENCLRR U(0x31C)
-#define RCC_MP_TZAHB6LPENSETR U(0x320)
-#define RCC_MP_TZAHB6LPENCLRR U(0x324)
-#define RCC_MC_APB4LPENSETR U(0x380)
-#define RCC_MC_APB4LPENCLRR U(0x384)
-#define RCC_MC_APB5LPENSETR U(0x388)
-#define RCC_MC_APB5LPENCLRR U(0x38C)
-#define RCC_MC_AHB5LPENSETR U(0x390)
-#define RCC_MC_AHB5LPENCLRR U(0x394)
-#define RCC_MC_AHB6LPENSETR U(0x398)
-#define RCC_MC_AHB6LPENCLRR U(0x39C)
-#define RCC_BR_RSTSCLRR U(0x400)
-#define RCC_MP_GRSTCSETR U(0x404)
-#define RCC_MP_RSTSCLRR U(0x408)
-#define RCC_MP_IWDGFZSETR U(0x40C)
-#define RCC_MP_IWDGFZCLRR U(0x410)
-#define RCC_MP_CIER U(0x414)
-#define RCC_MP_CIFR U(0x418)
-#define RCC_PWRLPDLYCR U(0x41C)
-#define RCC_MP_RSTSSETR U(0x420)
-#define RCC_MCO1CFGR U(0x800)
-#define RCC_MCO2CFGR U(0x804)
-#define RCC_OCRDYR U(0x808)
-#define RCC_DBGCFGR U(0x80C)
-#define RCC_RCK3SELR U(0x820)
-#define RCC_RCK4SELR U(0x824)
-#define RCC_TIMG1PRER U(0x828)
-#define RCC_TIMG2PRER U(0x82C)
-#define RCC_MCUDIVR U(0x830)
-#define RCC_APB1DIVR U(0x834)
-#define RCC_APB2DIVR U(0x838)
-#define RCC_APB3DIVR U(0x83C)
-#define RCC_PLL3CR U(0x880)
-#define RCC_PLL3CFGR1 U(0x884)
-#define RCC_PLL3CFGR2 U(0x888)
-#define RCC_PLL3FRACR U(0x88C)
-#define RCC_PLL3CSGR U(0x890)
-#define RCC_PLL4CR U(0x894)
-#define RCC_PLL4CFGR1 U(0x898)
-#define RCC_PLL4CFGR2 U(0x89C)
-#define RCC_PLL4FRACR U(0x8A0)
-#define RCC_PLL4CSGR U(0x8A4)
-#define RCC_I2C12CKSELR U(0x8C0)
-#define RCC_I2C35CKSELR U(0x8C4)
-#define RCC_SAI1CKSELR U(0x8C8)
-#define RCC_SAI2CKSELR U(0x8CC)
-#define RCC_SAI3CKSELR U(0x8D0)
-#define RCC_SAI4CKSELR U(0x8D4)
-#define RCC_SPI2S1CKSELR U(0x8D8)
-#define RCC_SPI2S23CKSELR U(0x8DC)
-#define RCC_SPI45CKSELR U(0x8E0)
-#define RCC_UART6CKSELR U(0x8E4)
-#define RCC_UART24CKSELR U(0x8E8)
-#define RCC_UART35CKSELR U(0x8EC)
-#define RCC_UART78CKSELR U(0x8F0)
-#define RCC_SDMMC12CKSELR U(0x8F4)
-#define RCC_SDMMC3CKSELR U(0x8F8)
-#define RCC_ETHCKSELR U(0x8FC)
-#define RCC_QSPICKSELR U(0x900)
-#define RCC_FMCCKSELR U(0x904)
-#define RCC_FDCANCKSELR U(0x90C)
-#define RCC_SPDIFCKSELR U(0x914)
-#define RCC_CECCKSELR U(0x918)
-#define RCC_USBCKSELR U(0x91C)
-#define RCC_RNG2CKSELR U(0x920)
-#define RCC_DSICKSELR U(0x924)
-#define RCC_ADCCKSELR U(0x928)
-#define RCC_LPTIM45CKSELR U(0x92C)
-#define RCC_LPTIM23CKSELR U(0x930)
-#define RCC_LPTIM1CKSELR U(0x934)
-#define RCC_APB1RSTSETR U(0x980)
-#define RCC_APB1RSTCLRR U(0x984)
-#define RCC_APB2RSTSETR U(0x988)
-#define RCC_APB2RSTCLRR U(0x98C)
-#define RCC_APB3RSTSETR U(0x990)
-#define RCC_APB3RSTCLRR U(0x994)
-#define RCC_AHB2RSTSETR U(0x998)
-#define RCC_AHB2RSTCLRR U(0x99C)
-#define RCC_AHB3RSTSETR U(0x9A0)
-#define RCC_AHB3RSTCLRR U(0x9A4)
-#define RCC_AHB4RSTSETR U(0x9A8)
-#define RCC_AHB4RSTCLRR U(0x9AC)
-#define RCC_MP_APB1ENSETR U(0xA00)
-#define RCC_MP_APB1ENCLRR U(0xA04)
-#define RCC_MP_APB2ENSETR U(0xA08)
-#define RCC_MP_APB2ENCLRR U(0xA0C)
-#define RCC_MP_APB3ENSETR U(0xA10)
-#define RCC_MP_APB3ENCLRR U(0xA14)
-#define RCC_MP_AHB2ENSETR U(0xA18)
-#define RCC_MP_AHB2ENCLRR U(0xA1C)
-#define RCC_MP_AHB3ENSETR U(0xA20)
-#define RCC_MP_AHB3ENCLRR U(0xA24)
-#define RCC_MP_AHB4ENSETR U(0xA28)
-#define RCC_MP_AHB4ENCLRR U(0xA2C)
-#define RCC_MP_MLAHBENSETR U(0xA38)
-#define RCC_MP_MLAHBENCLRR U(0xA3C)
-#define RCC_MC_APB1ENSETR U(0xA80)
-#define RCC_MC_APB1ENCLRR U(0xA84)
-#define RCC_MC_APB2ENSETR U(0xA88)
-#define RCC_MC_APB2ENCLRR U(0xA8C)
-#define RCC_MC_APB3ENSETR U(0xA90)
-#define RCC_MC_APB3ENCLRR U(0xA94)
-#define RCC_MC_AHB2ENSETR U(0xA98)
-#define RCC_MC_AHB2ENCLRR U(0xA9C)
-#define RCC_MC_AHB3ENSETR U(0xAA0)
-#define RCC_MC_AHB3ENCLRR U(0xAA4)
-#define RCC_MC_AHB4ENSETR U(0xAA8)
-#define RCC_MC_AHB4ENCLRR U(0xAAC)
-#define RCC_MC_AXIMENSETR U(0xAB0)
-#define RCC_MC_AXIMENCLRR U(0xAB4)
-#define RCC_MC_MLAHBENSETR U(0xAB8)
-#define RCC_MC_MLAHBENCLRR U(0xABC)
-#define RCC_MP_APB1LPENSETR U(0xB00)
-#define RCC_MP_APB1LPENCLRR U(0xB04)
-#define RCC_MP_APB2LPENSETR U(0xB08)
-#define RCC_MP_APB2LPENCLRR U(0xB0C)
-#define RCC_MP_APB3LPENSETR U(0xB10)
-#define RCC_MP_APB3LPENCLRR U(0xB14)
-#define RCC_MP_AHB2LPENSETR U(0xB18)
-#define RCC_MP_AHB2LPENCLRR U(0xB1C)
-#define RCC_MP_AHB3LPENSETR U(0xB20)
-#define RCC_MP_AHB3LPENCLRR U(0xB24)
-#define RCC_MP_AHB4LPENSETR U(0xB28)
-#define RCC_MP_AHB4LPENCLRR U(0xB2C)
-#define RCC_MP_AXIMLPENSETR U(0xB30)
-#define RCC_MP_AXIMLPENCLRR U(0xB34)
-#define RCC_MP_MLAHBLPENSETR U(0xB38)
-#define RCC_MP_MLAHBLPENCLRR U(0xB3C)
-#define RCC_MC_APB1LPENSETR U(0xB80)
-#define RCC_MC_APB1LPENCLRR U(0xB84)
-#define RCC_MC_APB2LPENSETR U(0xB88)
-#define RCC_MC_APB2LPENCLRR U(0xB8C)
-#define RCC_MC_APB3LPENSETR U(0xB90)
-#define RCC_MC_APB3LPENCLRR U(0xB94)
-#define RCC_MC_AHB2LPENSETR U(0xB98)
-#define RCC_MC_AHB2LPENCLRR U(0xB9C)
-#define RCC_MC_AHB3LPENSETR U(0xBA0)
-#define RCC_MC_AHB3LPENCLRR U(0xBA4)
-#define RCC_MC_AHB4LPENSETR U(0xBA8)
-#define RCC_MC_AHB4LPENCLRR U(0xBAC)
-#define RCC_MC_AXIMLPENSETR U(0xBB0)
-#define RCC_MC_AXIMLPENCLRR U(0xBB4)
-#define RCC_MC_MLAHBLPENSETR U(0xBB8)
-#define RCC_MC_MLAHBLPENCLRR U(0xBBC)
-#define RCC_MC_RSTSCLRR U(0xC00)
-#define RCC_MC_CIER U(0xC14)
-#define RCC_MC_CIFR U(0xC18)
-#define RCC_VERR U(0xFF4)
-#define RCC_IDR U(0xFF8)
-#define RCC_SIDR U(0xFFC)
+#define RCC_TZCR U(0x00)
+#define RCC_OCENSETR U(0x0C)
+#define RCC_OCENCLRR U(0x10)
+#define RCC_HSICFGR U(0x18)
+#define RCC_CSICFGR U(0x1C)
+#define RCC_MPCKSELR U(0x20)
+#define RCC_ASSCKSELR U(0x24)
+#define RCC_RCK12SELR U(0x28)
+#define RCC_MPCKDIVR U(0x2C)
+#define RCC_AXIDIVR U(0x30)
+#define RCC_APB4DIVR U(0x3C)
+#define RCC_APB5DIVR U(0x40)
+#define RCC_RTCDIVR U(0x44)
+#define RCC_MSSCKSELR U(0x48)
+#define RCC_PLL1CR U(0x80)
+#define RCC_PLL1CFGR1 U(0x84)
+#define RCC_PLL1CFGR2 U(0x88)
+#define RCC_PLL1FRACR U(0x8C)
+#define RCC_PLL1CSGR U(0x90)
+#define RCC_PLL2CR U(0x94)
+#define RCC_PLL2CFGR1 U(0x98)
+#define RCC_PLL2CFGR2 U(0x9C)
+#define RCC_PLL2FRACR U(0xA0)
+#define RCC_PLL2CSGR U(0xA4)
+#define RCC_I2C46CKSELR U(0xC0)
+#define RCC_SPI6CKSELR U(0xC4)
+#define RCC_UART1CKSELR U(0xC8)
+#define RCC_RNG1CKSELR U(0xCC)
+#define RCC_CPERCKSELR U(0xD0)
+#define RCC_STGENCKSELR U(0xD4)
+#define RCC_DDRITFCR U(0xD8)
+#define RCC_MP_BOOTCR U(0x100)
+#define RCC_MP_SREQSETR U(0x104)
+#define RCC_MP_SREQCLRR U(0x108)
+#define RCC_MP_GCR U(0x10C)
+#define RCC_MP_APRSTCR U(0x110)
+#define RCC_MP_APRSTSR U(0x114)
+#define RCC_BDCR U(0x140)
+#define RCC_RDLSICR U(0x144)
+#define RCC_APB4RSTSETR U(0x180)
+#define RCC_APB4RSTCLRR U(0x184)
+#define RCC_APB5RSTSETR U(0x188)
+#define RCC_APB5RSTCLRR U(0x18C)
+#define RCC_AHB5RSTSETR U(0x190)
+#define RCC_AHB5RSTCLRR U(0x194)
+#define RCC_AHB6RSTSETR U(0x198)
+#define RCC_AHB6RSTCLRR U(0x19C)
+#define RCC_TZAHB6RSTSETR U(0x1A0)
+#define RCC_TZAHB6RSTCLRR U(0x1A4)
+#define RCC_MP_APB4ENSETR U(0x200)
+#define RCC_MP_APB4ENCLRR U(0x204)
+#define RCC_MP_APB5ENSETR U(0x208)
+#define RCC_MP_APB5ENCLRR U(0x20C)
+#define RCC_MP_AHB5ENSETR U(0x210)
+#define RCC_MP_AHB5ENCLRR U(0x214)
+#define RCC_MP_AHB6ENSETR U(0x218)
+#define RCC_MP_AHB6ENCLRR U(0x21C)
+#define RCC_MP_TZAHB6ENSETR U(0x220)
+#define RCC_MP_TZAHB6ENCLRR U(0x224)
+#define RCC_MC_APB4ENSETR U(0x280)
+#define RCC_MC_APB4ENCLRR U(0x284)
+#define RCC_MC_APB5ENSETR U(0x288)
+#define RCC_MC_APB5ENCLRR U(0x28C)
+#define RCC_MC_AHB5ENSETR U(0x290)
+#define RCC_MC_AHB5ENCLRR U(0x294)
+#define RCC_MC_AHB6ENSETR U(0x298)
+#define RCC_MC_AHB6ENCLRR U(0x29C)
+#define RCC_MP_APB4LPENSETR U(0x300)
+#define RCC_MP_APB4LPENCLRR U(0x304)
+#define RCC_MP_APB5LPENSETR U(0x308)
+#define RCC_MP_APB5LPENCLRR U(0x30C)
+#define RCC_MP_AHB5LPENSETR U(0x310)
+#define RCC_MP_AHB5LPENCLRR U(0x314)
+#define RCC_MP_AHB6LPENSETR U(0x318)
+#define RCC_MP_AHB6LPENCLRR U(0x31C)
+#define RCC_MP_TZAHB6LPENSETR U(0x320)
+#define RCC_MP_TZAHB6LPENCLRR U(0x324)
+#define RCC_MC_APB4LPENSETR U(0x380)
+#define RCC_MC_APB4LPENCLRR U(0x384)
+#define RCC_MC_APB5LPENSETR U(0x388)
+#define RCC_MC_APB5LPENCLRR U(0x38C)
+#define RCC_MC_AHB5LPENSETR U(0x390)
+#define RCC_MC_AHB5LPENCLRR U(0x394)
+#define RCC_MC_AHB6LPENSETR U(0x398)
+#define RCC_MC_AHB6LPENCLRR U(0x39C)
+#define RCC_BR_RSTSCLRR U(0x400)
+#define RCC_MP_GRSTCSETR U(0x404)
+#define RCC_MP_RSTSCLRR U(0x408)
+#define RCC_MP_IWDGFZSETR U(0x40C)
+#define RCC_MP_IWDGFZCLRR U(0x410)
+#define RCC_MP_CIER U(0x414)
+#define RCC_MP_CIFR U(0x418)
+#define RCC_PWRLPDLYCR U(0x41C)
+#define RCC_MP_RSTSSETR U(0x420)
+#define RCC_MCO1CFGR U(0x800)
+#define RCC_MCO2CFGR U(0x804)
+#define RCC_OCRDYR U(0x808)
+#define RCC_DBGCFGR U(0x80C)
+#define RCC_RCK3SELR U(0x820)
+#define RCC_RCK4SELR U(0x824)
+#define RCC_TIMG1PRER U(0x828)
+#define RCC_TIMG2PRER U(0x82C)
+#define RCC_MCUDIVR U(0x830)
+#define RCC_APB1DIVR U(0x834)
+#define RCC_APB2DIVR U(0x838)
+#define RCC_APB3DIVR U(0x83C)
+#define RCC_PLL3CR U(0x880)
+#define RCC_PLL3CFGR1 U(0x884)
+#define RCC_PLL3CFGR2 U(0x888)
+#define RCC_PLL3FRACR U(0x88C)
+#define RCC_PLL3CSGR U(0x890)
+#define RCC_PLL4CR U(0x894)
+#define RCC_PLL4CFGR1 U(0x898)
+#define RCC_PLL4CFGR2 U(0x89C)
+#define RCC_PLL4FRACR U(0x8A0)
+#define RCC_PLL4CSGR U(0x8A4)
+#define RCC_I2C12CKSELR U(0x8C0)
+#define RCC_I2C35CKSELR U(0x8C4)
+#define RCC_SAI1CKSELR U(0x8C8)
+#define RCC_SAI2CKSELR U(0x8CC)
+#define RCC_SAI3CKSELR U(0x8D0)
+#define RCC_SAI4CKSELR U(0x8D4)
+#define RCC_SPI2S1CKSELR U(0x8D8)
+#define RCC_SPI2S23CKSELR U(0x8DC)
+#define RCC_SPI45CKSELR U(0x8E0)
+#define RCC_UART6CKSELR U(0x8E4)
+#define RCC_UART24CKSELR U(0x8E8)
+#define RCC_UART35CKSELR U(0x8EC)
+#define RCC_UART78CKSELR U(0x8F0)
+#define RCC_SDMMC12CKSELR U(0x8F4)
+#define RCC_SDMMC3CKSELR U(0x8F8)
+#define RCC_ETHCKSELR U(0x8FC)
+#define RCC_QSPICKSELR U(0x900)
+#define RCC_FMCCKSELR U(0x904)
+#define RCC_FDCANCKSELR U(0x90C)
+#define RCC_SPDIFCKSELR U(0x914)
+#define RCC_CECCKSELR U(0x918)
+#define RCC_USBCKSELR U(0x91C)
+#define RCC_RNG2CKSELR U(0x920)
+#define RCC_DSICKSELR U(0x924)
+#define RCC_ADCCKSELR U(0x928)
+#define RCC_LPTIM45CKSELR U(0x92C)
+#define RCC_LPTIM23CKSELR U(0x930)
+#define RCC_LPTIM1CKSELR U(0x934)
+#define RCC_APB1RSTSETR U(0x980)
+#define RCC_APB1RSTCLRR U(0x984)
+#define RCC_APB2RSTSETR U(0x988)
+#define RCC_APB2RSTCLRR U(0x98C)
+#define RCC_APB3RSTSETR U(0x990)
+#define RCC_APB3RSTCLRR U(0x994)
+#define RCC_AHB2RSTSETR U(0x998)
+#define RCC_AHB2RSTCLRR U(0x99C)
+#define RCC_AHB3RSTSETR U(0x9A0)
+#define RCC_AHB3RSTCLRR U(0x9A4)
+#define RCC_AHB4RSTSETR U(0x9A8)
+#define RCC_AHB4RSTCLRR U(0x9AC)
+#define RCC_MP_APB1ENSETR U(0xA00)
+#define RCC_MP_APB1ENCLRR U(0xA04)
+#define RCC_MP_APB2ENSETR U(0xA08)
+#define RCC_MP_APB2ENCLRR U(0xA0C)
+#define RCC_MP_APB3ENSETR U(0xA10)
+#define RCC_MP_APB3ENCLRR U(0xA14)
+#define RCC_MP_AHB2ENSETR U(0xA18)
+#define RCC_MP_AHB2ENCLRR U(0xA1C)
+#define RCC_MP_AHB3ENSETR U(0xA20)
+#define RCC_MP_AHB3ENCLRR U(0xA24)
+#define RCC_MP_AHB4ENSETR U(0xA28)
+#define RCC_MP_AHB4ENCLRR U(0xA2C)
+#define RCC_MP_MLAHBENSETR U(0xA38)
+#define RCC_MP_MLAHBENCLRR U(0xA3C)
+#define RCC_MC_APB1ENSETR U(0xA80)
+#define RCC_MC_APB1ENCLRR U(0xA84)
+#define RCC_MC_APB2ENSETR U(0xA88)
+#define RCC_MC_APB2ENCLRR U(0xA8C)
+#define RCC_MC_APB3ENSETR U(0xA90)
+#define RCC_MC_APB3ENCLRR U(0xA94)
+#define RCC_MC_AHB2ENSETR U(0xA98)
+#define RCC_MC_AHB2ENCLRR U(0xA9C)
+#define RCC_MC_AHB3ENSETR U(0xAA0)
+#define RCC_MC_AHB3ENCLRR U(0xAA4)
+#define RCC_MC_AHB4ENSETR U(0xAA8)
+#define RCC_MC_AHB4ENCLRR U(0xAAC)
+#define RCC_MC_AXIMENSETR U(0xAB0)
+#define RCC_MC_AXIMENCLRR U(0xAB4)
+#define RCC_MC_MLAHBENSETR U(0xAB8)
+#define RCC_MC_MLAHBENCLRR U(0xABC)
+#define RCC_MP_APB1LPENSETR U(0xB00)
+#define RCC_MP_APB1LPENCLRR U(0xB04)
+#define RCC_MP_APB2LPENSETR U(0xB08)
+#define RCC_MP_APB2LPENCLRR U(0xB0C)
+#define RCC_MP_APB3LPENSETR U(0xB10)
+#define RCC_MP_APB3LPENCLRR U(0xB14)
+#define RCC_MP_AHB2LPENSETR U(0xB18)
+#define RCC_MP_AHB2LPENCLRR U(0xB1C)
+#define RCC_MP_AHB3LPENSETR U(0xB20)
+#define RCC_MP_AHB3LPENCLRR U(0xB24)
+#define RCC_MP_AHB4LPENSETR U(0xB28)
+#define RCC_MP_AHB4LPENCLRR U(0xB2C)
+#define RCC_MP_AXIMLPENSETR U(0xB30)
+#define RCC_MP_AXIMLPENCLRR U(0xB34)
+#define RCC_MP_MLAHBLPENSETR U(0xB38)
+#define RCC_MP_MLAHBLPENCLRR U(0xB3C)
+#define RCC_MC_APB1LPENSETR U(0xB80)
+#define RCC_MC_APB1LPENCLRR U(0xB84)
+#define RCC_MC_APB2LPENSETR U(0xB88)
+#define RCC_MC_APB2LPENCLRR U(0xB8C)
+#define RCC_MC_APB3LPENSETR U(0xB90)
+#define RCC_MC_APB3LPENCLRR U(0xB94)
+#define RCC_MC_AHB2LPENSETR U(0xB98)
+#define RCC_MC_AHB2LPENCLRR U(0xB9C)
+#define RCC_MC_AHB3LPENSETR U(0xBA0)
+#define RCC_MC_AHB3LPENCLRR U(0xBA4)
+#define RCC_MC_AHB4LPENSETR U(0xBA8)
+#define RCC_MC_AHB4LPENCLRR U(0xBAC)
+#define RCC_MC_AXIMLPENSETR U(0xBB0)
+#define RCC_MC_AXIMLPENCLRR U(0xBB4)
+#define RCC_MC_MLAHBLPENSETR U(0xBB8)
+#define RCC_MC_MLAHBLPENCLRR U(0xBBC)
+#define RCC_MC_RSTSCLRR U(0xC00)
+#define RCC_MC_CIER U(0xC14)
+#define RCC_MC_CIFR U(0xC18)
+#define RCC_VERR U(0xFF4)
+#define RCC_IDR U(0xFF8)
+#define RCC_SIDR U(0xFFC)
-#define RCC_OFFSET_MASK GENMASK(11, 0)
+/* RCC_TZCR register fields */
+#define RCC_TZCR_TZEN BIT(0)
+#define RCC_TZCR_MCKPROT BIT(1)
-/* Values for RCC_TZCR register */
-#define RCC_TZCR_TZEN BIT(0)
-#define RCC_TZCR_MCKPROT BIT(1)
+/* RCC_OCENSETR register fields */
+#define RCC_OCENSETR_HSION BIT(0)
+#define RCC_OCENSETR_HSIKERON BIT(1)
+#define RCC_OCENSETR_CSION BIT(4)
+#define RCC_OCENSETR_CSIKERON BIT(5)
+#define RCC_OCENSETR_DIGBYP BIT(7)
+#define RCC_OCENSETR_HSEON BIT(8)
+#define RCC_OCENSETR_HSEKERON BIT(9)
+#define RCC_OCENSETR_HSEBYP BIT(10)
+#define RCC_OCENSETR_HSECSSON BIT(11)
-/* Used for most of RCC_<x>SELR registers */
-#define RCC_SELR_SRC_MASK GENMASK(2, 0)
-#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0)
-#define RCC_SELR_SRCRDY BIT(31)
+/* RCC_OCENCLRR register fields */
+#define RCC_OCENCLRR_HSION BIT(0)
+#define RCC_OCENCLRR_HSIKERON BIT(1)
+#define RCC_OCENCLRR_CSION BIT(4)
+#define RCC_OCENCLRR_CSIKERON BIT(5)
+#define RCC_OCENCLRR_DIGBYP BIT(7)
+#define RCC_OCENCLRR_HSEON BIT(8)
+#define RCC_OCENCLRR_HSEKERON BIT(9)
+#define RCC_OCENCLRR_HSEBYP BIT(10)
-/* Values of RCC_MPCKSELR register */
-#define RCC_MPCKSELR_HSI 0x00000000
-#define RCC_MPCKSELR_HSE 0x00000001
-#define RCC_MPCKSELR_PLL 0x00000002
-#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003
-#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0)
-#define RCC_MPCKSELR_MPUSRC_SHIFT 0
+/* RCC_HSICFGR register fields */
+#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0)
+#define RCC_HSICFGR_HSIDIV_SHIFT 0
+#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8)
+#define RCC_HSICFGR_HSITRIM_SHIFT 8
+#define RCC_HSICFGR_HSICAL_MASK GENMASK(24, 16)
+#define RCC_HSICFGR_HSICAL_SHIFT 16
+#define RCC_HSICFGR_HSICAL_TEMP_MASK GENMASK(27, 25)
-/* Values of RCC_ASSCKSELR register */
-#define RCC_ASSCKSELR_HSI 0x00000000
-#define RCC_ASSCKSELR_HSE 0x00000001
-#define RCC_ASSCKSELR_PLL 0x00000002
+/* RCC_CSICFGR register fields */
+#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8)
+#define RCC_CSICFGR_CSITRIM_SHIFT 8
+#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16)
+#define RCC_CSICFGR_CSICAL_SHIFT 16
-/* Values of RCC_MSSCKSELR register */
-#define RCC_MSSCKSELR_HSI 0x00000000
-#define RCC_MSSCKSELR_HSE 0x00000001
-#define RCC_MSSCKSELR_CSI 0x00000002
-#define RCC_MSSCKSELR_PLL 0x00000003
-
-/* Values of RCC_CPERCKSELR register */
-#define RCC_CPERCKSELR_HSI 0x00000000
-#define RCC_CPERCKSELR_CSI 0x00000001
-#define RCC_CPERCKSELR_HSE 0x00000002
-#define RCC_CPERCKSELR_PERSRC_MASK GENMASK(1, 0)
-#define RCC_CPERCKSELR_PERSRC_SHIFT 0
-
-/* Used for most of DIVR register: max div for RTC */
-#define RCC_DIVR_DIV_MASK GENMASK(5, 0)
-#define RCC_DIVR_DIVRDY BIT(31)
-
-/* Masks for specific DIVR registers */
-#define RCC_APBXDIV_MASK GENMASK(2, 0)
-#define RCC_MPUDIV_MASK GENMASK(2, 0)
-#define RCC_AXIDIV_MASK GENMASK(2, 0)
-#define RCC_MCUDIV_MASK GENMASK(3, 0)
-
-/* Used for TIMER Prescaler */
-#define RCC_TIMGXPRER_TIMGXPRE BIT(0)
-
-/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
-#define RCC_MP_ENCLRR_OFFSET U(4)
-
-/* Offset between RCC_xxxRSTSETR and RCC_xxxRSTCLRR registers */
-#define RCC_RSTCLRR_OFFSET U(4)
-
-/* Fields of RCC_BDCR register */
-#define RCC_BDCR_LSEON BIT(0)
-#define RCC_BDCR_LSEBYP BIT(1)
-#define RCC_BDCR_LSERDY BIT(2)
-#define RCC_BDCR_DIGBYP BIT(3)
-#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4)
-#define RCC_BDCR_LSEDRV_SHIFT 4
-#define RCC_BDCR_LSECSSON BIT(8)
-#define RCC_BDCR_RTCCKEN BIT(20)
-#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16)
-#define RCC_BDCR_RTCSRC_SHIFT 16
-#define RCC_BDCR_VSWRST BIT(31)
-
-/* Fields of RCC_RDLSICR register */
-#define RCC_RDLSICR_LSION BIT(0)
-#define RCC_RDLSICR_LSIRDY BIT(1)
-
-/* Used for all RCC_PLL<n>CR registers */
-#define RCC_PLLNCR_PLLON BIT(0)
-#define RCC_PLLNCR_PLLRDY BIT(1)
-#define RCC_PLLNCR_SSCG_CTRL BIT(2)
-#define RCC_PLLNCR_DIVPEN BIT(4)
-#define RCC_PLLNCR_DIVQEN BIT(5)
-#define RCC_PLLNCR_DIVREN BIT(6)
-#define RCC_PLLNCR_DIVEN_SHIFT 4
-
-/* Used for all RCC_PLL<n>CFGR1 registers */
-#define RCC_PLLNCFGR1_DIVM_SHIFT 16
-#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16)
-#define RCC_PLLNCFGR1_DIVN_SHIFT 0
-#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0)
-/* Only for PLL3 and PLL4 */
-#define RCC_PLLNCFGR1_IFRGE_SHIFT 24
-#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24)
-
-/* Used for all RCC_PLL<n>CFGR2 registers */
-#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0)
-#define RCC_PLLNCFGR2_DIVP_SHIFT 0
-#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0)
-#define RCC_PLLNCFGR2_DIVQ_SHIFT 8
-#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8)
-#define RCC_PLLNCFGR2_DIVR_SHIFT 16
-#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16)
-
-/* Used for all RCC_PLL<n>FRACR registers */
-#define RCC_PLLNFRACR_FRACV_SHIFT 3
-#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3)
-#define RCC_PLLNFRACR_FRACLE BIT(16)
-
-/* Used for all RCC_PLL<n>CSGR registers */
-#define RCC_PLLNCSGR_INC_STEP_SHIFT 16
-#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16)
-#define RCC_PLLNCSGR_MOD_PER_SHIFT 0
-#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0)
-#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15
-#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15)
-
-/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
-#define RCC_OCENR_HSION BIT(0)
-#define RCC_OCENR_HSIKERON BIT(1)
-#define RCC_OCENR_CSION BIT(4)
-#define RCC_OCENR_CSIKERON BIT(5)
-#define RCC_OCENR_DIGBYP BIT(7)
-#define RCC_OCENR_HSEON BIT(8)
-#define RCC_OCENR_HSEKERON BIT(9)
-#define RCC_OCENR_HSEBYP BIT(10)
-#define RCC_OCENR_HSECSSON BIT(11)
-
-/* Fields of RCC_OCRDYR register */
-#define RCC_OCRDYR_HSIRDY BIT(0)
-#define RCC_OCRDYR_HSIDIVRDY BIT(2)
-#define RCC_OCRDYR_CSIRDY BIT(4)
-#define RCC_OCRDYR_HSERDY BIT(8)
-
-/* Fields of RCC_DDRITFCR register */
-#define RCC_DDRITFCR_DDRC1EN BIT(0)
-#define RCC_DDRITFCR_DDRC1LPEN BIT(1)
-#define RCC_DDRITFCR_DDRC2EN BIT(2)
-#define RCC_DDRITFCR_DDRC2LPEN BIT(3)
-#define RCC_DDRITFCR_DDRPHYCEN BIT(4)
-#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5)
-#define RCC_DDRITFCR_DDRCAPBEN BIT(6)
-#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7)
-#define RCC_DDRITFCR_AXIDCGEN BIT(8)
-#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9)
-#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10)
-#define RCC_DDRITFCR_DDRCAPBRST BIT(14)
-#define RCC_DDRITFCR_DDRCAXIRST BIT(15)
-#define RCC_DDRITFCR_DDRCORERST BIT(16)
-#define RCC_DDRITFCR_DPHYAPBRST BIT(17)
-#define RCC_DDRITFCR_DPHYRST BIT(18)
-#define RCC_DDRITFCR_DPHYCTLRST BIT(19)
-#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20)
-#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20
-#define RCC_DDRITFCR_DDRCKMOD_SSR 0
-#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20)
-#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21)
-#define RCC_DDRITFCR_GSKPCTRL BIT(24)
-
-/* Fields of RCC_HSICFGR register */
-#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0)
-#define RCC_HSICFGR_HSITRIM_SHIFT 8
-#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8)
-#define RCC_HSICFGR_HSICAL_SHIFT 16
-#define RCC_HSICFGR_HSICAL_MASK GENMASK(27, 16)
-
-/* Fields of RCC_CSICFGR register */
-#define RCC_CSICFGR_CSITRIM_SHIFT 8
-#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8)
-#define RCC_CSICFGR_CSICAL_SHIFT 16
-#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16)
-
-/* Used for RCC_MCO related operations */
-#define RCC_MCOCFG_MCOON BIT(12)
-#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4)
-#define RCC_MCOCFG_MCODIV_SHIFT 4
-#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0)
-
-/* Fields of RCC_DBGCFGR register */
-#define RCC_DBGCFGR_DBGCKEN BIT(8)
-
-/* RCC register fields for reset reasons */
-#define RCC_MP_RSTSCLRR_PORRSTF BIT(0)
-#define RCC_MP_RSTSCLRR_BORRSTF BIT(1)
-#define RCC_MP_RSTSCLRR_PADRSTF BIT(2)
-#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3)
-#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4)
-#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6)
-#define RCC_MP_RSTSCLRR_MCSYSRSTF BIT(7)
-#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8)
-#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9)
-#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11)
-#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12)
-#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13)
-#define RCC_MP_RSTSCLRR_MPUP1RSTF BIT(14)
-
-/* Global Reset Register */
-#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
-#define RCC_MP_GRSTCSETR_MCURST BIT(1)
-#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4)
-#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5)
-
-/* Clock Source Interrupt Flag Register */
-#define RCC_MP_CIFR_MASK U(0x110F1F)
-#define RCC_MP_CIFR_LSIRDYF BIT(0)
-#define RCC_MP_CIFR_LSERDYF BIT(1)
-#define RCC_MP_CIFR_HSIRDYF BIT(2)
-#define RCC_MP_CIFR_HSERDYF BIT(3)
-#define RCC_MP_CIFR_CSIRDYF BIT(4)
-#define RCC_MP_CIFR_PLL1DYF BIT(8)
-#define RCC_MP_CIFR_PLL2DYF BIT(9)
-#define RCC_MP_CIFR_PLL3DYF BIT(10)
-#define RCC_MP_CIFR_PLL4DYF BIT(11)
-#define RCC_MP_CIFR_WKUPF BIT(20)
-
-/* Stop Request Set Register */
-#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0)
-#define RCC_MP_SREQSETR_STPREQ_P1 BIT(1)
-
-/* Stop Request Clear Register */
-#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0)
-#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1)
-
-/* Values of RCC_UART24CKSELR register */
-#define RCC_UART24CKSELR_HSI 0x00000002
-
-/* Values of RCC_MP_APB1ENSETR register */
-#define RCC_MP_APB1ENSETR_UART4EN BIT(16)
-
-/* Values of RCC_MP_APB5ENSETR register */
-#define RCC_MP_APB5ENSETR_SPI6EN BIT(0)
-#define RCC_MP_APB5ENSETR_I2C4EN BIT(2)
-#define RCC_MP_APB5ENSETR_I2C6EN BIT(3)
-#define RCC_MP_APB5ENSETR_USART1EN BIT(4)
-#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8)
-#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15)
-
-/* Values of RCC_MP_AHB4ENSETR register */
-#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6)
-#define RCC_MP_AHB4ENSETR_GPIOHEN BIT(7)
-
-/* Values of RCC_MP_AHB5ENSETR register */
-#define RCC_MP_AHB5ENSETR_GPIOZEN BIT(0)
-#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4)
-#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5)
-#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6)
-
-/* Values of RCC_MP_IWDGFZSETR register */
-#define RCC_MP_IWDGFZSETR_IWDG1 BIT(0)
-#define RCC_MP_IWDGFZSETR_IWDG2 BIT(1)
-
-/* Values of RCC_PWRLPDLYCR register */
-#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0)
+/* RCC_MPCKSELR register fields */
+#define RCC_MPCKSELR_HSI 0x00000000
+#define RCC_MPCKSELR_HSE 0x00000001
+#define RCC_MPCKSELR_PLL 0x00000002
+#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003
+#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0)
+#define RCC_MPCKSELR_MPUSRC_SHIFT 0
+#define RCC_MPCKSELR_MPUSRCRDY BIT(31)
/* RCC_ASSCKSELR register fields */
+#define RCC_ASSCKSELR_HSI 0x00000000
+#define RCC_ASSCKSELR_HSE 0x00000001
+#define RCC_ASSCKSELR_PLL 0x00000002
#define RCC_ASSCKSELR_AXISSRC_MASK GENMASK(2, 0)
#define RCC_ASSCKSELR_AXISSRC_SHIFT 0
+#define RCC_ASSCKSELR_AXISSRCRDY BIT(31)
+
+/* RCC_RCK12SELR register fields */
+#define RCC_RCK12SELR_PLL12SRC_MASK GENMASK(1, 0)
+#define RCC_RCK12SELR_PLL12SRC_SHIFT 0
+#define RCC_RCK12SELR_PLL12SRCRDY BIT(31)
+
+/* RCC_MPCKDIVR register fields */
+#define RCC_MPCKDIVR_MPUDIV_MASK GENMASK(2, 0)
+#define RCC_MPCKDIVR_MPUDIV_SHIFT 0
+#define RCC_MPCKDIVR_MPUDIVRDY BIT(31)
+
+/* RCC_AXIDIVR register fields */
+#define RCC_AXIDIVR_AXIDIV_MASK GENMASK(2, 0)
+#define RCC_AXIDIVR_AXIDIV_SHIFT 0
+#define RCC_AXIDIVR_AXIDIVRDY BIT(31)
+
+/* RCC_APB4DIVR register fields */
+#define RCC_APB4DIVR_APB4DIV_MASK GENMASK(2, 0)
+#define RCC_APB4DIVR_APB4DIV_SHIFT 0
+#define RCC_APB4DIVR_APB4DIVRDY BIT(31)
+
+/* RCC_APB5DIVR register fields */
+#define RCC_APB5DIVR_APB5DIV_MASK GENMASK(2, 0)
+#define RCC_APB5DIVR_APB5DIV_SHIFT 0
+#define RCC_APB5DIVR_APB5DIVRDY BIT(31)
+
+/* RCC_RTCDIVR register fields */
+#define RCC_RTCDIVR_RTCDIV_MASK GENMASK(5, 0)
+#define RCC_RTCDIVR_RTCDIV_SHIFT 0
/* RCC_MSSCKSELR register fields */
+#define RCC_MSSCKSELR_HSI 0x00000000
+#define RCC_MSSCKSELR_HSE 0x00000001
+#define RCC_MSSCKSELR_CSI 0x00000002
+#define RCC_MSSCKSELR_PLL 0x00000003
#define RCC_MSSCKSELR_MCUSSRC_MASK GENMASK(1, 0)
#define RCC_MSSCKSELR_MCUSSRC_SHIFT 0
+#define RCC_MSSCKSELR_MCUSSRCRDY BIT(31)
+
+/* RCC_PLL1CR register fields */
+#define RCC_PLL1CR_PLLON BIT(0)
+#define RCC_PLL1CR_PLL1RDY BIT(1)
+#define RCC_PLL1CR_SSCG_CTRL BIT(2)
+#define RCC_PLL1CR_DIVPEN BIT(4)
+#define RCC_PLL1CR_DIVQEN BIT(5)
+#define RCC_PLL1CR_DIVREN BIT(6)
+
+/* RCC_PLL1CFGR1 register fields */
+#define RCC_PLL1CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL1CFGR1_DIVN_SHIFT 0
+#define RCC_PLL1CFGR1_DIVM1_MASK GENMASK(21, 16)
+#define RCC_PLL1CFGR1_DIVM1_SHIFT 16
+
+/* RCC_PLL1CFGR2 register fields */
+#define RCC_PLL1CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL1CFGR2_DIVP_SHIFT 0
+#define RCC_PLL1CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL1CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL1CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL1CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL1FRACR register fields */
+#define RCC_PLL1FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL1FRACR_FRACV_SHIFT 3
+#define RCC_PLL1FRACR_FRACLE BIT(16)
+
+/* RCC_PLL1CSGR register fields */
+#define RCC_PLL1CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL1CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL1CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL1CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL1CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL1CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL1CSGR_INC_STEP_SHIFT 16
+
+/* RCC_PLL2CR register fields */
+#define RCC_PLL2CR_PLLON BIT(0)
+#define RCC_PLL2CR_PLL2RDY BIT(1)
+#define RCC_PLL2CR_SSCG_CTRL BIT(2)
+#define RCC_PLL2CR_DIVPEN BIT(4)
+#define RCC_PLL2CR_DIVQEN BIT(5)
+#define RCC_PLL2CR_DIVREN BIT(6)
+
+/* RCC_PLL2CFGR1 register fields */
+#define RCC_PLL2CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL2CFGR1_DIVN_SHIFT 0
+#define RCC_PLL2CFGR1_DIVM2_MASK GENMASK(21, 16)
+#define RCC_PLL2CFGR1_DIVM2_SHIFT 16
+
+/* RCC_PLL2CFGR2 register fields */
+#define RCC_PLL2CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL2CFGR2_DIVP_SHIFT 0
+#define RCC_PLL2CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL2CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL2CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL2CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL2FRACR register fields */
+#define RCC_PLL2FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL2FRACR_FRACV_SHIFT 3
+#define RCC_PLL2FRACR_FRACLE BIT(16)
+
+/* RCC_PLL2CSGR register fields */
+#define RCC_PLL2CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL2CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL2CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL2CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL2CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL2CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL2CSGR_INC_STEP_SHIFT 16
/* RCC_I2C46CKSELR register fields */
#define RCC_I2C46CKSELR_I2C46SRC_MASK GENMASK(2, 0)
@@ -508,10 +417,751 @@
#define RCC_RNG1CKSELR_RNG1SRC_MASK GENMASK(1, 0)
#define RCC_RNG1CKSELR_RNG1SRC_SHIFT 0
+/* RCC_CPERCKSELR register fields */
+#define RCC_CPERCKSELR_HSI 0x00000000
+#define RCC_CPERCKSELR_CSI 0x00000001
+#define RCC_CPERCKSELR_HSE 0x00000002
+#define RCC_CPERCKSELR_CKPERSRC_MASK GENMASK(1, 0)
+#define RCC_CPERCKSELR_CKPERSRC_SHIFT 0
+
/* RCC_STGENCKSELR register fields */
#define RCC_STGENCKSELR_STGENSRC_MASK GENMASK(1, 0)
#define RCC_STGENCKSELR_STGENSRC_SHIFT 0
+/* RCC_DDRITFCR register fields */
+#define RCC_DDRITFCR_DDRC1EN BIT(0)
+#define RCC_DDRITFCR_DDRC1LPEN BIT(1)
+#define RCC_DDRITFCR_DDRC2EN BIT(2)
+#define RCC_DDRITFCR_DDRC2LPEN BIT(3)
+#define RCC_DDRITFCR_DDRPHYCEN BIT(4)
+#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5)
+#define RCC_DDRITFCR_DDRCAPBEN BIT(6)
+#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7)
+#define RCC_DDRITFCR_AXIDCGEN BIT(8)
+#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9)
+#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10)
+#define RCC_DDRITFCR_KERDCG_DLY_MASK GENMASK(13, 11)
+#define RCC_DDRITFCR_KERDCG_DLY_SHIFT 11
+#define RCC_DDRITFCR_DDRCAPBRST BIT(14)
+#define RCC_DDRITFCR_DDRCAXIRST BIT(15)
+#define RCC_DDRITFCR_DDRCORERST BIT(16)
+#define RCC_DDRITFCR_DPHYAPBRST BIT(17)
+#define RCC_DDRITFCR_DPHYRST BIT(18)
+#define RCC_DDRITFCR_DPHYCTLRST BIT(19)
+#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20)
+#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20
+#define RCC_DDRITFCR_DDRCKMOD_SSR 0
+#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20)
+#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21)
+#define RCC_DDRITFCR_GSKPMOD BIT(23)
+#define RCC_DDRITFCR_GSKPCTRL BIT(24)
+#define RCC_DDRITFCR_DFILP_WIDTH_MASK GENMASK(27, 25)
+#define RCC_DDRITFCR_DFILP_WIDTH_SHIFT 25
+#define RCC_DDRITFCR_GSKP_DUR_MASK GENMASK(31, 28)
+#define RCC_DDRITFCR_GSKP_DUR_SHIFT 28
+
+/* RCC_MP_BOOTCR register fields */
+#define RCC_MP_BOOTCR_MCU_BEN BIT(0)
+#define RCC_MP_BOOTCR_MPU_BEN BIT(1)
+
+/* RCC_MP_SREQSETR register fields */
+#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0)
+#define RCC_MP_SREQSETR_STPREQ_P1 BIT(1)
+
+/* RCC_MP_SREQCLRR register fields */
+#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0)
+#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1)
+
+/* RCC_MP_GCR register fields */
+#define RCC_MP_GCR_BOOT_MCU BIT(0)
+
+/* RCC_MP_APRSTCR register fields */
+#define RCC_MP_APRSTCR_RDCTLEN BIT(0)
+#define RCC_MP_APRSTCR_RSTTO_MASK GENMASK(14, 8)
+#define RCC_MP_APRSTCR_RSTTO_SHIFT 8
+
+/* RCC_MP_APRSTSR register fields */
+#define RCC_MP_APRSTSR_RSTTOV_MASK GENMASK(14, 8)
+#define RCC_MP_APRSTSR_RSTTOV_SHIFT 8
+
+/* RCC_BDCR register fields */
+#define RCC_BDCR_LSEON BIT(0)
+#define RCC_BDCR_LSEBYP BIT(1)
+#define RCC_BDCR_LSERDY BIT(2)
+#define RCC_BDCR_DIGBYP BIT(3)
+#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4)
+#define RCC_BDCR_LSEDRV_SHIFT 4
+#define RCC_BDCR_LSECSSON BIT(8)
+#define RCC_BDCR_LSECSSD BIT(9)
+#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16)
+#define RCC_BDCR_RTCSRC_SHIFT 16
+#define RCC_BDCR_RTCCKEN BIT(20)
+#define RCC_BDCR_VSWRST BIT(31)
+
+/* RCC_RDLSICR register fields */
+#define RCC_RDLSICR_LSION BIT(0)
+#define RCC_RDLSICR_LSIRDY BIT(1)
+#define RCC_RDLSICR_MRD_MASK GENMASK(20, 16)
+#define RCC_RDLSICR_MRD_SHIFT 16
+#define RCC_RDLSICR_EADLY_MASK GENMASK(26, 24)
+#define RCC_RDLSICR_EADLY_SHIFT 24
+#define RCC_RDLSICR_SPARE_MASK GENMASK(31, 27)
+#define RCC_RDLSICR_SPARE_SHIFT 27
+
+/* RCC_APB4RSTSETR register fields */
+#define RCC_APB4RSTSETR_LTDCRST BIT(0)
+#define RCC_APB4RSTSETR_DSIRST BIT(4)
+#define RCC_APB4RSTSETR_DDRPERFMRST BIT(8)
+#define RCC_APB4RSTSETR_USBPHYRST BIT(16)
+
+/* RCC_APB4RSTCLRR register fields */
+#define RCC_APB4RSTCLRR_LTDCRST BIT(0)
+#define RCC_APB4RSTCLRR_DSIRST BIT(4)
+#define RCC_APB4RSTCLRR_DDRPERFMRST BIT(8)
+#define RCC_APB4RSTCLRR_USBPHYRST BIT(16)
+
+/* RCC_APB5RSTSETR register fields */
+#define RCC_APB5RSTSETR_SPI6RST BIT(0)
+#define RCC_APB5RSTSETR_I2C4RST BIT(2)
+#define RCC_APB5RSTSETR_I2C6RST BIT(3)
+#define RCC_APB5RSTSETR_USART1RST BIT(4)
+#define RCC_APB5RSTSETR_STGENRST BIT(20)
+
+/* RCC_APB5RSTCLRR register fields */
+#define RCC_APB5RSTCLRR_SPI6RST BIT(0)
+#define RCC_APB5RSTCLRR_I2C4RST BIT(2)
+#define RCC_APB5RSTCLRR_I2C6RST BIT(3)
+#define RCC_APB5RSTCLRR_USART1RST BIT(4)
+#define RCC_APB5RSTCLRR_STGENRST BIT(20)
+
+/* RCC_AHB5RSTSETR register fields */
+#define RCC_AHB5RSTSETR_GPIOZRST BIT(0)
+#define RCC_AHB5RSTSETR_CRYP1RST BIT(4)
+#define RCC_AHB5RSTSETR_HASH1RST BIT(5)
+#define RCC_AHB5RSTSETR_RNG1RST BIT(6)
+#define RCC_AHB5RSTSETR_AXIMCRST BIT(16)
+
+/* RCC_AHB5RSTCLRR register fields */
+#define RCC_AHB5RSTCLRR_GPIOZRST BIT(0)
+#define RCC_AHB5RSTCLRR_CRYP1RST BIT(4)
+#define RCC_AHB5RSTCLRR_HASH1RST BIT(5)
+#define RCC_AHB5RSTCLRR_RNG1RST BIT(6)
+#define RCC_AHB5RSTCLRR_AXIMCRST BIT(16)
+
+/* RCC_AHB6RSTSETR register fields */
+#define RCC_AHB6RSTSETR_GPURST BIT(5)
+#define RCC_AHB6RSTSETR_ETHMACRST BIT(10)
+#define RCC_AHB6RSTSETR_FMCRST BIT(12)
+#define RCC_AHB6RSTSETR_QSPIRST BIT(14)
+#define RCC_AHB6RSTSETR_SDMMC1RST BIT(16)
+#define RCC_AHB6RSTSETR_SDMMC2RST BIT(17)
+#define RCC_AHB6RSTSETR_CRC1RST BIT(20)
+#define RCC_AHB6RSTSETR_USBHRST BIT(24)
+
+/* RCC_AHB6RSTCLRR register fields */
+#define RCC_AHB6RSTCLRR_ETHMACRST BIT(10)
+#define RCC_AHB6RSTCLRR_FMCRST BIT(12)
+#define RCC_AHB6RSTCLRR_QSPIRST BIT(14)
+#define RCC_AHB6RSTCLRR_SDMMC1RST BIT(16)
+#define RCC_AHB6RSTCLRR_SDMMC2RST BIT(17)
+#define RCC_AHB6RSTCLRR_CRC1RST BIT(20)
+#define RCC_AHB6RSTCLRR_USBHRST BIT(24)
+
+/* RCC_TZAHB6RSTSETR register fields */
+#define RCC_TZAHB6RSTSETR_MDMARST BIT(0)
+
+/* RCC_TZAHB6RSTCLRR register fields */
+#define RCC_TZAHB6RSTCLRR_MDMARST BIT(0)
+
+/* RCC_MP_APB4ENSETR register fields */
+#define RCC_MP_APB4ENSETR_LTDCEN BIT(0)
+#define RCC_MP_APB4ENSETR_DSIEN BIT(4)
+#define RCC_MP_APB4ENSETR_DDRPERFMEN BIT(8)
+#define RCC_MP_APB4ENSETR_IWDG2APBEN BIT(15)
+#define RCC_MP_APB4ENSETR_USBPHYEN BIT(16)
+#define RCC_MP_APB4ENSETR_STGENROEN BIT(20)
+
+/* RCC_MP_APB4ENCLRR register fields */
+#define RCC_MP_APB4ENCLRR_LTDCEN BIT(0)
+#define RCC_MP_APB4ENCLRR_DSIEN BIT(4)
+#define RCC_MP_APB4ENCLRR_DDRPERFMEN BIT(8)
+#define RCC_MP_APB4ENCLRR_IWDG2APBEN BIT(15)
+#define RCC_MP_APB4ENCLRR_USBPHYEN BIT(16)
+#define RCC_MP_APB4ENCLRR_STGENROEN BIT(20)
+
+/* RCC_MP_APB5ENSETR register fields */
+#define RCC_MP_APB5ENSETR_SPI6EN BIT(0)
+#define RCC_MP_APB5ENSETR_I2C4EN BIT(2)
+#define RCC_MP_APB5ENSETR_I2C6EN BIT(3)
+#define RCC_MP_APB5ENSETR_USART1EN BIT(4)
+#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8)
+#define RCC_MP_APB5ENSETR_TZC1EN BIT(11)
+#define RCC_MP_APB5ENSETR_TZC2EN BIT(12)
+#define RCC_MP_APB5ENSETR_TZPCEN BIT(13)
+#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15)
+#define RCC_MP_APB5ENSETR_BSECEN BIT(16)
+#define RCC_MP_APB5ENSETR_STGENEN BIT(20)
+
+/* RCC_MP_APB5ENCLRR register fields */
+#define RCC_MP_APB5ENCLRR_SPI6EN BIT(0)
+#define RCC_MP_APB5ENCLRR_I2C4EN BIT(2)
+#define RCC_MP_APB5ENCLRR_I2C6EN BIT(3)
+#define RCC_MP_APB5ENCLRR_USART1EN BIT(4)
+#define RCC_MP_APB5ENCLRR_RTCAPBEN BIT(8)
+#define RCC_MP_APB5ENCLRR_TZC1EN BIT(11)
+#define RCC_MP_APB5ENCLRR_TZC2EN BIT(12)
+#define RCC_MP_APB5ENCLRR_TZPCEN BIT(13)
+#define RCC_MP_APB5ENCLRR_IWDG1APBEN BIT(15)
+#define RCC_MP_APB5ENCLRR_BSECEN BIT(16)
+#define RCC_MP_APB5ENCLRR_STGENEN BIT(20)
+
+/* RCC_MP_AHB5ENSETR register fields */
+#define RCC_MP_AHB5ENSETR_GPIOZEN BIT(0)
+#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4)
+#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5)
+#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6)
+#define RCC_MP_AHB5ENSETR_BKPSRAMEN BIT(8)
+#define RCC_MP_AHB5ENSETR_AXIMCEN BIT(16)
+
+/* RCC_MP_AHB5ENCLRR register fields */
+#define RCC_MP_AHB5ENCLRR_GPIOZEN BIT(0)
+#define RCC_MP_AHB5ENCLRR_CRYP1EN BIT(4)
+#define RCC_MP_AHB5ENCLRR_HASH1EN BIT(5)
+#define RCC_MP_AHB5ENCLRR_RNG1EN BIT(6)
+#define RCC_MP_AHB5ENCLRR_BKPSRAMEN BIT(8)
+#define RCC_MP_AHB5ENCLRR_AXIMCEN BIT(16)
+
+/* RCC_MP_AHB6ENSETR register fields */
+#define RCC_MP_AHB6ENSETR_MDMAEN BIT(0)
+#define RCC_MP_AHB6ENSETR_GPUEN BIT(5)
+#define RCC_MP_AHB6ENSETR_ETHCKEN BIT(7)
+#define RCC_MP_AHB6ENSETR_ETHTXEN BIT(8)
+#define RCC_MP_AHB6ENSETR_ETHRXEN BIT(9)
+#define RCC_MP_AHB6ENSETR_ETHMACEN BIT(10)
+#define RCC_MP_AHB6ENSETR_FMCEN BIT(12)
+#define RCC_MP_AHB6ENSETR_QSPIEN BIT(14)
+#define RCC_MP_AHB6ENSETR_SDMMC1EN BIT(16)
+#define RCC_MP_AHB6ENSETR_SDMMC2EN BIT(17)
+#define RCC_MP_AHB6ENSETR_CRC1EN BIT(20)
+#define RCC_MP_AHB6ENSETR_USBHEN BIT(24)
+
+/* RCC_MP_AHB6ENCLRR register fields */
+#define RCC_MP_AHB6ENCLRR_MDMAEN BIT(0)
+#define RCC_MP_AHB6ENCLRR_GPUEN BIT(5)
+#define RCC_MP_AHB6ENCLRR_ETHCKEN BIT(7)
+#define RCC_MP_AHB6ENCLRR_ETHTXEN BIT(8)
+#define RCC_MP_AHB6ENCLRR_ETHRXEN BIT(9)
+#define RCC_MP_AHB6ENCLRR_ETHMACEN BIT(10)
+#define RCC_MP_AHB6ENCLRR_FMCEN BIT(12)
+#define RCC_MP_AHB6ENCLRR_QSPIEN BIT(14)
+#define RCC_MP_AHB6ENCLRR_SDMMC1EN BIT(16)
+#define RCC_MP_AHB6ENCLRR_SDMMC2EN BIT(17)
+#define RCC_MP_AHB6ENCLRR_CRC1EN BIT(20)
+#define RCC_MP_AHB6ENCLRR_USBHEN BIT(24)
+
+/* RCC_MP_TZAHB6ENSETR register fields */
+#define RCC_MP_TZAHB6ENSETR_MDMAEN BIT(0)
+
+/* RCC_MP_TZAHB6ENCLRR register fields */
+#define RCC_MP_TZAHB6ENCLRR_MDMAEN BIT(0)
+
+/* RCC_MC_APB4ENSETR register fields */
+#define RCC_MC_APB4ENSETR_LTDCEN BIT(0)
+#define RCC_MC_APB4ENSETR_DSIEN BIT(4)
+#define RCC_MC_APB4ENSETR_DDRPERFMEN BIT(8)
+#define RCC_MC_APB4ENSETR_USBPHYEN BIT(16)
+#define RCC_MC_APB4ENSETR_STGENROEN BIT(20)
+
+/* RCC_MC_APB4ENCLRR register fields */
+#define RCC_MC_APB4ENCLRR_LTDCEN BIT(0)
+#define RCC_MC_APB4ENCLRR_DSIEN BIT(4)
+#define RCC_MC_APB4ENCLRR_DDRPERFMEN BIT(8)
+#define RCC_MC_APB4ENCLRR_USBPHYEN BIT(16)
+#define RCC_MC_APB4ENCLRR_STGENROEN BIT(20)
+
+/* RCC_MC_APB5ENSETR register fields */
+#define RCC_MC_APB5ENSETR_SPI6EN BIT(0)
+#define RCC_MC_APB5ENSETR_I2C4EN BIT(2)
+#define RCC_MC_APB5ENSETR_I2C6EN BIT(3)
+#define RCC_MC_APB5ENSETR_USART1EN BIT(4)
+#define RCC_MC_APB5ENSETR_RTCAPBEN BIT(8)
+#define RCC_MC_APB5ENSETR_TZC1EN BIT(11)
+#define RCC_MC_APB5ENSETR_TZC2EN BIT(12)
+#define RCC_MC_APB5ENSETR_TZPCEN BIT(13)
+#define RCC_MC_APB5ENSETR_BSECEN BIT(16)
+#define RCC_MC_APB5ENSETR_STGENEN BIT(20)
+
+/* RCC_MC_APB5ENCLRR register fields */
+#define RCC_MC_APB5ENCLRR_SPI6EN BIT(0)
+#define RCC_MC_APB5ENCLRR_I2C4EN BIT(2)
+#define RCC_MC_APB5ENCLRR_I2C6EN BIT(3)
+#define RCC_MC_APB5ENCLRR_USART1EN BIT(4)
+#define RCC_MC_APB5ENCLRR_RTCAPBEN BIT(8)
+#define RCC_MC_APB5ENCLRR_TZC1EN BIT(11)
+#define RCC_MC_APB5ENCLRR_TZC2EN BIT(12)
+#define RCC_MC_APB5ENCLRR_TZPCEN BIT(13)
+#define RCC_MC_APB5ENCLRR_BSECEN BIT(16)
+#define RCC_MC_APB5ENCLRR_STGENEN BIT(20)
+
+/* RCC_MC_AHB5ENSETR register fields */
+#define RCC_MC_AHB5ENSETR_GPIOZEN BIT(0)
+#define RCC_MC_AHB5ENSETR_CRYP1EN BIT(4)
+#define RCC_MC_AHB5ENSETR_HASH1EN BIT(5)
+#define RCC_MC_AHB5ENSETR_RNG1EN BIT(6)
+#define RCC_MC_AHB5ENSETR_BKPSRAMEN BIT(8)
+
+/* RCC_MC_AHB5ENCLRR register fields */
+#define RCC_MC_AHB5ENCLRR_GPIOZEN BIT(0)
+#define RCC_MC_AHB5ENCLRR_CRYP1EN BIT(4)
+#define RCC_MC_AHB5ENCLRR_HASH1EN BIT(5)
+#define RCC_MC_AHB5ENCLRR_RNG1EN BIT(6)
+#define RCC_MC_AHB5ENCLRR_BKPSRAMEN BIT(8)
+
+/* RCC_MC_AHB6ENSETR register fields */
+#define RCC_MC_AHB6ENSETR_MDMAEN BIT(0)
+#define RCC_MC_AHB6ENSETR_GPUEN BIT(5)
+#define RCC_MC_AHB6ENSETR_ETHCKEN BIT(7)
+#define RCC_MC_AHB6ENSETR_ETHTXEN BIT(8)
+#define RCC_MC_AHB6ENSETR_ETHRXEN BIT(9)
+#define RCC_MC_AHB6ENSETR_ETHMACEN BIT(10)
+#define RCC_MC_AHB6ENSETR_FMCEN BIT(12)
+#define RCC_MC_AHB6ENSETR_QSPIEN BIT(14)
+#define RCC_MC_AHB6ENSETR_SDMMC1EN BIT(16)
+#define RCC_MC_AHB6ENSETR_SDMMC2EN BIT(17)
+#define RCC_MC_AHB6ENSETR_CRC1EN BIT(20)
+#define RCC_MC_AHB6ENSETR_USBHEN BIT(24)
+
+/* RCC_MC_AHB6ENCLRR register fields */
+#define RCC_MC_AHB6ENCLRR_MDMAEN BIT(0)
+#define RCC_MC_AHB6ENCLRR_GPUEN BIT(5)
+#define RCC_MC_AHB6ENCLRR_ETHCKEN BIT(7)
+#define RCC_MC_AHB6ENCLRR_ETHTXEN BIT(8)
+#define RCC_MC_AHB6ENCLRR_ETHRXEN BIT(9)
+#define RCC_MC_AHB6ENCLRR_ETHMACEN BIT(10)
+#define RCC_MC_AHB6ENCLRR_FMCEN BIT(12)
+#define RCC_MC_AHB6ENCLRR_QSPIEN BIT(14)
+#define RCC_MC_AHB6ENCLRR_SDMMC1EN BIT(16)
+#define RCC_MC_AHB6ENCLRR_SDMMC2EN BIT(17)
+#define RCC_MC_AHB6ENCLRR_CRC1EN BIT(20)
+#define RCC_MC_AHB6ENCLRR_USBHEN BIT(24)
+
+/* RCC_MP_APB4LPENSETR register fields */
+#define RCC_MP_APB4LPENSETR_LTDCLPEN BIT(0)
+#define RCC_MP_APB4LPENSETR_DSILPEN BIT(4)
+#define RCC_MP_APB4LPENSETR_DDRPERFMLPEN BIT(8)
+#define RCC_MP_APB4LPENSETR_IWDG2APBLPEN BIT(15)
+#define RCC_MP_APB4LPENSETR_USBPHYLPEN BIT(16)
+#define RCC_MP_APB4LPENSETR_STGENROLPEN BIT(20)
+#define RCC_MP_APB4LPENSETR_STGENROSTPEN BIT(21)
+
+/* RCC_MP_APB4LPENCLRR register fields */
+#define RCC_MP_APB4LPENCLRR_LTDCLPEN BIT(0)
+#define RCC_MP_APB4LPENCLRR_DSILPEN BIT(4)
+#define RCC_MP_APB4LPENCLRR_DDRPERFMLPEN BIT(8)
+#define RCC_MP_APB4LPENCLRR_IWDG2APBLPEN BIT(15)
+#define RCC_MP_APB4LPENCLRR_USBPHYLPEN BIT(16)
+#define RCC_MP_APB4LPENCLRR_STGENROLPEN BIT(20)
+#define RCC_MP_APB4LPENCLRR_STGENROSTPEN BIT(21)
+
+/* RCC_MP_APB5LPENSETR register fields */
+#define RCC_MP_APB5LPENSETR_SPI6LPEN BIT(0)
+#define RCC_MP_APB5LPENSETR_I2C4LPEN BIT(2)
+#define RCC_MP_APB5LPENSETR_I2C6LPEN BIT(3)
+#define RCC_MP_APB5LPENSETR_USART1LPEN BIT(4)
+#define RCC_MP_APB5LPENSETR_RTCAPBLPEN BIT(8)
+#define RCC_MP_APB5LPENSETR_TZC1LPEN BIT(11)
+#define RCC_MP_APB5LPENSETR_TZC2LPEN BIT(12)
+#define RCC_MP_APB5LPENSETR_TZPCLPEN BIT(13)
+#define RCC_MP_APB5LPENSETR_IWDG1APBLPEN BIT(15)
+#define RCC_MP_APB5LPENSETR_BSECLPEN BIT(16)
+#define RCC_MP_APB5LPENSETR_STGENLPEN BIT(20)
+#define RCC_MP_APB5LPENSETR_STGENSTPEN BIT(21)
+
+/* RCC_MP_APB5LPENCLRR register fields */
+#define RCC_MP_APB5LPENCLRR_SPI6LPEN BIT(0)
+#define RCC_MP_APB5LPENCLRR_I2C4LPEN BIT(2)
+#define RCC_MP_APB5LPENCLRR_I2C6LPEN BIT(3)
+#define RCC_MP_APB5LPENCLRR_USART1LPEN BIT(4)
+#define RCC_MP_APB5LPENCLRR_RTCAPBLPEN BIT(8)
+#define RCC_MP_APB5LPENCLRR_TZC1LPEN BIT(11)
+#define RCC_MP_APB5LPENCLRR_TZC2LPEN BIT(12)
+#define RCC_MP_APB5LPENCLRR_TZPCLPEN BIT(13)
+#define RCC_MP_APB5LPENCLRR_IWDG1APBLPEN BIT(15)
+#define RCC_MP_APB5LPENCLRR_BSECLPEN BIT(16)
+#define RCC_MP_APB5LPENCLRR_STGENLPEN BIT(20)
+#define RCC_MP_APB5LPENCLRR_STGENSTPEN BIT(21)
+
+/* RCC_MP_AHB5LPENSETR register fields */
+#define RCC_MP_AHB5LPENSETR_GPIOZLPEN BIT(0)
+#define RCC_MP_AHB5LPENSETR_CRYP1LPEN BIT(4)
+#define RCC_MP_AHB5LPENSETR_HASH1LPEN BIT(5)
+#define RCC_MP_AHB5LPENSETR_RNG1LPEN BIT(6)
+#define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MP_AHB5LPENCLRR register fields */
+#define RCC_MP_AHB5LPENCLRR_GPIOZLPEN BIT(0)
+#define RCC_MP_AHB5LPENCLRR_CRYP1LPEN BIT(4)
+#define RCC_MP_AHB5LPENCLRR_HASH1LPEN BIT(5)
+#define RCC_MP_AHB5LPENCLRR_RNG1LPEN BIT(6)
+#define RCC_MP_AHB5LPENCLRR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MP_AHB6LPENSETR register fields */
+#define RCC_MP_AHB6LPENSETR_MDMALPEN BIT(0)
+#define RCC_MP_AHB6LPENSETR_GPULPEN BIT(5)
+#define RCC_MP_AHB6LPENSETR_ETHCKLPEN BIT(7)
+#define RCC_MP_AHB6LPENSETR_ETHTXLPEN BIT(8)
+#define RCC_MP_AHB6LPENSETR_ETHRXLPEN BIT(9)
+#define RCC_MP_AHB6LPENSETR_ETHMACLPEN BIT(10)
+#define RCC_MP_AHB6LPENSETR_ETHSTPEN BIT(11)
+#define RCC_MP_AHB6LPENSETR_FMCLPEN BIT(12)
+#define RCC_MP_AHB6LPENSETR_QSPILPEN BIT(14)
+#define RCC_MP_AHB6LPENSETR_SDMMC1LPEN BIT(16)
+#define RCC_MP_AHB6LPENSETR_SDMMC2LPEN BIT(17)
+#define RCC_MP_AHB6LPENSETR_CRC1LPEN BIT(20)
+#define RCC_MP_AHB6LPENSETR_USBHLPEN BIT(24)
+
+/* RCC_MP_AHB6LPENCLRR register fields */
+#define RCC_MP_AHB6LPENCLRR_MDMALPEN BIT(0)
+#define RCC_MP_AHB6LPENCLRR_GPULPEN BIT(5)
+#define RCC_MP_AHB6LPENCLRR_ETHCKLPEN BIT(7)
+#define RCC_MP_AHB6LPENCLRR_ETHTXLPEN BIT(8)
+#define RCC_MP_AHB6LPENCLRR_ETHRXLPEN BIT(9)
+#define RCC_MP_AHB6LPENCLRR_ETHMACLPEN BIT(10)
+#define RCC_MP_AHB6LPENCLRR_ETHSTPEN BIT(11)
+#define RCC_MP_AHB6LPENCLRR_FMCLPEN BIT(12)
+#define RCC_MP_AHB6LPENCLRR_QSPILPEN BIT(14)
+#define RCC_MP_AHB6LPENCLRR_SDMMC1LPEN BIT(16)
+#define RCC_MP_AHB6LPENCLRR_SDMMC2LPEN BIT(17)
+#define RCC_MP_AHB6LPENCLRR_CRC1LPEN BIT(20)
+#define RCC_MP_AHB6LPENCLRR_USBHLPEN BIT(24)
+
+/* RCC_MP_TZAHB6LPENSETR register fields */
+#define RCC_MP_TZAHB6LPENSETR_MDMALPEN BIT(0)
+
+/* RCC_MP_TZAHB6LPENCLRR register fields */
+#define RCC_MP_TZAHB6LPENCLRR_MDMALPEN BIT(0)
+
+/* RCC_MC_APB4LPENSETR register fields */
+#define RCC_MC_APB4LPENSETR_LTDCLPEN BIT(0)
+#define RCC_MC_APB4LPENSETR_DSILPEN BIT(4)
+#define RCC_MC_APB4LPENSETR_DDRPERFMLPEN BIT(8)
+#define RCC_MC_APB4LPENSETR_USBPHYLPEN BIT(16)
+#define RCC_MC_APB4LPENSETR_STGENROLPEN BIT(20)
+#define RCC_MC_APB4LPENSETR_STGENROSTPEN BIT(21)
+
+/* RCC_MC_APB4LPENCLRR register fields */
+#define RCC_MC_APB4LPENCLRR_LTDCLPEN BIT(0)
+#define RCC_MC_APB4LPENCLRR_DSILPEN BIT(4)
+#define RCC_MC_APB4LPENCLRR_DDRPERFMLPEN BIT(8)
+#define RCC_MC_APB4LPENCLRR_USBPHYLPEN BIT(16)
+#define RCC_MC_APB4LPENCLRR_STGENROLPEN BIT(20)
+#define RCC_MC_APB4LPENCLRR_STGENROSTPEN BIT(21)
+
+/* RCC_MC_APB5LPENSETR register fields */
+#define RCC_MC_APB5LPENSETR_SPI6LPEN BIT(0)
+#define RCC_MC_APB5LPENSETR_I2C4LPEN BIT(2)
+#define RCC_MC_APB5LPENSETR_I2C6LPEN BIT(3)
+#define RCC_MC_APB5LPENSETR_USART1LPEN BIT(4)
+#define RCC_MC_APB5LPENSETR_RTCAPBLPEN BIT(8)
+#define RCC_MC_APB5LPENSETR_TZC1LPEN BIT(11)
+#define RCC_MC_APB5LPENSETR_TZC2LPEN BIT(12)
+#define RCC_MC_APB5LPENSETR_TZPCLPEN BIT(13)
+#define RCC_MC_APB5LPENSETR_BSECLPEN BIT(16)
+#define RCC_MC_APB5LPENSETR_STGENLPEN BIT(20)
+#define RCC_MC_APB5LPENSETR_STGENSTPEN BIT(21)
+
+/* RCC_MC_APB5LPENCLRR register fields */
+#define RCC_MC_APB5LPENCLRR_SPI6LPEN BIT(0)
+#define RCC_MC_APB5LPENCLRR_I2C4LPEN BIT(2)
+#define RCC_MC_APB5LPENCLRR_I2C6LPEN BIT(3)
+#define RCC_MC_APB5LPENCLRR_USART1LPEN BIT(4)
+#define RCC_MC_APB5LPENCLRR_RTCAPBLPEN BIT(8)
+#define RCC_MC_APB5LPENCLRR_TZC1LPEN BIT(11)
+#define RCC_MC_APB5LPENCLRR_TZC2LPEN BIT(12)
+#define RCC_MC_APB5LPENCLRR_TZPCLPEN BIT(13)
+#define RCC_MC_APB5LPENCLRR_BSECLPEN BIT(16)
+#define RCC_MC_APB5LPENCLRR_STGENLPEN BIT(20)
+#define RCC_MC_APB5LPENCLRR_STGENSTPEN BIT(21)
+
+/* RCC_MC_AHB5LPENSETR register fields */
+#define RCC_MC_AHB5LPENSETR_GPIOZLPEN BIT(0)
+#define RCC_MC_AHB5LPENSETR_CRYP1LPEN BIT(4)
+#define RCC_MC_AHB5LPENSETR_HASH1LPEN BIT(5)
+#define RCC_MC_AHB5LPENSETR_RNG1LPEN BIT(6)
+#define RCC_MC_AHB5LPENSETR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MC_AHB5LPENCLRR register fields */
+#define RCC_MC_AHB5LPENCLRR_GPIOZLPEN BIT(0)
+#define RCC_MC_AHB5LPENCLRR_CRYP1LPEN BIT(4)
+#define RCC_MC_AHB5LPENCLRR_HASH1LPEN BIT(5)
+#define RCC_MC_AHB5LPENCLRR_RNG1LPEN BIT(6)
+#define RCC_MC_AHB5LPENCLRR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MC_AHB6LPENSETR register fields */
+#define RCC_MC_AHB6LPENSETR_MDMALPEN BIT(0)
+#define RCC_MC_AHB6LPENSETR_GPULPEN BIT(5)
+#define RCC_MC_AHB6LPENSETR_ETHCKLPEN BIT(7)
+#define RCC_MC_AHB6LPENSETR_ETHTXLPEN BIT(8)
+#define RCC_MC_AHB6LPENSETR_ETHRXLPEN BIT(9)
+#define RCC_MC_AHB6LPENSETR_ETHMACLPEN BIT(10)
+#define RCC_MC_AHB6LPENSETR_ETHSTPEN BIT(11)
+#define RCC_MC_AHB6LPENSETR_FMCLPEN BIT(12)
+#define RCC_MC_AHB6LPENSETR_QSPILPEN BIT(14)
+#define RCC_MC_AHB6LPENSETR_SDMMC1LPEN BIT(16)
+#define RCC_MC_AHB6LPENSETR_SDMMC2LPEN BIT(17)
+#define RCC_MC_AHB6LPENSETR_CRC1LPEN BIT(20)
+#define RCC_MC_AHB6LPENSETR_USBHLPEN BIT(24)
+
+/* RCC_MC_AHB6LPENCLRR register fields */
+#define RCC_MC_AHB6LPENCLRR_MDMALPEN BIT(0)
+#define RCC_MC_AHB6LPENCLRR_GPULPEN BIT(5)
+#define RCC_MC_AHB6LPENCLRR_ETHCKLPEN BIT(7)
+#define RCC_MC_AHB6LPENCLRR_ETHTXLPEN BIT(8)
+#define RCC_MC_AHB6LPENCLRR_ETHRXLPEN BIT(9)
+#define RCC_MC_AHB6LPENCLRR_ETHMACLPEN BIT(10)
+#define RCC_MC_AHB6LPENCLRR_ETHSTPEN BIT(11)
+#define RCC_MC_AHB6LPENCLRR_FMCLPEN BIT(12)
+#define RCC_MC_AHB6LPENCLRR_QSPILPEN BIT(14)
+#define RCC_MC_AHB6LPENCLRR_SDMMC1LPEN BIT(16)
+#define RCC_MC_AHB6LPENCLRR_SDMMC2LPEN BIT(17)
+#define RCC_MC_AHB6LPENCLRR_CRC1LPEN BIT(20)
+#define RCC_MC_AHB6LPENCLRR_USBHLPEN BIT(24)
+
+/* RCC_BR_RSTSCLRR register fields */
+#define RCC_BR_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_BR_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_BR_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_BR_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_BR_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_BR_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_BR_RSTSCLRR_MCSYSRSTF BIT(7)
+#define RCC_BR_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_BR_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_BR_RSTSCLRR_MPUP0RSTF BIT(13)
+#define RCC_BR_RSTSCLRR_MPUP1RSTF BIT(14)
+
+/* RCC_MP_GRSTCSETR register fields */
+#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
+#define RCC_MP_GRSTCSETR_MCURST BIT(1)
+#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4)
+#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5)
+
+/* RCC_MP_RSTSCLRR register fields */
+#define RCC_MP_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_MP_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_MP_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_MP_RSTSCLRR_MCSYSRSTF BIT(7)
+#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11)
+#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12)
+#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13)
+#define RCC_MP_RSTSCLRR_MPUP1RSTF BIT(14)
+#define RCC_MP_RSTSCLRR_SPARE BIT(15)
+
+/* RCC_MP_IWDGFZSETR register fields */
+#define RCC_MP_IWDGFZSETR_FZ_IWDG1 BIT(0)
+#define RCC_MP_IWDGFZSETR_FZ_IWDG2 BIT(1)
+
+/* RCC_MP_IWDGFZCLRR register fields */
+#define RCC_MP_IWDGFZCLRR_FZ_IWDG1 BIT(0)
+#define RCC_MP_IWDGFZCLRR_FZ_IWDG2 BIT(1)
+
+/* RCC_MP_CIER register fields */
+#define RCC_MP_CIER_LSIRDYIE BIT(0)
+#define RCC_MP_CIER_LSERDYIE BIT(1)
+#define RCC_MP_CIER_HSIRDYIE BIT(2)
+#define RCC_MP_CIER_HSERDYIE BIT(3)
+#define RCC_MP_CIER_CSIRDYIE BIT(4)
+#define RCC_MP_CIER_PLL1DYIE BIT(8)
+#define RCC_MP_CIER_PLL2DYIE BIT(9)
+#define RCC_MP_CIER_PLL3DYIE BIT(10)
+#define RCC_MP_CIER_PLL4DYIE BIT(11)
+#define RCC_MP_CIER_LSECSSIE BIT(16)
+#define RCC_MP_CIER_WKUPIE BIT(20)
+
+/* RCC_MP_CIFR register fields */
+#define RCC_MP_CIFR_MASK U(0x110F1F)
+#define RCC_MP_CIFR_LSIRDYF BIT(0)
+#define RCC_MP_CIFR_LSERDYF BIT(1)
+#define RCC_MP_CIFR_HSIRDYF BIT(2)
+#define RCC_MP_CIFR_HSERDYF BIT(3)
+#define RCC_MP_CIFR_CSIRDYF BIT(4)
+#define RCC_MP_CIFR_PLL1DYF BIT(8)
+#define RCC_MP_CIFR_PLL2DYF BIT(9)
+#define RCC_MP_CIFR_PLL3DYF BIT(10)
+#define RCC_MP_CIFR_PLL4DYF BIT(11)
+#define RCC_MP_CIFR_LSECSSF BIT(16)
+#define RCC_MP_CIFR_WKUPF BIT(20)
+
+/* RCC_PWRLPDLYCR register fields */
+#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0)
+#define RCC_PWRLPDLYCR_PWRLP_DLY_SHIFT 0
+#define RCC_PWRLPDLYCR_MCTMPSKP BIT(24)
+
+/* RCC_MP_RSTSSETR register fields */
+#define RCC_MP_RSTSSETR_PORRSTF BIT(0)
+#define RCC_MP_RSTSSETR_BORRSTF BIT(1)
+#define RCC_MP_RSTSSETR_PADRSTF BIT(2)
+#define RCC_MP_RSTSSETR_HCSSRSTF BIT(3)
+#define RCC_MP_RSTSSETR_VCORERSTF BIT(4)
+#define RCC_MP_RSTSSETR_MPSYSRSTF BIT(6)
+#define RCC_MP_RSTSSETR_MCSYSRSTF BIT(7)
+#define RCC_MP_RSTSSETR_IWDG1RSTF BIT(8)
+#define RCC_MP_RSTSSETR_IWDG2RSTF BIT(9)
+#define RCC_MP_RSTSSETR_STDBYRSTF BIT(11)
+#define RCC_MP_RSTSSETR_CSTDBYRSTF BIT(12)
+#define RCC_MP_RSTSSETR_MPUP0RSTF BIT(13)
+#define RCC_MP_RSTSSETR_MPUP1RSTF BIT(14)
+#define RCC_MP_RSTSSETR_SPARE BIT(15)
+
+/* RCC_MCO1CFGR register fields */
+#define RCC_MCO1CFGR_MCO1SEL_MASK GENMASK(2, 0)
+#define RCC_MCO1CFGR_MCO1SEL_SHIFT 0
+#define RCC_MCO1CFGR_MCO1DIV_MASK GENMASK(7, 4)
+#define RCC_MCO1CFGR_MCO1DIV_SHIFT 4
+#define RCC_MCO1CFGR_MCO1ON BIT(12)
+
+/* RCC_MCO2CFGR register fields */
+#define RCC_MCO2CFGR_MCO2SEL_MASK GENMASK(2, 0)
+#define RCC_MCO2CFGR_MCO2SEL_SHIFT 0
+#define RCC_MCO2CFGR_MCO2DIV_MASK GENMASK(7, 4)
+#define RCC_MCO2CFGR_MCO2DIV_SHIFT 4
+#define RCC_MCO2CFGR_MCO2ON BIT(12)
+
+/* RCC_OCRDYR register fields */
+#define RCC_OCRDYR_HSIRDY BIT(0)
+#define RCC_OCRDYR_HSIDIVRDY BIT(2)
+#define RCC_OCRDYR_CSIRDY BIT(4)
+#define RCC_OCRDYR_HSERDY BIT(8)
+#define RCC_OCRDYR_MPUCKRDY BIT(23)
+#define RCC_OCRDYR_AXICKRDY BIT(24)
+#define RCC_OCRDYR_CKREST BIT(25)
+
+/* RCC_DBGCFGR register fields */
+#define RCC_DBGCFGR_TRACEDIV_MASK GENMASK(2, 0)
+#define RCC_DBGCFGR_TRACEDIV_SHIFT 0
+#define RCC_DBGCFGR_DBGCKEN BIT(8)
+#define RCC_DBGCFGR_TRACECKEN BIT(9)
+#define RCC_DBGCFGR_DBGRST BIT(12)
+
+/* RCC_RCK3SELR register fields */
+#define RCC_RCK3SELR_PLL3SRC_MASK GENMASK(1, 0)
+#define RCC_RCK3SELR_PLL3SRC_SHIFT 0
+#define RCC_RCK3SELR_PLL3SRCRDY BIT(31)
+
+/* RCC_RCK4SELR register fields */
+#define RCC_RCK4SELR_PLL4SRC_MASK GENMASK(1, 0)
+#define RCC_RCK4SELR_PLL4SRC_SHIFT 0
+#define RCC_RCK4SELR_PLL4SRCRDY BIT(31)
+
+/* RCC_TIMG1PRER register fields */
+#define RCC_TIMG1PRER_TIMG1PRE BIT(0)
+#define RCC_TIMG1PRER_TIMG1PRERDY BIT(31)
+
+/* RCC_TIMG2PRER register fields */
+#define RCC_TIMG2PRER_TIMG2PRE BIT(0)
+#define RCC_TIMG2PRER_TIMG2PRERDY BIT(31)
+
+/* RCC_MCUDIVR register fields */
+#define RCC_MCUDIVR_MCUDIV_MASK GENMASK(3, 0)
+#define RCC_MCUDIVR_MCUDIV_SHIFT 0
+#define RCC_MCUDIVR_MCUDIVRDY BIT(31)
+
+/* RCC_APB1DIVR register fields */
+#define RCC_APB1DIVR_APB1DIV_MASK GENMASK(2, 0)
+#define RCC_APB1DIVR_APB1DIV_SHIFT 0
+#define RCC_APB1DIVR_APB1DIVRDY BIT(31)
+
+/* RCC_APB2DIVR register fields */
+#define RCC_APB2DIVR_APB2DIV_MASK GENMASK(2, 0)
+#define RCC_APB2DIVR_APB2DIV_SHIFT 0
+#define RCC_APB2DIVR_APB2DIVRDY BIT(31)
+
+/* RCC_APB3DIVR register fields */
+#define RCC_APB3DIVR_APB3DIV_MASK GENMASK(2, 0)
+#define RCC_APB3DIVR_APB3DIV_SHIFT 0
+#define RCC_APB3DIVR_APB3DIVRDY BIT(31)
+
+/* RCC_PLL3CR register fields */
+#define RCC_PLL3CR_PLLON BIT(0)
+#define RCC_PLL3CR_PLL3RDY BIT(1)
+#define RCC_PLL3CR_SSCG_CTRL BIT(2)
+#define RCC_PLL3CR_DIVPEN BIT(4)
+#define RCC_PLL3CR_DIVQEN BIT(5)
+#define RCC_PLL3CR_DIVREN BIT(6)
+
+/* RCC_PLL3CFGR1 register fields */
+#define RCC_PLL3CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL3CFGR1_DIVN_SHIFT 0
+#define RCC_PLL3CFGR1_DIVM3_MASK GENMASK(21, 16)
+#define RCC_PLL3CFGR1_DIVM3_SHIFT 16
+#define RCC_PLL3CFGR1_IFRGE_MASK GENMASK(25, 24)
+#define RCC_PLL3CFGR1_IFRGE_SHIFT 24
+
+/* RCC_PLL3CFGR2 register fields */
+#define RCC_PLL3CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL3CFGR2_DIVP_SHIFT 0
+#define RCC_PLL3CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL3CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL3CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL3CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL3FRACR register fields */
+#define RCC_PLL3FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL3FRACR_FRACV_SHIFT 3
+#define RCC_PLL3FRACR_FRACLE BIT(16)
+
+/* RCC_PLL3CSGR register fields */
+#define RCC_PLL3CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL3CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL3CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL3CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL3CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL3CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL3CSGR_INC_STEP_SHIFT 16
+
+/* RCC_PLL4CR register fields */
+#define RCC_PLL4CR_PLLON BIT(0)
+#define RCC_PLL4CR_PLL4RDY BIT(1)
+#define RCC_PLL4CR_SSCG_CTRL BIT(2)
+#define RCC_PLL4CR_DIVPEN BIT(4)
+#define RCC_PLL4CR_DIVQEN BIT(5)
+#define RCC_PLL4CR_DIVREN BIT(6)
+
+/* RCC_PLL4CFGR1 register fields */
+#define RCC_PLL4CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL4CFGR1_DIVN_SHIFT 0
+#define RCC_PLL4CFGR1_DIVM4_MASK GENMASK(21, 16)
+#define RCC_PLL4CFGR1_DIVM4_SHIFT 16
+#define RCC_PLL4CFGR1_IFRGE_MASK GENMASK(25, 24)
+#define RCC_PLL4CFGR1_IFRGE_SHIFT 24
+
+/* RCC_PLL4CFGR2 register fields */
+#define RCC_PLL4CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL4CFGR2_DIVP_SHIFT 0
+#define RCC_PLL4CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL4CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL4CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL4CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL4FRACR register fields */
+#define RCC_PLL4FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL4FRACR_FRACV_SHIFT 3
+#define RCC_PLL4FRACR_FRACLE BIT(16)
+
+/* RCC_PLL4CSGR register fields */
+#define RCC_PLL4CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL4CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL4CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL4CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL4CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL4CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL4CSGR_INC_STEP_SHIFT 16
+
/* RCC_I2C12CKSELR register fields */
#define RCC_I2C12CKSELR_I2C12SRC_MASK GENMASK(2, 0)
#define RCC_I2C12CKSELR_I2C12SRC_SHIFT 0
@@ -520,11 +1170,40 @@
#define RCC_I2C35CKSELR_I2C35SRC_MASK GENMASK(2, 0)
#define RCC_I2C35CKSELR_I2C35SRC_SHIFT 0
+/* RCC_SAI1CKSELR register fields */
+#define RCC_SAI1CKSELR_SAI1SRC_MASK GENMASK(2, 0)
+#define RCC_SAI1CKSELR_SAI1SRC_SHIFT 0
+
+/* RCC_SAI2CKSELR register fields */
+#define RCC_SAI2CKSELR_SAI2SRC_MASK GENMASK(2, 0)
+#define RCC_SAI2CKSELR_SAI2SRC_SHIFT 0
+
+/* RCC_SAI3CKSELR register fields */
+#define RCC_SAI3CKSELR_SAI3SRC_MASK GENMASK(2, 0)
+#define RCC_SAI3CKSELR_SAI3SRC_SHIFT 0
+
+/* RCC_SAI4CKSELR register fields */
+#define RCC_SAI4CKSELR_SAI4SRC_MASK GENMASK(2, 0)
+#define RCC_SAI4CKSELR_SAI4SRC_SHIFT 0
+
+/* RCC_SPI2S1CKSELR register fields */
+#define RCC_SPI2S1CKSELR_SPI1SRC_MASK GENMASK(2, 0)
+#define RCC_SPI2S1CKSELR_SPI1SRC_SHIFT 0
+
+/* RCC_SPI2S23CKSELR register fields */
+#define RCC_SPI2S23CKSELR_SPI23SRC_MASK GENMASK(2, 0)
+#define RCC_SPI2S23CKSELR_SPI23SRC_SHIFT 0
+
+/* RCC_SPI45CKSELR register fields */
+#define RCC_SPI45CKSELR_SPI45SRC_MASK GENMASK(2, 0)
+#define RCC_SPI45CKSELR_SPI45SRC_SHIFT 0
+
/* RCC_UART6CKSELR register fields */
#define RCC_UART6CKSELR_UART6SRC_MASK GENMASK(2, 0)
#define RCC_UART6CKSELR_UART6SRC_SHIFT 0
/* RCC_UART24CKSELR register fields */
+#define RCC_UART24CKSELR_HSI 0x00000002
#define RCC_UART24CKSELR_UART24SRC_MASK GENMASK(2, 0)
#define RCC_UART24CKSELR_UART24SRC_SHIFT 0
@@ -547,6 +1226,8 @@
/* RCC_ETHCKSELR register fields */
#define RCC_ETHCKSELR_ETHSRC_MASK GENMASK(1, 0)
#define RCC_ETHCKSELR_ETHSRC_SHIFT 0
+#define RCC_ETHCKSELR_ETHPTPDIV_MASK GENMASK(7, 4)
+#define RCC_ETHCKSELR_ETHPTPDIV_SHIFT 4
/* RCC_QSPICKSELR register fields */
#define RCC_QSPICKSELR_QSPISRC_MASK GENMASK(1, 0)
@@ -556,10 +1237,1092 @@
#define RCC_FMCCKSELR_FMCSRC_MASK GENMASK(1, 0)
#define RCC_FMCCKSELR_FMCSRC_SHIFT 0
+/* RCC_FDCANCKSELR register fields */
+#define RCC_FDCANCKSELR_FDCANSRC_MASK GENMASK(1, 0)
+#define RCC_FDCANCKSELR_FDCANSRC_SHIFT 0
+
+/* RCC_SPDIFCKSELR register fields */
+#define RCC_SPDIFCKSELR_SPDIFSRC_MASK GENMASK(1, 0)
+#define RCC_SPDIFCKSELR_SPDIFSRC_SHIFT 0
+
+/* RCC_CECCKSELR register fields */
+#define RCC_CECCKSELR_CECSRC_MASK GENMASK(1, 0)
+#define RCC_CECCKSELR_CECSRC_SHIFT 0
+
/* RCC_USBCKSELR register fields */
#define RCC_USBCKSELR_USBPHYSRC_MASK GENMASK(1, 0)
#define RCC_USBCKSELR_USBPHYSRC_SHIFT 0
+#define RCC_USBCKSELR_USBOSRC BIT(4)
#define RCC_USBCKSELR_USBOSRC_MASK BIT(4)
#define RCC_USBCKSELR_USBOSRC_SHIFT 4
+/* RCC_RNG2CKSELR register fields */
+#define RCC_RNG2CKSELR_RNG2SRC_MASK GENMASK(1, 0)
+#define RCC_RNG2CKSELR_RNG2SRC_SHIFT 0
+
+/* RCC_DSICKSELR register fields */
+#define RCC_DSICKSELR_DSISRC BIT(0)
+
+/* RCC_ADCCKSELR register fields */
+#define RCC_ADCCKSELR_ADCSRC_MASK GENMASK(1, 0)
+#define RCC_ADCCKSELR_ADCSRC_SHIFT 0
+
+/* RCC_LPTIM45CKSELR register fields */
+#define RCC_LPTIM45CKSELR_LPTIM45SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM45CKSELR_LPTIM45SRC_SHIFT 0
+
+/* RCC_LPTIM23CKSELR register fields */
+#define RCC_LPTIM23CKSELR_LPTIM23SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM23CKSELR_LPTIM23SRC_SHIFT 0
+
+/* RCC_LPTIM1CKSELR register fields */
+#define RCC_LPTIM1CKSELR_LPTIM1SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM1CKSELR_LPTIM1SRC_SHIFT 0
+
+/* RCC_APB1RSTSETR register fields */
+#define RCC_APB1RSTSETR_TIM2RST BIT(0)
+#define RCC_APB1RSTSETR_TIM3RST BIT(1)
+#define RCC_APB1RSTSETR_TIM4RST BIT(2)
+#define RCC_APB1RSTSETR_TIM5RST BIT(3)
+#define RCC_APB1RSTSETR_TIM6RST BIT(4)
+#define RCC_APB1RSTSETR_TIM7RST BIT(5)
+#define RCC_APB1RSTSETR_TIM12RST BIT(6)
+#define RCC_APB1RSTSETR_TIM13RST BIT(7)
+#define RCC_APB1RSTSETR_TIM14RST BIT(8)
+#define RCC_APB1RSTSETR_LPTIM1RST BIT(9)
+#define RCC_APB1RSTSETR_SPI2RST BIT(11)
+#define RCC_APB1RSTSETR_SPI3RST BIT(12)
+#define RCC_APB1RSTSETR_USART2RST BIT(14)
+#define RCC_APB1RSTSETR_USART3RST BIT(15)
+#define RCC_APB1RSTSETR_UART4RST BIT(16)
+#define RCC_APB1RSTSETR_UART5RST BIT(17)
+#define RCC_APB1RSTSETR_UART7RST BIT(18)
+#define RCC_APB1RSTSETR_UART8RST BIT(19)
+#define RCC_APB1RSTSETR_I2C1RST BIT(21)
+#define RCC_APB1RSTSETR_I2C2RST BIT(22)
+#define RCC_APB1RSTSETR_I2C3RST BIT(23)
+#define RCC_APB1RSTSETR_I2C5RST BIT(24)
+#define RCC_APB1RSTSETR_SPDIFRST BIT(26)
+#define RCC_APB1RSTSETR_CECRST BIT(27)
+#define RCC_APB1RSTSETR_DAC12RST BIT(29)
+#define RCC_APB1RSTSETR_MDIOSRST BIT(31)
+
+/* RCC_APB1RSTCLRR register fields */
+#define RCC_APB1RSTCLRR_TIM2RST BIT(0)
+#define RCC_APB1RSTCLRR_TIM3RST BIT(1)
+#define RCC_APB1RSTCLRR_TIM4RST BIT(2)
+#define RCC_APB1RSTCLRR_TIM5RST BIT(3)
+#define RCC_APB1RSTCLRR_TIM6RST BIT(4)
+#define RCC_APB1RSTCLRR_TIM7RST BIT(5)
+#define RCC_APB1RSTCLRR_TIM12RST BIT(6)
+#define RCC_APB1RSTCLRR_TIM13RST BIT(7)
+#define RCC_APB1RSTCLRR_TIM14RST BIT(8)
+#define RCC_APB1RSTCLRR_LPTIM1RST BIT(9)
+#define RCC_APB1RSTCLRR_SPI2RST BIT(11)
+#define RCC_APB1RSTCLRR_SPI3RST BIT(12)
+#define RCC_APB1RSTCLRR_USART2RST BIT(14)
+#define RCC_APB1RSTCLRR_USART3RST BIT(15)
+#define RCC_APB1RSTCLRR_UART4RST BIT(16)
+#define RCC_APB1RSTCLRR_UART5RST BIT(17)
+#define RCC_APB1RSTCLRR_UART7RST BIT(18)
+#define RCC_APB1RSTCLRR_UART8RST BIT(19)
+#define RCC_APB1RSTCLRR_I2C1RST BIT(21)
+#define RCC_APB1RSTCLRR_I2C2RST BIT(22)
+#define RCC_APB1RSTCLRR_I2C3RST BIT(23)
+#define RCC_APB1RSTCLRR_I2C5RST BIT(24)
+#define RCC_APB1RSTCLRR_SPDIFRST BIT(26)
+#define RCC_APB1RSTCLRR_CECRST BIT(27)
+#define RCC_APB1RSTCLRR_DAC12RST BIT(29)
+#define RCC_APB1RSTCLRR_MDIOSRST BIT(31)
+
+/* RCC_APB2RSTSETR register fields */
+#define RCC_APB2RSTSETR_TIM1RST BIT(0)
+#define RCC_APB2RSTSETR_TIM8RST BIT(1)
+#define RCC_APB2RSTSETR_TIM15RST BIT(2)
+#define RCC_APB2RSTSETR_TIM16RST BIT(3)
+#define RCC_APB2RSTSETR_TIM17RST BIT(4)
+#define RCC_APB2RSTSETR_SPI1RST BIT(8)
+#define RCC_APB2RSTSETR_SPI4RST BIT(9)
+#define RCC_APB2RSTSETR_SPI5RST BIT(10)
+#define RCC_APB2RSTSETR_USART6RST BIT(13)
+#define RCC_APB2RSTSETR_SAI1RST BIT(16)
+#define RCC_APB2RSTSETR_SAI2RST BIT(17)
+#define RCC_APB2RSTSETR_SAI3RST BIT(18)
+#define RCC_APB2RSTSETR_DFSDMRST BIT(20)
+#define RCC_APB2RSTSETR_FDCANRST BIT(24)
+
+/* RCC_APB2RSTCLRR register fields */
+#define RCC_APB2RSTCLRR_TIM1RST BIT(0)
+#define RCC_APB2RSTCLRR_TIM8RST BIT(1)
+#define RCC_APB2RSTCLRR_TIM15RST BIT(2)
+#define RCC_APB2RSTCLRR_TIM16RST BIT(3)
+#define RCC_APB2RSTCLRR_TIM17RST BIT(4)
+#define RCC_APB2RSTCLRR_SPI1RST BIT(8)
+#define RCC_APB2RSTCLRR_SPI4RST BIT(9)
+#define RCC_APB2RSTCLRR_SPI5RST BIT(10)
+#define RCC_APB2RSTCLRR_USART6RST BIT(13)
+#define RCC_APB2RSTCLRR_SAI1RST BIT(16)
+#define RCC_APB2RSTCLRR_SAI2RST BIT(17)
+#define RCC_APB2RSTCLRR_SAI3RST BIT(18)
+#define RCC_APB2RSTCLRR_DFSDMRST BIT(20)
+#define RCC_APB2RSTCLRR_FDCANRST BIT(24)
+
+/* RCC_APB3RSTSETR register fields */
+#define RCC_APB3RSTSETR_LPTIM2RST BIT(0)
+#define RCC_APB3RSTSETR_LPTIM3RST BIT(1)
+#define RCC_APB3RSTSETR_LPTIM4RST BIT(2)
+#define RCC_APB3RSTSETR_LPTIM5RST BIT(3)
+#define RCC_APB3RSTSETR_SAI4RST BIT(8)
+#define RCC_APB3RSTSETR_SYSCFGRST BIT(11)
+#define RCC_APB3RSTSETR_VREFRST BIT(13)
+#define RCC_APB3RSTSETR_TMPSENSRST BIT(16)
+#define RCC_APB3RSTSETR_PMBCTRLRST BIT(17)
+
+/* RCC_APB3RSTCLRR register fields */
+#define RCC_APB3RSTCLRR_LPTIM2RST BIT(0)
+#define RCC_APB3RSTCLRR_LPTIM3RST BIT(1)
+#define RCC_APB3RSTCLRR_LPTIM4RST BIT(2)
+#define RCC_APB3RSTCLRR_LPTIM5RST BIT(3)
+#define RCC_APB3RSTCLRR_SAI4RST BIT(8)
+#define RCC_APB3RSTCLRR_SYSCFGRST BIT(11)
+#define RCC_APB3RSTCLRR_VREFRST BIT(13)
+#define RCC_APB3RSTCLRR_TMPSENSRST BIT(16)
+#define RCC_APB3RSTCLRR_PMBCTRLRST BIT(17)
+
+/* RCC_AHB2RSTSETR register fields */
+#define RCC_AHB2RSTSETR_DMA1RST BIT(0)
+#define RCC_AHB2RSTSETR_DMA2RST BIT(1)
+#define RCC_AHB2RSTSETR_DMAMUXRST BIT(2)
+#define RCC_AHB2RSTSETR_ADC12RST BIT(5)
+#define RCC_AHB2RSTSETR_USBORST BIT(8)
+#define RCC_AHB2RSTSETR_SDMMC3RST BIT(16)
+
+/* RCC_AHB2RSTCLRR register fields */
+#define RCC_AHB2RSTCLRR_DMA1RST BIT(0)
+#define RCC_AHB2RSTCLRR_DMA2RST BIT(1)
+#define RCC_AHB2RSTCLRR_DMAMUXRST BIT(2)
+#define RCC_AHB2RSTCLRR_ADC12RST BIT(5)
+#define RCC_AHB2RSTCLRR_USBORST BIT(8)
+#define RCC_AHB2RSTCLRR_SDMMC3RST BIT(16)
+
+/* RCC_AHB3RSTSETR register fields */
+#define RCC_AHB3RSTSETR_DCMIRST BIT(0)
+#define RCC_AHB3RSTSETR_CRYP2RST BIT(4)
+#define RCC_AHB3RSTSETR_HASH2RST BIT(5)
+#define RCC_AHB3RSTSETR_RNG2RST BIT(6)
+#define RCC_AHB3RSTSETR_CRC2RST BIT(7)
+#define RCC_AHB3RSTSETR_HSEMRST BIT(11)
+#define RCC_AHB3RSTSETR_IPCCRST BIT(12)
+
+/* RCC_AHB3RSTCLRR register fields */
+#define RCC_AHB3RSTCLRR_DCMIRST BIT(0)
+#define RCC_AHB3RSTCLRR_CRYP2RST BIT(4)
+#define RCC_AHB3RSTCLRR_HASH2RST BIT(5)
+#define RCC_AHB3RSTCLRR_RNG2RST BIT(6)
+#define RCC_AHB3RSTCLRR_CRC2RST BIT(7)
+#define RCC_AHB3RSTCLRR_HSEMRST BIT(11)
+#define RCC_AHB3RSTCLRR_IPCCRST BIT(12)
+
+/* RCC_AHB4RSTSETR register fields */
+#define RCC_AHB4RSTSETR_GPIOARST BIT(0)
+#define RCC_AHB4RSTSETR_GPIOBRST BIT(1)
+#define RCC_AHB4RSTSETR_GPIOCRST BIT(2)
+#define RCC_AHB4RSTSETR_GPIODRST BIT(3)
+#define RCC_AHB4RSTSETR_GPIOERST BIT(4)
+#define RCC_AHB4RSTSETR_GPIOFRST BIT(5)
+#define RCC_AHB4RSTSETR_GPIOGRST BIT(6)
+#define RCC_AHB4RSTSETR_GPIOHRST BIT(7)
+#define RCC_AHB4RSTSETR_GPIOIRST BIT(8)
+#define RCC_AHB4RSTSETR_GPIOJRST BIT(9)
+#define RCC_AHB4RSTSETR_GPIOKRST BIT(10)
+
+/* RCC_AHB4RSTCLRR register fields */
+#define RCC_AHB4RSTCLRR_GPIOARST BIT(0)
+#define RCC_AHB4RSTCLRR_GPIOBRST BIT(1)
+#define RCC_AHB4RSTCLRR_GPIOCRST BIT(2)
+#define RCC_AHB4RSTCLRR_GPIODRST BIT(3)
+#define RCC_AHB4RSTCLRR_GPIOERST BIT(4)
+#define RCC_AHB4RSTCLRR_GPIOFRST BIT(5)
+#define RCC_AHB4RSTCLRR_GPIOGRST BIT(6)
+#define RCC_AHB4RSTCLRR_GPIOHRST BIT(7)
+#define RCC_AHB4RSTCLRR_GPIOIRST BIT(8)
+#define RCC_AHB4RSTCLRR_GPIOJRST BIT(9)
+#define RCC_AHB4RSTCLRR_GPIOKRST BIT(10)
+
+/* RCC_MP_APB1ENSETR register fields */
+#define RCC_MP_APB1ENSETR_TIM2EN BIT(0)
+#define RCC_MP_APB1ENSETR_TIM3EN BIT(1)
+#define RCC_MP_APB1ENSETR_TIM4EN BIT(2)
+#define RCC_MP_APB1ENSETR_TIM5EN BIT(3)
+#define RCC_MP_APB1ENSETR_TIM6EN BIT(4)
+#define RCC_MP_APB1ENSETR_TIM7EN BIT(5)
+#define RCC_MP_APB1ENSETR_TIM12EN BIT(6)
+#define RCC_MP_APB1ENSETR_TIM13EN BIT(7)
+#define RCC_MP_APB1ENSETR_TIM14EN BIT(8)
+#define RCC_MP_APB1ENSETR_LPTIM1EN BIT(9)
+#define RCC_MP_APB1ENSETR_SPI2EN BIT(11)
+#define RCC_MP_APB1ENSETR_SPI3EN BIT(12)
+#define RCC_MP_APB1ENSETR_USART2EN BIT(14)
+#define RCC_MP_APB1ENSETR_USART3EN BIT(15)
+#define RCC_MP_APB1ENSETR_UART4EN BIT(16)
+#define RCC_MP_APB1ENSETR_UART5EN BIT(17)
+#define RCC_MP_APB1ENSETR_UART7EN BIT(18)
+#define RCC_MP_APB1ENSETR_UART8EN BIT(19)
+#define RCC_MP_APB1ENSETR_I2C1EN BIT(21)
+#define RCC_MP_APB1ENSETR_I2C2EN BIT(22)
+#define RCC_MP_APB1ENSETR_I2C3EN BIT(23)
+#define RCC_MP_APB1ENSETR_I2C5EN BIT(24)
+#define RCC_MP_APB1ENSETR_SPDIFEN BIT(26)
+#define RCC_MP_APB1ENSETR_CECEN BIT(27)
+#define RCC_MP_APB1ENSETR_DAC12EN BIT(29)
+#define RCC_MP_APB1ENSETR_MDIOSEN BIT(31)
+
+/* RCC_MP_APB1ENCLRR register fields */
+#define RCC_MP_APB1ENCLRR_TIM2EN BIT(0)
+#define RCC_MP_APB1ENCLRR_TIM3EN BIT(1)
+#define RCC_MP_APB1ENCLRR_TIM4EN BIT(2)
+#define RCC_MP_APB1ENCLRR_TIM5EN BIT(3)
+#define RCC_MP_APB1ENCLRR_TIM6EN BIT(4)
+#define RCC_MP_APB1ENCLRR_TIM7EN BIT(5)
+#define RCC_MP_APB1ENCLRR_TIM12EN BIT(6)
+#define RCC_MP_APB1ENCLRR_TIM13EN BIT(7)
+#define RCC_MP_APB1ENCLRR_TIM14EN BIT(8)
+#define RCC_MP_APB1ENCLRR_LPTIM1EN BIT(9)
+#define RCC_MP_APB1ENCLRR_SPI2EN BIT(11)
+#define RCC_MP_APB1ENCLRR_SPI3EN BIT(12)
+#define RCC_MP_APB1ENCLRR_USART2EN BIT(14)
+#define RCC_MP_APB1ENCLRR_USART3EN BIT(15)
+#define RCC_MP_APB1ENCLRR_UART4EN BIT(16)
+#define RCC_MP_APB1ENCLRR_UART5EN BIT(17)
+#define RCC_MP_APB1ENCLRR_UART7EN BIT(18)
+#define RCC_MP_APB1ENCLRR_UART8EN BIT(19)
+#define RCC_MP_APB1ENCLRR_I2C1EN BIT(21)
+#define RCC_MP_APB1ENCLRR_I2C2EN BIT(22)
+#define RCC_MP_APB1ENCLRR_I2C3EN BIT(23)
+#define RCC_MP_APB1ENCLRR_I2C5EN BIT(24)
+#define RCC_MP_APB1ENCLRR_SPDIFEN BIT(26)
+#define RCC_MP_APB1ENCLRR_CECEN BIT(27)
+#define RCC_MP_APB1ENCLRR_DAC12EN BIT(29)
+#define RCC_MP_APB1ENCLRR_MDIOSEN BIT(31)
+
+/* RCC_MP_APB2ENSETR register fields */
+#define RCC_MP_APB2ENSETR_TIM1EN BIT(0)
+#define RCC_MP_APB2ENSETR_TIM8EN BIT(1)
+#define RCC_MP_APB2ENSETR_TIM15EN BIT(2)
+#define RCC_MP_APB2ENSETR_TIM16EN BIT(3)
+#define RCC_MP_APB2ENSETR_TIM17EN BIT(4)
+#define RCC_MP_APB2ENSETR_SPI1EN BIT(8)
+#define RCC_MP_APB2ENSETR_SPI4EN BIT(9)
+#define RCC_MP_APB2ENSETR_SPI5EN BIT(10)
+#define RCC_MP_APB2ENSETR_USART6EN BIT(13)
+#define RCC_MP_APB2ENSETR_SAI1EN BIT(16)
+#define RCC_MP_APB2ENSETR_SAI2EN BIT(17)
+#define RCC_MP_APB2ENSETR_SAI3EN BIT(18)
+#define RCC_MP_APB2ENSETR_DFSDMEN BIT(20)
+#define RCC_MP_APB2ENSETR_ADFSDMEN BIT(21)
+#define RCC_MP_APB2ENSETR_FDCANEN BIT(24)
+
+/* RCC_MP_APB2ENCLRR register fields */
+#define RCC_MP_APB2ENCLRR_TIM1EN BIT(0)
+#define RCC_MP_APB2ENCLRR_TIM8EN BIT(1)
+#define RCC_MP_APB2ENCLRR_TIM15EN BIT(2)
+#define RCC_MP_APB2ENCLRR_TIM16EN BIT(3)
+#define RCC_MP_APB2ENCLRR_TIM17EN BIT(4)
+#define RCC_MP_APB2ENCLRR_SPI1EN BIT(8)
+#define RCC_MP_APB2ENCLRR_SPI4EN BIT(9)
+#define RCC_MP_APB2ENCLRR_SPI5EN BIT(10)
+#define RCC_MP_APB2ENCLRR_USART6EN BIT(13)
+#define RCC_MP_APB2ENCLRR_SAI1EN BIT(16)
+#define RCC_MP_APB2ENCLRR_SAI2EN BIT(17)
+#define RCC_MP_APB2ENCLRR_SAI3EN BIT(18)
+#define RCC_MP_APB2ENCLRR_DFSDMEN BIT(20)
+#define RCC_MP_APB2ENCLRR_ADFSDMEN BIT(21)
+#define RCC_MP_APB2ENCLRR_FDCANEN BIT(24)
+
+/* RCC_MP_APB3ENSETR register fields */
+#define RCC_MP_APB3ENSETR_LPTIM2EN BIT(0)
+#define RCC_MP_APB3ENSETR_LPTIM3EN BIT(1)
+#define RCC_MP_APB3ENSETR_LPTIM4EN BIT(2)
+#define RCC_MP_APB3ENSETR_LPTIM5EN BIT(3)
+#define RCC_MP_APB3ENSETR_SAI4EN BIT(8)
+#define RCC_MP_APB3ENSETR_SYSCFGEN BIT(11)
+#define RCC_MP_APB3ENSETR_VREFEN BIT(13)
+#define RCC_MP_APB3ENSETR_TMPSENSEN BIT(16)
+#define RCC_MP_APB3ENSETR_PMBCTRLEN BIT(17)
+#define RCC_MP_APB3ENSETR_HDPEN BIT(20)
+
+/* RCC_MP_APB3ENCLRR register fields */
+#define RCC_MP_APB3ENCLRR_LPTIM2EN BIT(0)
+#define RCC_MP_APB3ENCLRR_LPTIM3EN BIT(1)
+#define RCC_MP_APB3ENCLRR_LPTIM4EN BIT(2)
+#define RCC_MP_APB3ENCLRR_LPTIM5EN BIT(3)
+#define RCC_MP_APB3ENCLRR_SAI4EN BIT(8)
+#define RCC_MP_APB3ENCLRR_SYSCFGEN BIT(11)
+#define RCC_MP_APB3ENCLRR_VREFEN BIT(13)
+#define RCC_MP_APB3ENCLRR_TMPSENSEN BIT(16)
+#define RCC_MP_APB3ENCLRR_PMBCTRLEN BIT(17)
+#define RCC_MP_APB3ENCLRR_HDPEN BIT(20)
+
+/* RCC_MP_AHB2ENSETR register fields */
+#define RCC_MP_AHB2ENSETR_DMA1EN BIT(0)
+#define RCC_MP_AHB2ENSETR_DMA2EN BIT(1)
+#define RCC_MP_AHB2ENSETR_DMAMUXEN BIT(2)
+#define RCC_MP_AHB2ENSETR_ADC12EN BIT(5)
+#define RCC_MP_AHB2ENSETR_USBOEN BIT(8)
+#define RCC_MP_AHB2ENSETR_SDMMC3EN BIT(16)
+
+/* RCC_MP_AHB2ENCLRR register fields */
+#define RCC_MP_AHB2ENCLRR_DMA1EN BIT(0)
+#define RCC_MP_AHB2ENCLRR_DMA2EN BIT(1)
+#define RCC_MP_AHB2ENCLRR_DMAMUXEN BIT(2)
+#define RCC_MP_AHB2ENCLRR_ADC12EN BIT(5)
+#define RCC_MP_AHB2ENCLRR_USBOEN BIT(8)
+#define RCC_MP_AHB2ENCLRR_SDMMC3EN BIT(16)
+
+/* RCC_MP_AHB3ENSETR register fields */
+#define RCC_MP_AHB3ENSETR_DCMIEN BIT(0)
+#define RCC_MP_AHB3ENSETR_CRYP2EN BIT(4)
+#define RCC_MP_AHB3ENSETR_HASH2EN BIT(5)
+#define RCC_MP_AHB3ENSETR_RNG2EN BIT(6)
+#define RCC_MP_AHB3ENSETR_CRC2EN BIT(7)
+#define RCC_MP_AHB3ENSETR_HSEMEN BIT(11)
+#define RCC_MP_AHB3ENSETR_IPCCEN BIT(12)
+
+/* RCC_MP_AHB3ENCLRR register fields */
+#define RCC_MP_AHB3ENCLRR_DCMIEN BIT(0)
+#define RCC_MP_AHB3ENCLRR_CRYP2EN BIT(4)
+#define RCC_MP_AHB3ENCLRR_HASH2EN BIT(5)
+#define RCC_MP_AHB3ENCLRR_RNG2EN BIT(6)
+#define RCC_MP_AHB3ENCLRR_CRC2EN BIT(7)
+#define RCC_MP_AHB3ENCLRR_HSEMEN BIT(11)
+#define RCC_MP_AHB3ENCLRR_IPCCEN BIT(12)
+
+/* RCC_MP_AHB4ENSETR register fields */
+#define RCC_MP_AHB4ENSETR_GPIOAEN BIT(0)
+#define RCC_MP_AHB4ENSETR_GPIOBEN BIT(1)
+#define RCC_MP_AHB4ENSETR_GPIOCEN BIT(2)
+#define RCC_MP_AHB4ENSETR_GPIODEN BIT(3)
+#define RCC_MP_AHB4ENSETR_GPIOEEN BIT(4)
+#define RCC_MP_AHB4ENSETR_GPIOFEN BIT(5)
+#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6)
+#define RCC_MP_AHB4ENSETR_GPIOHEN BIT(7)
+#define RCC_MP_AHB4ENSETR_GPIOIEN BIT(8)
+#define RCC_MP_AHB4ENSETR_GPIOJEN BIT(9)
+#define RCC_MP_AHB4ENSETR_GPIOKEN BIT(10)
+
+/* RCC_MP_AHB4ENCLRR register fields */
+#define RCC_MP_AHB4ENCLRR_GPIOAEN BIT(0)
+#define RCC_MP_AHB4ENCLRR_GPIOBEN BIT(1)
+#define RCC_MP_AHB4ENCLRR_GPIOCEN BIT(2)
+#define RCC_MP_AHB4ENCLRR_GPIODEN BIT(3)
+#define RCC_MP_AHB4ENCLRR_GPIOEEN BIT(4)
+#define RCC_MP_AHB4ENCLRR_GPIOFEN BIT(5)
+#define RCC_MP_AHB4ENCLRR_GPIOGEN BIT(6)
+#define RCC_MP_AHB4ENCLRR_GPIOHEN BIT(7)
+#define RCC_MP_AHB4ENCLRR_GPIOIEN BIT(8)
+#define RCC_MP_AHB4ENCLRR_GPIOJEN BIT(9)
+#define RCC_MP_AHB4ENCLRR_GPIOKEN BIT(10)
+
+/* RCC_MP_MLAHBENSETR register fields */
+#define RCC_MP_MLAHBENSETR_RETRAMEN BIT(4)
+
+/* RCC_MP_MLAHBENCLRR register fields */
+#define RCC_MP_MLAHBENCLRR_RETRAMEN BIT(4)
+
+/* RCC_MC_APB1ENSETR register fields */
+#define RCC_MC_APB1ENSETR_TIM2EN BIT(0)
+#define RCC_MC_APB1ENSETR_TIM3EN BIT(1)
+#define RCC_MC_APB1ENSETR_TIM4EN BIT(2)
+#define RCC_MC_APB1ENSETR_TIM5EN BIT(3)
+#define RCC_MC_APB1ENSETR_TIM6EN BIT(4)
+#define RCC_MC_APB1ENSETR_TIM7EN BIT(5)
+#define RCC_MC_APB1ENSETR_TIM12EN BIT(6)
+#define RCC_MC_APB1ENSETR_TIM13EN BIT(7)
+#define RCC_MC_APB1ENSETR_TIM14EN BIT(8)
+#define RCC_MC_APB1ENSETR_LPTIM1EN BIT(9)
+#define RCC_MC_APB1ENSETR_SPI2EN BIT(11)
+#define RCC_MC_APB1ENSETR_SPI3EN BIT(12)
+#define RCC_MC_APB1ENSETR_USART2EN BIT(14)
+#define RCC_MC_APB1ENSETR_USART3EN BIT(15)
+#define RCC_MC_APB1ENSETR_UART4EN BIT(16)
+#define RCC_MC_APB1ENSETR_UART5EN BIT(17)
+#define RCC_MC_APB1ENSETR_UART7EN BIT(18)
+#define RCC_MC_APB1ENSETR_UART8EN BIT(19)
+#define RCC_MC_APB1ENSETR_I2C1EN BIT(21)
+#define RCC_MC_APB1ENSETR_I2C2EN BIT(22)
+#define RCC_MC_APB1ENSETR_I2C3EN BIT(23)
+#define RCC_MC_APB1ENSETR_I2C5EN BIT(24)
+#define RCC_MC_APB1ENSETR_SPDIFEN BIT(26)
+#define RCC_MC_APB1ENSETR_CECEN BIT(27)
+#define RCC_MC_APB1ENSETR_WWDG1EN BIT(28)
+#define RCC_MC_APB1ENSETR_DAC12EN BIT(29)
+#define RCC_MC_APB1ENSETR_MDIOSEN BIT(31)
+
+/* RCC_MC_APB1ENCLRR register fields */
+#define RCC_MC_APB1ENCLRR_TIM2EN BIT(0)
+#define RCC_MC_APB1ENCLRR_TIM3EN BIT(1)
+#define RCC_MC_APB1ENCLRR_TIM4EN BIT(2)
+#define RCC_MC_APB1ENCLRR_TIM5EN BIT(3)
+#define RCC_MC_APB1ENCLRR_TIM6EN BIT(4)
+#define RCC_MC_APB1ENCLRR_TIM7EN BIT(5)
+#define RCC_MC_APB1ENCLRR_TIM12EN BIT(6)
+#define RCC_MC_APB1ENCLRR_TIM13EN BIT(7)
+#define RCC_MC_APB1ENCLRR_TIM14EN BIT(8)
+#define RCC_MC_APB1ENCLRR_LPTIM1EN BIT(9)
+#define RCC_MC_APB1ENCLRR_SPI2EN BIT(11)
+#define RCC_MC_APB1ENCLRR_SPI3EN BIT(12)
+#define RCC_MC_APB1ENCLRR_USART2EN BIT(14)
+#define RCC_MC_APB1ENCLRR_USART3EN BIT(15)
+#define RCC_MC_APB1ENCLRR_UART4EN BIT(16)
+#define RCC_MC_APB1ENCLRR_UART5EN BIT(17)
+#define RCC_MC_APB1ENCLRR_UART7EN BIT(18)
+#define RCC_MC_APB1ENCLRR_UART8EN BIT(19)
+#define RCC_MC_APB1ENCLRR_I2C1EN BIT(21)
+#define RCC_MC_APB1ENCLRR_I2C2EN BIT(22)
+#define RCC_MC_APB1ENCLRR_I2C3EN BIT(23)
+#define RCC_MC_APB1ENCLRR_I2C5EN BIT(24)
+#define RCC_MC_APB1ENCLRR_SPDIFEN BIT(26)
+#define RCC_MC_APB1ENCLRR_CECEN BIT(27)
+#define RCC_MC_APB1ENCLRR_DAC12EN BIT(29)
+#define RCC_MC_APB1ENCLRR_MDIOSEN BIT(31)
+
+/* RCC_MC_APB2ENSETR register fields */
+#define RCC_MC_APB2ENSETR_TIM1EN BIT(0)
+#define RCC_MC_APB2ENSETR_TIM8EN BIT(1)
+#define RCC_MC_APB2ENSETR_TIM15EN BIT(2)
+#define RCC_MC_APB2ENSETR_TIM16EN BIT(3)
+#define RCC_MC_APB2ENSETR_TIM17EN BIT(4)
+#define RCC_MC_APB2ENSETR_SPI1EN BIT(8)
+#define RCC_MC_APB2ENSETR_SPI4EN BIT(9)
+#define RCC_MC_APB2ENSETR_SPI5EN BIT(10)
+#define RCC_MC_APB2ENSETR_USART6EN BIT(13)
+#define RCC_MC_APB2ENSETR_SAI1EN BIT(16)
+#define RCC_MC_APB2ENSETR_SAI2EN BIT(17)
+#define RCC_MC_APB2ENSETR_SAI3EN BIT(18)
+#define RCC_MC_APB2ENSETR_DFSDMEN BIT(20)
+#define RCC_MC_APB2ENSETR_ADFSDMEN BIT(21)
+#define RCC_MC_APB2ENSETR_FDCANEN BIT(24)
+
+/* RCC_MC_APB2ENCLRR register fields */
+#define RCC_MC_APB2ENCLRR_TIM1EN BIT(0)
+#define RCC_MC_APB2ENCLRR_TIM8EN BIT(1)
+#define RCC_MC_APB2ENCLRR_TIM15EN BIT(2)
+#define RCC_MC_APB2ENCLRR_TIM16EN BIT(3)
+#define RCC_MC_APB2ENCLRR_TIM17EN BIT(4)
+#define RCC_MC_APB2ENCLRR_SPI1EN BIT(8)
+#define RCC_MC_APB2ENCLRR_SPI4EN BIT(9)
+#define RCC_MC_APB2ENCLRR_SPI5EN BIT(10)
+#define RCC_MC_APB2ENCLRR_USART6EN BIT(13)
+#define RCC_MC_APB2ENCLRR_SAI1EN BIT(16)
+#define RCC_MC_APB2ENCLRR_SAI2EN BIT(17)
+#define RCC_MC_APB2ENCLRR_SAI3EN BIT(18)
+#define RCC_MC_APB2ENCLRR_DFSDMEN BIT(20)
+#define RCC_MC_APB2ENCLRR_ADFSDMEN BIT(21)
+#define RCC_MC_APB2ENCLRR_FDCANEN BIT(24)
+
+/* RCC_MC_APB3ENSETR register fields */
+#define RCC_MC_APB3ENSETR_LPTIM2EN BIT(0)
+#define RCC_MC_APB3ENSETR_LPTIM3EN BIT(1)
+#define RCC_MC_APB3ENSETR_LPTIM4EN BIT(2)
+#define RCC_MC_APB3ENSETR_LPTIM5EN BIT(3)
+#define RCC_MC_APB3ENSETR_SAI4EN BIT(8)
+#define RCC_MC_APB3ENSETR_SYSCFGEN BIT(11)
+#define RCC_MC_APB3ENSETR_VREFEN BIT(13)
+#define RCC_MC_APB3ENSETR_TMPSENSEN BIT(16)
+#define RCC_MC_APB3ENSETR_PMBCTRLEN BIT(17)
+#define RCC_MC_APB3ENSETR_HDPEN BIT(20)
+
+/* RCC_MC_APB3ENCLRR register fields */
+#define RCC_MC_APB3ENCLRR_LPTIM2EN BIT(0)
+#define RCC_MC_APB3ENCLRR_LPTIM3EN BIT(1)
+#define RCC_MC_APB3ENCLRR_LPTIM4EN BIT(2)
+#define RCC_MC_APB3ENCLRR_LPTIM5EN BIT(3)
+#define RCC_MC_APB3ENCLRR_SAI4EN BIT(8)
+#define RCC_MC_APB3ENCLRR_SYSCFGEN BIT(11)
+#define RCC_MC_APB3ENCLRR_VREFEN BIT(13)
+#define RCC_MC_APB3ENCLRR_TMPSENSEN BIT(16)
+#define RCC_MC_APB3ENCLRR_PMBCTRLEN BIT(17)
+#define RCC_MC_APB3ENCLRR_HDPEN BIT(20)
+
+/* RCC_MC_AHB2ENSETR register fields */
+#define RCC_MC_AHB2ENSETR_DMA1EN BIT(0)
+#define RCC_MC_AHB2ENSETR_DMA2EN BIT(1)
+#define RCC_MC_AHB2ENSETR_DMAMUXEN BIT(2)
+#define RCC_MC_AHB2ENSETR_ADC12EN BIT(5)
+#define RCC_MC_AHB2ENSETR_USBOEN BIT(8)
+#define RCC_MC_AHB2ENSETR_SDMMC3EN BIT(16)
+
+/* RCC_MC_AHB2ENCLRR register fields */
+#define RCC_MC_AHB2ENCLRR_DMA1EN BIT(0)
+#define RCC_MC_AHB2ENCLRR_DMA2EN BIT(1)
+#define RCC_MC_AHB2ENCLRR_DMAMUXEN BIT(2)
+#define RCC_MC_AHB2ENCLRR_ADC12EN BIT(5)
+#define RCC_MC_AHB2ENCLRR_USBOEN BIT(8)
+#define RCC_MC_AHB2ENCLRR_SDMMC3EN BIT(16)
+
+/* RCC_MC_AHB3ENSETR register fields */
+#define RCC_MC_AHB3ENSETR_DCMIEN BIT(0)
+#define RCC_MC_AHB3ENSETR_CRYP2EN BIT(4)
+#define RCC_MC_AHB3ENSETR_HASH2EN BIT(5)
+#define RCC_MC_AHB3ENSETR_RNG2EN BIT(6)
+#define RCC_MC_AHB3ENSETR_CRC2EN BIT(7)
+#define RCC_MC_AHB3ENSETR_HSEMEN BIT(11)
+#define RCC_MC_AHB3ENSETR_IPCCEN BIT(12)
+
+/* RCC_MC_AHB3ENCLRR register fields */
+#define RCC_MC_AHB3ENCLRR_DCMIEN BIT(0)
+#define RCC_MC_AHB3ENCLRR_CRYP2EN BIT(4)
+#define RCC_MC_AHB3ENCLRR_HASH2EN BIT(5)
+#define RCC_MC_AHB3ENCLRR_RNG2EN BIT(6)
+#define RCC_MC_AHB3ENCLRR_CRC2EN BIT(7)
+#define RCC_MC_AHB3ENCLRR_HSEMEN BIT(11)
+#define RCC_MC_AHB3ENCLRR_IPCCEN BIT(12)
+
+/* RCC_MC_AHB4ENSETR register fields */
+#define RCC_MC_AHB4ENSETR_GPIOAEN BIT(0)
+#define RCC_MC_AHB4ENSETR_GPIOBEN BIT(1)
+#define RCC_MC_AHB4ENSETR_GPIOCEN BIT(2)
+#define RCC_MC_AHB4ENSETR_GPIODEN BIT(3)
+#define RCC_MC_AHB4ENSETR_GPIOEEN BIT(4)
+#define RCC_MC_AHB4ENSETR_GPIOFEN BIT(5)
+#define RCC_MC_AHB4ENSETR_GPIOGEN BIT(6)
+#define RCC_MC_AHB4ENSETR_GPIOHEN BIT(7)
+#define RCC_MC_AHB4ENSETR_GPIOIEN BIT(8)
+#define RCC_MC_AHB4ENSETR_GPIOJEN BIT(9)
+#define RCC_MC_AHB4ENSETR_GPIOKEN BIT(10)
+
+/* RCC_MC_AHB4ENCLRR register fields */
+#define RCC_MC_AHB4ENCLRR_GPIOAEN BIT(0)
+#define RCC_MC_AHB4ENCLRR_GPIOBEN BIT(1)
+#define RCC_MC_AHB4ENCLRR_GPIOCEN BIT(2)
+#define RCC_MC_AHB4ENCLRR_GPIODEN BIT(3)
+#define RCC_MC_AHB4ENCLRR_GPIOEEN BIT(4)
+#define RCC_MC_AHB4ENCLRR_GPIOFEN BIT(5)
+#define RCC_MC_AHB4ENCLRR_GPIOGEN BIT(6)
+#define RCC_MC_AHB4ENCLRR_GPIOHEN BIT(7)
+#define RCC_MC_AHB4ENCLRR_GPIOIEN BIT(8)
+#define RCC_MC_AHB4ENCLRR_GPIOJEN BIT(9)
+#define RCC_MC_AHB4ENCLRR_GPIOKEN BIT(10)
+
+/* RCC_MC_AXIMENSETR register fields */
+#define RCC_MC_AXIMENSETR_SYSRAMEN BIT(0)
+
+/* RCC_MC_AXIMENCLRR register fields */
+#define RCC_MC_AXIMENCLRR_SYSRAMEN BIT(0)
+
+/* RCC_MC_MLAHBENSETR register fields */
+#define RCC_MC_MLAHBENSETR_RETRAMEN BIT(4)
+
+/* RCC_MC_MLAHBENCLRR register fields */
+#define RCC_MC_MLAHBENCLRR_RETRAMEN BIT(4)
+
+/* RCC_MP_APB1LPENSETR register fields */
+#define RCC_MP_APB1LPENSETR_TIM2LPEN BIT(0)
+#define RCC_MP_APB1LPENSETR_TIM3LPEN BIT(1)
+#define RCC_MP_APB1LPENSETR_TIM4LPEN BIT(2)
+#define RCC_MP_APB1LPENSETR_TIM5LPEN BIT(3)
+#define RCC_MP_APB1LPENSETR_TIM6LPEN BIT(4)
+#define RCC_MP_APB1LPENSETR_TIM7LPEN BIT(5)
+#define RCC_MP_APB1LPENSETR_TIM12LPEN BIT(6)
+#define RCC_MP_APB1LPENSETR_TIM13LPEN BIT(7)
+#define RCC_MP_APB1LPENSETR_TIM14LPEN BIT(8)
+#define RCC_MP_APB1LPENSETR_LPTIM1LPEN BIT(9)
+#define RCC_MP_APB1LPENSETR_SPI2LPEN BIT(11)
+#define RCC_MP_APB1LPENSETR_SPI3LPEN BIT(12)
+#define RCC_MP_APB1LPENSETR_USART2LPEN BIT(14)
+#define RCC_MP_APB1LPENSETR_USART3LPEN BIT(15)
+#define RCC_MP_APB1LPENSETR_UART4LPEN BIT(16)
+#define RCC_MP_APB1LPENSETR_UART5LPEN BIT(17)
+#define RCC_MP_APB1LPENSETR_UART7LPEN BIT(18)
+#define RCC_MP_APB1LPENSETR_UART8LPEN BIT(19)
+#define RCC_MP_APB1LPENSETR_I2C1LPEN BIT(21)
+#define RCC_MP_APB1LPENSETR_I2C2LPEN BIT(22)
+#define RCC_MP_APB1LPENSETR_I2C3LPEN BIT(23)
+#define RCC_MP_APB1LPENSETR_I2C5LPEN BIT(24)
+#define RCC_MP_APB1LPENSETR_SPDIFLPEN BIT(26)
+#define RCC_MP_APB1LPENSETR_CECLPEN BIT(27)
+#define RCC_MP_APB1LPENSETR_DAC12LPEN BIT(29)
+#define RCC_MP_APB1LPENSETR_MDIOSLPEN BIT(31)
+
+/* RCC_MP_APB1LPENCLRR register fields */
+#define RCC_MP_APB1LPENCLRR_TIM2LPEN BIT(0)
+#define RCC_MP_APB1LPENCLRR_TIM3LPEN BIT(1)
+#define RCC_MP_APB1LPENCLRR_TIM4LPEN BIT(2)
+#define RCC_MP_APB1LPENCLRR_TIM5LPEN BIT(3)
+#define RCC_MP_APB1LPENCLRR_TIM6LPEN BIT(4)
+#define RCC_MP_APB1LPENCLRR_TIM7LPEN BIT(5)
+#define RCC_MP_APB1LPENCLRR_TIM12LPEN BIT(6)
+#define RCC_MP_APB1LPENCLRR_TIM13LPEN BIT(7)
+#define RCC_MP_APB1LPENCLRR_TIM14LPEN BIT(8)
+#define RCC_MP_APB1LPENCLRR_LPTIM1LPEN BIT(9)
+#define RCC_MP_APB1LPENCLRR_SPI2LPEN BIT(11)
+#define RCC_MP_APB1LPENCLRR_SPI3LPEN BIT(12)
+#define RCC_MP_APB1LPENCLRR_USART2LPEN BIT(14)
+#define RCC_MP_APB1LPENCLRR_USART3LPEN BIT(15)
+#define RCC_MP_APB1LPENCLRR_UART4LPEN BIT(16)
+#define RCC_MP_APB1LPENCLRR_UART5LPEN BIT(17)
+#define RCC_MP_APB1LPENCLRR_UART7LPEN BIT(18)
+#define RCC_MP_APB1LPENCLRR_UART8LPEN BIT(19)
+#define RCC_MP_APB1LPENCLRR_I2C1LPEN BIT(21)
+#define RCC_MP_APB1LPENCLRR_I2C2LPEN BIT(22)
+#define RCC_MP_APB1LPENCLRR_I2C3LPEN BIT(23)
+#define RCC_MP_APB1LPENCLRR_I2C5LPEN BIT(24)
+#define RCC_MP_APB1LPENCLRR_SPDIFLPEN BIT(26)
+#define RCC_MP_APB1LPENCLRR_CECLPEN BIT(27)
+#define RCC_MP_APB1LPENCLRR_DAC12LPEN BIT(29)
+#define RCC_MP_APB1LPENCLRR_MDIOSLPEN BIT(31)
+
+/* RCC_MP_APB2LPENSETR register fields */
+#define RCC_MP_APB2LPENSETR_TIM1LPEN BIT(0)
+#define RCC_MP_APB2LPENSETR_TIM8LPEN BIT(1)
+#define RCC_MP_APB2LPENSETR_TIM15LPEN BIT(2)
+#define RCC_MP_APB2LPENSETR_TIM16LPEN BIT(3)
+#define RCC_MP_APB2LPENSETR_TIM17LPEN BIT(4)
+#define RCC_MP_APB2LPENSETR_SPI1LPEN BIT(8)
+#define RCC_MP_APB2LPENSETR_SPI4LPEN BIT(9)
+#define RCC_MP_APB2LPENSETR_SPI5LPEN BIT(10)
+#define RCC_MP_APB2LPENSETR_USART6LPEN BIT(13)
+#define RCC_MP_APB2LPENSETR_SAI1LPEN BIT(16)
+#define RCC_MP_APB2LPENSETR_SAI2LPEN BIT(17)
+#define RCC_MP_APB2LPENSETR_SAI3LPEN BIT(18)
+#define RCC_MP_APB2LPENSETR_DFSDMLPEN BIT(20)
+#define RCC_MP_APB2LPENSETR_ADFSDMLPEN BIT(21)
+#define RCC_MP_APB2LPENSETR_FDCANLPEN BIT(24)
+
+/* RCC_MP_APB2LPENCLRR register fields */
+#define RCC_MP_APB2LPENCLRR_TIM1LPEN BIT(0)
+#define RCC_MP_APB2LPENCLRR_TIM8LPEN BIT(1)
+#define RCC_MP_APB2LPENCLRR_TIM15LPEN BIT(2)
+#define RCC_MP_APB2LPENCLRR_TIM16LPEN BIT(3)
+#define RCC_MP_APB2LPENCLRR_TIM17LPEN BIT(4)
+#define RCC_MP_APB2LPENCLRR_SPI1LPEN BIT(8)
+#define RCC_MP_APB2LPENCLRR_SPI4LPEN BIT(9)
+#define RCC_MP_APB2LPENCLRR_SPI5LPEN BIT(10)
+#define RCC_MP_APB2LPENCLRR_USART6LPEN BIT(13)
+#define RCC_MP_APB2LPENCLRR_SAI1LPEN BIT(16)
+#define RCC_MP_APB2LPENCLRR_SAI2LPEN BIT(17)
+#define RCC_MP_APB2LPENCLRR_SAI3LPEN BIT(18)
+#define RCC_MP_APB2LPENCLRR_DFSDMLPEN BIT(20)
+#define RCC_MP_APB2LPENCLRR_ADFSDMLPEN BIT(21)
+#define RCC_MP_APB2LPENCLRR_FDCANLPEN BIT(24)
+
+/* RCC_MP_APB3LPENSETR register fields */
+#define RCC_MP_APB3LPENSETR_LPTIM2LPEN BIT(0)
+#define RCC_MP_APB3LPENSETR_LPTIM3LPEN BIT(1)
+#define RCC_MP_APB3LPENSETR_LPTIM4LPEN BIT(2)
+#define RCC_MP_APB3LPENSETR_LPTIM5LPEN BIT(3)
+#define RCC_MP_APB3LPENSETR_SAI4LPEN BIT(8)
+#define RCC_MP_APB3LPENSETR_SYSCFGLPEN BIT(11)
+#define RCC_MP_APB3LPENSETR_VREFLPEN BIT(13)
+#define RCC_MP_APB3LPENSETR_TMPSENSLPEN BIT(16)
+#define RCC_MP_APB3LPENSETR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MP_APB3LPENCLRR register fields */
+#define RCC_MP_APB3LPENCLRR_LPTIM2LPEN BIT(0)
+#define RCC_MP_APB3LPENCLRR_LPTIM3LPEN BIT(1)
+#define RCC_MP_APB3LPENCLRR_LPTIM4LPEN BIT(2)
+#define RCC_MP_APB3LPENCLRR_LPTIM5LPEN BIT(3)
+#define RCC_MP_APB3LPENCLRR_SAI4LPEN BIT(8)
+#define RCC_MP_APB3LPENCLRR_SYSCFGLPEN BIT(11)
+#define RCC_MP_APB3LPENCLRR_VREFLPEN BIT(13)
+#define RCC_MP_APB3LPENCLRR_TMPSENSLPEN BIT(16)
+#define RCC_MP_APB3LPENCLRR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MP_AHB2LPENSETR register fields */
+#define RCC_MP_AHB2LPENSETR_DMA1LPEN BIT(0)
+#define RCC_MP_AHB2LPENSETR_DMA2LPEN BIT(1)
+#define RCC_MP_AHB2LPENSETR_DMAMUXLPEN BIT(2)
+#define RCC_MP_AHB2LPENSETR_ADC12LPEN BIT(5)
+#define RCC_MP_AHB2LPENSETR_USBOLPEN BIT(8)
+#define RCC_MP_AHB2LPENSETR_SDMMC3LPEN BIT(16)
+
+/* RCC_MP_AHB2LPENCLRR register fields */
+#define RCC_MP_AHB2LPENCLRR_DMA1LPEN BIT(0)
+#define RCC_MP_AHB2LPENCLRR_DMA2LPEN BIT(1)
+#define RCC_MP_AHB2LPENCLRR_DMAMUXLPEN BIT(2)
+#define RCC_MP_AHB2LPENCLRR_ADC12LPEN BIT(5)
+#define RCC_MP_AHB2LPENCLRR_USBOLPEN BIT(8)
+#define RCC_MP_AHB2LPENCLRR_SDMMC3LPEN BIT(16)
+
+/* RCC_MP_AHB3LPENSETR register fields */
+#define RCC_MP_AHB3LPENSETR_DCMILPEN BIT(0)
+#define RCC_MP_AHB3LPENSETR_CRYP2LPEN BIT(4)
+#define RCC_MP_AHB3LPENSETR_HASH2LPEN BIT(5)
+#define RCC_MP_AHB3LPENSETR_RNG2LPEN BIT(6)
+#define RCC_MP_AHB3LPENSETR_CRC2LPEN BIT(7)
+#define RCC_MP_AHB3LPENSETR_HSEMLPEN BIT(11)
+#define RCC_MP_AHB3LPENSETR_IPCCLPEN BIT(12)
+
+/* RCC_MP_AHB3LPENCLRR register fields */
+#define RCC_MP_AHB3LPENCLRR_DCMILPEN BIT(0)
+#define RCC_MP_AHB3LPENCLRR_CRYP2LPEN BIT(4)
+#define RCC_MP_AHB3LPENCLRR_HASH2LPEN BIT(5)
+#define RCC_MP_AHB3LPENCLRR_RNG2LPEN BIT(6)
+#define RCC_MP_AHB3LPENCLRR_CRC2LPEN BIT(7)
+#define RCC_MP_AHB3LPENCLRR_HSEMLPEN BIT(11)
+#define RCC_MP_AHB3LPENCLRR_IPCCLPEN BIT(12)
+
+/* RCC_MP_AHB4LPENSETR register fields */
+#define RCC_MP_AHB4LPENSETR_GPIOALPEN BIT(0)
+#define RCC_MP_AHB4LPENSETR_GPIOBLPEN BIT(1)
+#define RCC_MP_AHB4LPENSETR_GPIOCLPEN BIT(2)
+#define RCC_MP_AHB4LPENSETR_GPIODLPEN BIT(3)
+#define RCC_MP_AHB4LPENSETR_GPIOELPEN BIT(4)
+#define RCC_MP_AHB4LPENSETR_GPIOFLPEN BIT(5)
+#define RCC_MP_AHB4LPENSETR_GPIOGLPEN BIT(6)
+#define RCC_MP_AHB4LPENSETR_GPIOHLPEN BIT(7)
+#define RCC_MP_AHB4LPENSETR_GPIOILPEN BIT(8)
+#define RCC_MP_AHB4LPENSETR_GPIOJLPEN BIT(9)
+#define RCC_MP_AHB4LPENSETR_GPIOKLPEN BIT(10)
+
+/* RCC_MP_AHB4LPENCLRR register fields */
+#define RCC_MP_AHB4LPENCLRR_GPIOALPEN BIT(0)
+#define RCC_MP_AHB4LPENCLRR_GPIOBLPEN BIT(1)
+#define RCC_MP_AHB4LPENCLRR_GPIOCLPEN BIT(2)
+#define RCC_MP_AHB4LPENCLRR_GPIODLPEN BIT(3)
+#define RCC_MP_AHB4LPENCLRR_GPIOELPEN BIT(4)
+#define RCC_MP_AHB4LPENCLRR_GPIOFLPEN BIT(5)
+#define RCC_MP_AHB4LPENCLRR_GPIOGLPEN BIT(6)
+#define RCC_MP_AHB4LPENCLRR_GPIOHLPEN BIT(7)
+#define RCC_MP_AHB4LPENCLRR_GPIOILPEN BIT(8)
+#define RCC_MP_AHB4LPENCLRR_GPIOJLPEN BIT(9)
+#define RCC_MP_AHB4LPENCLRR_GPIOKLPEN BIT(10)
+
+/* RCC_MP_AXIMLPENSETR register fields */
+#define RCC_MP_AXIMLPENSETR_SYSRAMLPEN BIT(0)
+
+/* RCC_MP_AXIMLPENCLRR register fields */
+#define RCC_MP_AXIMLPENCLRR_SYSRAMLPEN BIT(0)
+
+/* RCC_MP_MLAHBLPENSETR register fields */
+#define RCC_MP_MLAHBLPENSETR_SRAM1LPEN BIT(0)
+#define RCC_MP_MLAHBLPENSETR_SRAM2LPEN BIT(1)
+#define RCC_MP_MLAHBLPENSETR_SRAM34LPEN BIT(2)
+#define RCC_MP_MLAHBLPENSETR_RETRAMLPEN BIT(4)
+
+/* RCC_MP_MLAHBLPENCLRR register fields */
+#define RCC_MP_MLAHBLPENCLRR_SRAM1LPEN BIT(0)
+#define RCC_MP_MLAHBLPENCLRR_SRAM2LPEN BIT(1)
+#define RCC_MP_MLAHBLPENCLRR_SRAM34LPEN BIT(2)
+#define RCC_MP_MLAHBLPENCLRR_RETRAMLPEN BIT(4)
+
+/* RCC_MC_APB1LPENSETR register fields */
+#define RCC_MC_APB1LPENSETR_TIM2LPEN BIT(0)
+#define RCC_MC_APB1LPENSETR_TIM3LPEN BIT(1)
+#define RCC_MC_APB1LPENSETR_TIM4LPEN BIT(2)
+#define RCC_MC_APB1LPENSETR_TIM5LPEN BIT(3)
+#define RCC_MC_APB1LPENSETR_TIM6LPEN BIT(4)
+#define RCC_MC_APB1LPENSETR_TIM7LPEN BIT(5)
+#define RCC_MC_APB1LPENSETR_TIM12LPEN BIT(6)
+#define RCC_MC_APB1LPENSETR_TIM13LPEN BIT(7)
+#define RCC_MC_APB1LPENSETR_TIM14LPEN BIT(8)
+#define RCC_MC_APB1LPENSETR_LPTIM1LPEN BIT(9)
+#define RCC_MC_APB1LPENSETR_SPI2LPEN BIT(11)
+#define RCC_MC_APB1LPENSETR_SPI3LPEN BIT(12)
+#define RCC_MC_APB1LPENSETR_USART2LPEN BIT(14)
+#define RCC_MC_APB1LPENSETR_USART3LPEN BIT(15)
+#define RCC_MC_APB1LPENSETR_UART4LPEN BIT(16)
+#define RCC_MC_APB1LPENSETR_UART5LPEN BIT(17)
+#define RCC_MC_APB1LPENSETR_UART7LPEN BIT(18)
+#define RCC_MC_APB1LPENSETR_UART8LPEN BIT(19)
+#define RCC_MC_APB1LPENSETR_I2C1LPEN BIT(21)
+#define RCC_MC_APB1LPENSETR_I2C2LPEN BIT(22)
+#define RCC_MC_APB1LPENSETR_I2C3LPEN BIT(23)
+#define RCC_MC_APB1LPENSETR_I2C5LPEN BIT(24)
+#define RCC_MC_APB1LPENSETR_SPDIFLPEN BIT(26)
+#define RCC_MC_APB1LPENSETR_CECLPEN BIT(27)
+#define RCC_MC_APB1LPENSETR_WWDG1LPEN BIT(28)
+#define RCC_MC_APB1LPENSETR_DAC12LPEN BIT(29)
+#define RCC_MC_APB1LPENSETR_MDIOSLPEN BIT(31)
+
+/* RCC_MC_APB1LPENCLRR register fields */
+#define RCC_MC_APB1LPENCLRR_TIM2LPEN BIT(0)
+#define RCC_MC_APB1LPENCLRR_TIM3LPEN BIT(1)
+#define RCC_MC_APB1LPENCLRR_TIM4LPEN BIT(2)
+#define RCC_MC_APB1LPENCLRR_TIM5LPEN BIT(3)
+#define RCC_MC_APB1LPENCLRR_TIM6LPEN BIT(4)
+#define RCC_MC_APB1LPENCLRR_TIM7LPEN BIT(5)
+#define RCC_MC_APB1LPENCLRR_TIM12LPEN BIT(6)
+#define RCC_MC_APB1LPENCLRR_TIM13LPEN BIT(7)
+#define RCC_MC_APB1LPENCLRR_TIM14LPEN BIT(8)
+#define RCC_MC_APB1LPENCLRR_LPTIM1LPEN BIT(9)
+#define RCC_MC_APB1LPENCLRR_SPI2LPEN BIT(11)
+#define RCC_MC_APB1LPENCLRR_SPI3LPEN BIT(12)
+#define RCC_MC_APB1LPENCLRR_USART2LPEN BIT(14)
+#define RCC_MC_APB1LPENCLRR_USART3LPEN BIT(15)
+#define RCC_MC_APB1LPENCLRR_UART4LPEN BIT(16)
+#define RCC_MC_APB1LPENCLRR_UART5LPEN BIT(17)
+#define RCC_MC_APB1LPENCLRR_UART7LPEN BIT(18)
+#define RCC_MC_APB1LPENCLRR_UART8LPEN BIT(19)
+#define RCC_MC_APB1LPENCLRR_I2C1LPEN BIT(21)
+#define RCC_MC_APB1LPENCLRR_I2C2LPEN BIT(22)
+#define RCC_MC_APB1LPENCLRR_I2C3LPEN BIT(23)
+#define RCC_MC_APB1LPENCLRR_I2C5LPEN BIT(24)
+#define RCC_MC_APB1LPENCLRR_SPDIFLPEN BIT(26)
+#define RCC_MC_APB1LPENCLRR_CECLPEN BIT(27)
+#define RCC_MC_APB1LPENCLRR_WWDG1LPEN BIT(28)
+#define RCC_MC_APB1LPENCLRR_DAC12LPEN BIT(29)
+#define RCC_MC_APB1LPENCLRR_MDIOSLPEN BIT(31)
+
+/* RCC_MC_APB2LPENSETR register fields */
+#define RCC_MC_APB2LPENSETR_TIM1LPEN BIT(0)
+#define RCC_MC_APB2LPENSETR_TIM8LPEN BIT(1)
+#define RCC_MC_APB2LPENSETR_TIM15LPEN BIT(2)
+#define RCC_MC_APB2LPENSETR_TIM16LPEN BIT(3)
+#define RCC_MC_APB2LPENSETR_TIM17LPEN BIT(4)
+#define RCC_MC_APB2LPENSETR_SPI1LPEN BIT(8)
+#define RCC_MC_APB2LPENSETR_SPI4LPEN BIT(9)
+#define RCC_MC_APB2LPENSETR_SPI5LPEN BIT(10)
+#define RCC_MC_APB2LPENSETR_USART6LPEN BIT(13)
+#define RCC_MC_APB2LPENSETR_SAI1LPEN BIT(16)
+#define RCC_MC_APB2LPENSETR_SAI2LPEN BIT(17)
+#define RCC_MC_APB2LPENSETR_SAI3LPEN BIT(18)
+#define RCC_MC_APB2LPENSETR_DFSDMLPEN BIT(20)
+#define RCC_MC_APB2LPENSETR_ADFSDMLPEN BIT(21)
+#define RCC_MC_APB2LPENSETR_FDCANLPEN BIT(24)
+
+/* RCC_MC_APB2LPENCLRR register fields */
+#define RCC_MC_APB2LPENCLRR_TIM1LPEN BIT(0)
+#define RCC_MC_APB2LPENCLRR_TIM8LPEN BIT(1)
+#define RCC_MC_APB2LPENCLRR_TIM15LPEN BIT(2)
+#define RCC_MC_APB2LPENCLRR_TIM16LPEN BIT(3)
+#define RCC_MC_APB2LPENCLRR_TIM17LPEN BIT(4)
+#define RCC_MC_APB2LPENCLRR_SPI1LPEN BIT(8)
+#define RCC_MC_APB2LPENCLRR_SPI4LPEN BIT(9)
+#define RCC_MC_APB2LPENCLRR_SPI5LPEN BIT(10)
+#define RCC_MC_APB2LPENCLRR_USART6LPEN BIT(13)
+#define RCC_MC_APB2LPENCLRR_SAI1LPEN BIT(16)
+#define RCC_MC_APB2LPENCLRR_SAI2LPEN BIT(17)
+#define RCC_MC_APB2LPENCLRR_SAI3LPEN BIT(18)
+#define RCC_MC_APB2LPENCLRR_DFSDMLPEN BIT(20)
+#define RCC_MC_APB2LPENCLRR_ADFSDMLPEN BIT(21)
+#define RCC_MC_APB2LPENCLRR_FDCANLPEN BIT(24)
+
+/* RCC_MC_APB3LPENSETR register fields */
+#define RCC_MC_APB3LPENSETR_LPTIM2LPEN BIT(0)
+#define RCC_MC_APB3LPENSETR_LPTIM3LPEN BIT(1)
+#define RCC_MC_APB3LPENSETR_LPTIM4LPEN BIT(2)
+#define RCC_MC_APB3LPENSETR_LPTIM5LPEN BIT(3)
+#define RCC_MC_APB3LPENSETR_SAI4LPEN BIT(8)
+#define RCC_MC_APB3LPENSETR_SYSCFGLPEN BIT(11)
+#define RCC_MC_APB3LPENSETR_VREFLPEN BIT(13)
+#define RCC_MC_APB3LPENSETR_TMPSENSLPEN BIT(16)
+#define RCC_MC_APB3LPENSETR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MC_APB3LPENCLRR register fields */
+#define RCC_MC_APB3LPENCLRR_LPTIM2LPEN BIT(0)
+#define RCC_MC_APB3LPENCLRR_LPTIM3LPEN BIT(1)
+#define RCC_MC_APB3LPENCLRR_LPTIM4LPEN BIT(2)
+#define RCC_MC_APB3LPENCLRR_LPTIM5LPEN BIT(3)
+#define RCC_MC_APB3LPENCLRR_SAI4LPEN BIT(8)
+#define RCC_MC_APB3LPENCLRR_SYSCFGLPEN BIT(11)
+#define RCC_MC_APB3LPENCLRR_VREFLPEN BIT(13)
+#define RCC_MC_APB3LPENCLRR_TMPSENSLPEN BIT(16)
+#define RCC_MC_APB3LPENCLRR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MC_AHB2LPENSETR register fields */
+#define RCC_MC_AHB2LPENSETR_DMA1LPEN BIT(0)
+#define RCC_MC_AHB2LPENSETR_DMA2LPEN BIT(1)
+#define RCC_MC_AHB2LPENSETR_DMAMUXLPEN BIT(2)
+#define RCC_MC_AHB2LPENSETR_ADC12LPEN BIT(5)
+#define RCC_MC_AHB2LPENSETR_USBOLPEN BIT(8)
+#define RCC_MC_AHB2LPENSETR_SDMMC3LPEN BIT(16)
+
+/* RCC_MC_AHB2LPENCLRR register fields */
+#define RCC_MC_AHB2LPENCLRR_DMA1LPEN BIT(0)
+#define RCC_MC_AHB2LPENCLRR_DMA2LPEN BIT(1)
+#define RCC_MC_AHB2LPENCLRR_DMAMUXLPEN BIT(2)
+#define RCC_MC_AHB2LPENCLRR_ADC12LPEN BIT(5)
+#define RCC_MC_AHB2LPENCLRR_USBOLPEN BIT(8)
+#define RCC_MC_AHB2LPENCLRR_SDMMC3LPEN BIT(16)
+
+/* RCC_MC_AHB3LPENSETR register fields */
+#define RCC_MC_AHB3LPENSETR_DCMILPEN BIT(0)
+#define RCC_MC_AHB3LPENSETR_CRYP2LPEN BIT(4)
+#define RCC_MC_AHB3LPENSETR_HASH2LPEN BIT(5)
+#define RCC_MC_AHB3LPENSETR_RNG2LPEN BIT(6)
+#define RCC_MC_AHB3LPENSETR_CRC2LPEN BIT(7)
+#define RCC_MC_AHB3LPENSETR_HSEMLPEN BIT(11)
+#define RCC_MC_AHB3LPENSETR_IPCCLPEN BIT(12)
+
+/* RCC_MC_AHB3LPENCLRR register fields */
+#define RCC_MC_AHB3LPENCLRR_DCMILPEN BIT(0)
+#define RCC_MC_AHB3LPENCLRR_CRYP2LPEN BIT(4)
+#define RCC_MC_AHB3LPENCLRR_HASH2LPEN BIT(5)
+#define RCC_MC_AHB3LPENCLRR_RNG2LPEN BIT(6)
+#define RCC_MC_AHB3LPENCLRR_CRC2LPEN BIT(7)
+#define RCC_MC_AHB3LPENCLRR_HSEMLPEN BIT(11)
+#define RCC_MC_AHB3LPENCLRR_IPCCLPEN BIT(12)
+
+/* RCC_MC_AHB4LPENSETR register fields */
+#define RCC_MC_AHB4LPENSETR_GPIOALPEN BIT(0)
+#define RCC_MC_AHB4LPENSETR_GPIOBLPEN BIT(1)
+#define RCC_MC_AHB4LPENSETR_GPIOCLPEN BIT(2)
+#define RCC_MC_AHB4LPENSETR_GPIODLPEN BIT(3)
+#define RCC_MC_AHB4LPENSETR_GPIOELPEN BIT(4)
+#define RCC_MC_AHB4LPENSETR_GPIOFLPEN BIT(5)
+#define RCC_MC_AHB4LPENSETR_GPIOGLPEN BIT(6)
+#define RCC_MC_AHB4LPENSETR_GPIOHLPEN BIT(7)
+#define RCC_MC_AHB4LPENSETR_GPIOILPEN BIT(8)
+#define RCC_MC_AHB4LPENSETR_GPIOJLPEN BIT(9)
+#define RCC_MC_AHB4LPENSETR_GPIOKLPEN BIT(10)
+
+/* RCC_MC_AHB4LPENCLRR register fields */
+#define RCC_MC_AHB4LPENCLRR_GPIOALPEN BIT(0)
+#define RCC_MC_AHB4LPENCLRR_GPIOBLPEN BIT(1)
+#define RCC_MC_AHB4LPENCLRR_GPIOCLPEN BIT(2)
+#define RCC_MC_AHB4LPENCLRR_GPIODLPEN BIT(3)
+#define RCC_MC_AHB4LPENCLRR_GPIOELPEN BIT(4)
+#define RCC_MC_AHB4LPENCLRR_GPIOFLPEN BIT(5)
+#define RCC_MC_AHB4LPENCLRR_GPIOGLPEN BIT(6)
+#define RCC_MC_AHB4LPENCLRR_GPIOHLPEN BIT(7)
+#define RCC_MC_AHB4LPENCLRR_GPIOILPEN BIT(8)
+#define RCC_MC_AHB4LPENCLRR_GPIOJLPEN BIT(9)
+#define RCC_MC_AHB4LPENCLRR_GPIOKLPEN BIT(10)
+
+/* RCC_MC_AXIMLPENSETR register fields */
+#define RCC_MC_AXIMLPENSETR_SYSRAMLPEN BIT(0)
+
+/* RCC_MC_AXIMLPENCLRR register fields */
+#define RCC_MC_AXIMLPENCLRR_SYSRAMLPEN BIT(0)
+
+/* RCC_MC_MLAHBLPENSETR register fields */
+#define RCC_MC_MLAHBLPENSETR_SRAM1LPEN BIT(0)
+#define RCC_MC_MLAHBLPENSETR_SRAM2LPEN BIT(1)
+#define RCC_MC_MLAHBLPENSETR_SRAM34LPEN BIT(2)
+#define RCC_MC_MLAHBLPENSETR_RETRAMLPEN BIT(4)
+
+/* RCC_MC_MLAHBLPENCLRR register fields */
+#define RCC_MC_MLAHBLPENCLRR_SRAM1LPEN BIT(0)
+#define RCC_MC_MLAHBLPENCLRR_SRAM2LPEN BIT(1)
+#define RCC_MC_MLAHBLPENCLRR_SRAM34LPEN BIT(2)
+#define RCC_MC_MLAHBLPENCLRR_RETRAMLPEN BIT(4)
+
+/* RCC_MC_RSTSCLRR register fields */
+#define RCC_MC_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_MC_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_MC_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_MC_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_MC_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_MC_RSTSCLRR_MCURSTF BIT(5)
+#define RCC_MC_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_MC_RSTSCLRR_MCSYSRSTF BIT(7)
+#define RCC_MC_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_MC_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_MC_RSTSCLRR_WWDG1RSTF BIT(10)
+
+/* RCC_MC_CIER register fields */
+#define RCC_MC_CIER_LSIRDYIE BIT(0)
+#define RCC_MC_CIER_LSERDYIE BIT(1)
+#define RCC_MC_CIER_HSIRDYIE BIT(2)
+#define RCC_MC_CIER_HSERDYIE BIT(3)
+#define RCC_MC_CIER_CSIRDYIE BIT(4)
+#define RCC_MC_CIER_PLL1DYIE BIT(8)
+#define RCC_MC_CIER_PLL2DYIE BIT(9)
+#define RCC_MC_CIER_PLL3DYIE BIT(10)
+#define RCC_MC_CIER_PLL4DYIE BIT(11)
+#define RCC_MC_CIER_LSECSSIE BIT(16)
+#define RCC_MC_CIER_WKUPIE BIT(20)
+
+/* RCC_MC_CIFR register fields */
+#define RCC_MC_CIFR_LSIRDYF BIT(0)
+#define RCC_MC_CIFR_LSERDYF BIT(1)
+#define RCC_MC_CIFR_HSIRDYF BIT(2)
+#define RCC_MC_CIFR_HSERDYF BIT(3)
+#define RCC_MC_CIFR_CSIRDYF BIT(4)
+#define RCC_MC_CIFR_PLL1DYF BIT(8)
+#define RCC_MC_CIFR_PLL2DYF BIT(9)
+#define RCC_MC_CIFR_PLL3DYF BIT(10)
+#define RCC_MC_CIFR_PLL4DYF BIT(11)
+#define RCC_MC_CIFR_LSECSSF BIT(16)
+#define RCC_MC_CIFR_WKUPF BIT(20)
+
+/* RCC_VERR register fields */
+#define RCC_VERR_MINREV_MASK GENMASK(3, 0)
+#define RCC_VERR_MINREV_SHIFT 0
+#define RCC_VERR_MAJREV_MASK GENMASK(7, 4)
+#define RCC_VERR_MAJREV_SHIFT 4
+
+/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
+#define RCC_OCENR_HSION BIT(0)
+#define RCC_OCENR_HSIKERON BIT(1)
+#define RCC_OCENR_CSION BIT(4)
+#define RCC_OCENR_CSIKERON BIT(5)
+#define RCC_OCENR_DIGBYP BIT(7)
+#define RCC_OCENR_HSEON BIT(8)
+#define RCC_OCENR_HSEKERON BIT(9)
+#define RCC_OCENR_HSEBYP BIT(10)
+#define RCC_OCENR_HSECSSON BIT(11)
+
+/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
+#define RCC_MP_ENCLRR_OFFSET U(4)
+
+/* Offset between RCC_xxxRSTSETR and RCC_xxxRSTCLRR registers */
+#define RCC_RSTCLRR_OFFSET U(4)
+
+/* Used for most of DIVR register: max div for RTC */
+#define RCC_DIVR_DIV_MASK GENMASK(5, 0)
+#define RCC_DIVR_DIVRDY BIT(31)
+
+/* Masks for specific DIVR registers */
+#define RCC_APBXDIV_MASK GENMASK(2, 0)
+#define RCC_MPUDIV_MASK GENMASK(2, 0)
+#define RCC_AXIDIV_MASK GENMASK(2, 0)
+#define RCC_MCUDIV_MASK GENMASK(3, 0)
+
+/* Used for most of RCC_<x>SELR registers */
+#define RCC_SELR_SRC_MASK GENMASK(2, 0)
+#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0)
+#define RCC_SELR_SRCRDY BIT(31)
+
+/* Used for all RCC_PLL<n>CR registers */
+#define RCC_PLLNCR_PLLON BIT(0)
+#define RCC_PLLNCR_PLLRDY BIT(1)
+#define RCC_PLLNCR_SSCG_CTRL BIT(2)
+#define RCC_PLLNCR_DIVPEN BIT(4)
+#define RCC_PLLNCR_DIVQEN BIT(5)
+#define RCC_PLLNCR_DIVREN BIT(6)
+#define RCC_PLLNCR_DIVEN_SHIFT 4
+
+/* Used for all RCC_PLL<n>CFGR1 registers */
+#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16)
+#define RCC_PLLNCFGR1_DIVM_SHIFT 16
+#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLLNCFGR1_DIVN_SHIFT 0
+
+/* Only for PLL3 and PLL4 */
+#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24)
+#define RCC_PLLNCFGR1_IFRGE_SHIFT 24
+
+/* Used for all RCC_PLL<n>CFGR2 registers */
+#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVP_SHIFT 0
+#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLLNCFGR2_DIVQ_SHIFT 8
+#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLLNCFGR2_DIVR_SHIFT 16
+
+/* Used for all RCC_PLL<n>FRACR registers */
+#define RCC_PLLNFRACR_FRACV_SHIFT 3
+#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLLNFRACR_FRACLE BIT(16)
+
+/* Used for all RCC_PLL<n>CSGR registers */
+#define RCC_PLLNCSGR_INC_STEP_SHIFT 16
+#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLLNCSGR_MOD_PER_SHIFT 0
+#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15
+#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15)
+
+/* Used for TIMER Prescaler */
+#define RCC_TIMGXPRER_TIMGXPRE BIT(0)
+
+/* Used for RCC_MCO related operations */
+#define RCC_MCOCFG_MCOON BIT(12)
+#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4)
+#define RCC_MCOCFG_MCODIV_SHIFT 4
+#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0)
+
#endif /* STM32MP1_RCC_H */
diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h
index c7e0b6e..c3329cc 100644
--- a/include/drivers/st/stm32mp_clkfunc.h
+++ b/include/drivers/st/stm32mp_clkfunc.h
@@ -19,7 +19,6 @@
const char *prop_name,
uint32_t dflt_value);
-int fdt_get_rcc_node(void *fdt);
int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count,
uint32_t *array);
int fdt_rcc_subnode_offset(const char *name);
diff --git a/include/dt-bindings/soc/stm32mp15-tzc400.h b/include/dt-bindings/soc/stm32mp15-tzc400.h
new file mode 100644
index 0000000..54cd902
--- /dev/null
+++ b/include/dt-bindings/soc/stm32mp15-tzc400.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _DT_BINDINGS_STM32MP15_TZC400_H
+#define _DT_BINDINGS_STM32MP15_TZC400_H
+
+#include <drivers/arm/tzc_common.h>
+
+#define STM32MP1_TZC_A7_ID U(0)
+#define STM32MP1_TZC_M4_ID U(1)
+#define STM32MP1_TZC_LCD_ID U(3)
+#define STM32MP1_TZC_GPU_ID U(4)
+#define STM32MP1_TZC_MDMA_ID U(5)
+#define STM32MP1_TZC_DMA_ID U(6)
+#define STM32MP1_TZC_USB_HOST_ID U(7)
+#define STM32MP1_TZC_USB_OTG_ID U(8)
+#define STM32MP1_TZC_SDMMC_ID U(9)
+#define STM32MP1_TZC_ETH_ID U(10)
+#define STM32MP1_TZC_DAP_ID U(15)
+
+#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \
+ (TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID))
+
+#endif /* _DT_BINDINGS_STM32MP15_TZC400_H */
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index 44c540c..19394ba 100644
--- a/include/lib/cpus/aarch64/cortex_a710.h
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -13,6 +13,7 @@
* CPU Extended Control register specific definitions
******************************************************************************/
#define CORTEX_A710_CPUECTLR_EL1 S3_0_C15_C1_4
+#define CORTEX_A710_CPUECTLR_EL1_PFSTIDIS_BIT (ULL(1) << 8)
/*******************************************************************************
* CPU Power Control register specific definitions
@@ -20,4 +21,16 @@
#define CORTEX_A710_CPUPWRCTLR_EL1 S3_0_C15_C2_7
#define CORTEX_A710_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A710_CPUACTLR_EL1 S3_0_C15_C1_0
+#define CORTEX_A710_CPUACTLR_EL1_BIT_46 (ULL(1) << 46)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A710_CPUACTLR5_EL1 S3_0_C15_C8_0
+#define CORTEX_A710_CPUACTLR5_EL1_BIT_13 (ULL(1) << 13)
+
#endif /* CORTEX_A710_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h
index 4bc49f3..42b0833 100644
--- a/include/lib/cpus/aarch64/cortex_a78.h
+++ b/include/lib/cpus/aarch64/cortex_a78.h
@@ -16,6 +16,9 @@
******************************************************************************/
#define CORTEX_A78_CPUECTLR_EL1 S3_0_C15_C1_4
#define CORTEX_A78_CPUECTLR_EL1_BIT_8 (ULL(1) << 8)
+#define CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV ULL(3)
+#define CPUECTLR_EL1_PF_MODE_LSB U(6)
+#define CPUECTLR_EL1_PF_MODE_WIDTH U(2)
/*******************************************************************************
* CPU Power Control register specific definitions
diff --git a/include/lib/cpus/aarch64/cortex_hayes.h b/include/lib/cpus/aarch64/cortex_hayes.h
new file mode 100644
index 0000000..82022e9
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_hayes.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_HAYES_H
+#define CORTEX_HAYES_H
+
+#define CORTEX_HAYES_MIDR U(0x410FD800)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_HAYES_CPUECTLR_EL1 S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_HAYES_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_HAYES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+
+#endif /* CORTEX_HAYES_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index 7cbd8c1..f414cb5 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,24 +8,45 @@
#define NEOVERSE_N2_H
/* Neoverse N2 ID register for revision r0p0 */
-#define NEOVERSE_N2_MIDR U(0x410FD490)
+#define NEOVERSE_N2_MIDR U(0x410FD490)
/*******************************************************************************
* CPU Power control register
******************************************************************************/
-#define NEOVERSE_N2_CPUPWRCTLR_EL1 S3_0_C15_C2_7
-#define NEOVERSE_N2_CORE_PWRDN_EN_BIT (ULL(1) << 0)
+#define NEOVERSE_N2_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define NEOVERSE_N2_CORE_PWRDN_EN_BIT (ULL(1) << 0)
/*******************************************************************************
* CPU Extended Control register specific definitions.
******************************************************************************/
-#define NEOVERSE_N2_CPUECTLR_EL1 S3_0_C15_C1_4
-#define NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT (ULL(1) << 0)
+#define NEOVERSE_N2_CPUECTLR_EL1 S3_0_C15_C1_4
+#define NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT (ULL(1) << 0)
+#define NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT (ULL(1) << 8)
/*******************************************************************************
* CPU Auxiliary Control register specific definitions.
******************************************************************************/
-#define NEOVERSE_N2_CPUACTLR2_EL1 S3_0_C15_C1_1
-#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2)
+#define NEOVERSE_N2_CPUACTLR_EL1 S3_0_C15_C1_0
+#define NEOVERSE_N2_CPUACTLR_EL1_BIT_46 (ULL(1) << 46)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N2_CPUACTLR2_EL1 S3_0_C15_C1_1
+#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 5 specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N2_CPUACTLR5_EL1 S3_0_C15_C8_0
+#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44 (ULL(1) << 44)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N2_CPUECTLR2_EL1 S3_0_C15_C1_5
+#define NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV ULL(9)
+#define CPUECTLR2_EL1_PF_MODE_LSB U(11)
+#define CPUECTLR2_EL1_PF_MODE_WIDTH U(4)
#endif /* NEOVERSE_N2_H */
diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h
index cfb26ab..e43c907 100644
--- a/include/lib/cpus/aarch64/neoverse_v1.h
+++ b/include/lib/cpus/aarch64/neoverse_v1.h
@@ -15,6 +15,9 @@
#define NEOVERSE_V1_CPUECTLR_EL1 S3_0_C15_C1_4
#define NEOVERSE_V1_CPUECTLR_EL1_BIT_8 (ULL(1) << 8)
#define NEOVERSE_V1_CPUECTLR_EL1_BIT_53 (ULL(1) << 53)
+#define NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV ULL(3)
+#define CPUECTLR_EL1_PF_MODE_LSB U(6)
+#define CPUECTLR_EL1_PF_MODE_WIDTH U(2)
/*******************************************************************************
* CPU Power Control register specific definitions
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index d449a65..c3f4117 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -228,6 +228,10 @@
// Starting with Armv8.5
#define CTX_SCXTNUM_EL2 U(0x1e0)
+
+// Register for FEAT_HCX
+#define CTX_HCRX_EL2 U(0x1e8)
+
/* Align to the next 16 byte boundary */
#define CTX_EL2_SYSREGS_END U(0x1f0)
diff --git a/include/lib/extensions/sys_reg_trace.h b/include/lib/extensions/sys_reg_trace.h
new file mode 100644
index 0000000..74470fe
--- /dev/null
+++ b/include/lib/extensions/sys_reg_trace.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYS_REG_TRACE_H
+#define SYS_REG_TRACE_H
+
+#include <context.h>
+
+#if __aarch64__
+void sys_reg_trace_enable(cpu_context_t *context);
+#else
+void sys_reg_trace_enable(void);
+#endif /* __aarch64__ */
+
+#endif /* SYS_REG_TRACE_H */
diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h
new file mode 100644
index 0000000..1753ab6
--- /dev/null
+++ b/include/lib/extensions/trbe.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRBE_H
+#define TRBE_H
+
+void trbe_enable(void);
+
+#endif /* TRBE_H */
diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h
new file mode 100644
index 0000000..18f17f3
--- /dev/null
+++ b/include/lib/extensions/trf.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRF_H
+#define TRF_H
+
+void trf_enable(void);
+
+#endif /* TRF_H */
diff --git a/include/lib/optee_utils.h b/include/lib/optee_utils.h
index 6067caf..06378eb 100644
--- a/include/lib/optee_utils.h
+++ b/include/lib/optee_utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,8 +7,12 @@
#ifndef OPTEE_UTILS_H
#define OPTEE_UTILS_H
+#include <stdbool.h>
+
#include <common/bl_common.h>
+bool optee_header_is_valid(uintptr_t header_base);
+
int parse_optee_header(entry_point_info_t *header_ep,
image_info_t *pager_image_info,
image_info_t *paged_image_info);
diff --git a/include/lib/xlat_mpu/xlat_mpu.h b/include/lib/xlat_mpu/xlat_mpu.h
new file mode 100644
index 0000000..252b92c
--- /dev/null
+++ b/include/lib/xlat_mpu/xlat_mpu.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef XLAT_MPU_H
+#define XLAT_MPU_H
+
+#ifndef __ASSEMBLER__
+
+#include <lib/cassert.h>
+
+#define XLAT_TABLES_LIB_V2 1
+
+void enable_mpu_el2(unsigned int flags);
+void enable_mpu_direct_el2(unsigned int flags);
+
+/*
+ * Function to wipe clean and disable all MPU regions. This function expects
+ * that the MPU has already been turned off, and caching concerns addressed,
+ * but it nevertheless also explicitly turns off the MPU.
+ */
+void clear_all_mpu_regions(void);
+
+#endif /* __ASSEMBLER__ */
+#endif /* XLAT_MPU_H */
diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h
index 6a6979c..cb11dac 100644
--- a/include/plat/arm/board/common/v2m_def.h
+++ b/include/plat/arm/board/common/v2m_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,13 @@
#include <lib/utils_def.h>
+/* Base address of all V2M */
+#ifdef PLAT_V2M_OFFSET
+#define V2M_OFFSET PLAT_V2M_OFFSET
+#else
+#define V2M_OFFSET UL(0)
+#endif
+
/* V2M motherboard system registers & offsets */
#define V2M_SYSREGS_BASE UL(0x1c010000)
#define V2M_SYS_ID UL(0x0)
@@ -69,18 +76,18 @@
/* NOR Flash */
-#define V2M_FLASH0_BASE UL(0x08000000)
+#define V2M_FLASH0_BASE (V2M_OFFSET + UL(0x08000000))
#define V2M_FLASH0_SIZE UL(0x04000000)
-#define V2M_FLASH_BLOCK_SIZE UL(0x00040000) /* 256 KB */
+#define V2M_FLASH_BLOCK_SIZE UL(0x00040000) /* 256 KB */
-#define V2M_IOFPGA_BASE UL(0x1c000000)
+#define V2M_IOFPGA_BASE (V2M_OFFSET + UL(0x1c000000))
#define V2M_IOFPGA_SIZE UL(0x03000000)
/* PL011 UART related constants */
-#define V2M_IOFPGA_UART0_BASE UL(0x1c090000)
-#define V2M_IOFPGA_UART1_BASE UL(0x1c0a0000)
-#define V2M_IOFPGA_UART2_BASE UL(0x1c0b0000)
-#define V2M_IOFPGA_UART3_BASE UL(0x1c0c0000)
+#define V2M_IOFPGA_UART0_BASE (V2M_OFFSET + UL(0x1c090000))
+#define V2M_IOFPGA_UART1_BASE (V2M_OFFSET + UL(0x1c0a0000))
+#define V2M_IOFPGA_UART2_BASE (V2M_OFFSET + UL(0x1c0b0000))
+#define V2M_IOFPGA_UART3_BASE (V2M_OFFSET + UL(0x1c0c0000))
#define V2M_IOFPGA_UART0_CLK_IN_HZ 24000000
#define V2M_IOFPGA_UART1_CLK_IN_HZ 24000000
@@ -88,11 +95,11 @@
#define V2M_IOFPGA_UART3_CLK_IN_HZ 24000000
/* SP804 timer related constants */
-#define V2M_SP804_TIMER0_BASE UL(0x1C110000)
-#define V2M_SP804_TIMER1_BASE UL(0x1C120000)
+#define V2M_SP804_TIMER0_BASE (V2M_OFFSET + UL(0x1C110000))
+#define V2M_SP804_TIMER1_BASE (V2M_OFFSET + UL(0x1C120000))
/* SP810 controller */
-#define V2M_SP810_BASE UL(0x1c020000)
+#define V2M_SP810_BASE (V2M_OFFSET + UL(0x1c020000))
#define V2M_SP810_CTRL_TIM0_SEL BIT_32(15)
#define V2M_SP810_CTRL_TIM1_SEL BIT_32(17)
#define V2M_SP810_CTRL_TIM2_SEL BIT_32(19)
diff --git a/include/plat/arm/board/fvp_r/fvp_r_bl1.h b/include/plat/arm/board/fvp_r/fvp_r_bl1.h
new file mode 100644
index 0000000..0b41e67
--- /dev/null
+++ b/include/plat/arm/board/fvp_r/fvp_r_bl1.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_R_BL1_H
+#define FVP_R_BL1_H
+
+void bl1_load_bl33(void);
+void bl1_transfer_bl33(void);
+
+#endif /* FVP_R_BL1_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index ae80628..7cc215f 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -58,8 +58,12 @@
#define ARM_TRUSTED_DRAM_ID 1
#define ARM_DRAM_ID 2
-/* The first 4KB of Trusted SRAM are used as shared memory */
+#ifdef PLAT_ARM_TRUSTED_SRAM_BASE
+#define ARM_TRUSTED_SRAM_BASE PLAT_ARM_TRUSTED_SRAM_BASE
+#else
#define ARM_TRUSTED_SRAM_BASE UL(0x04000000)
+#endif /* PLAT_ARM_TRUSTED_SRAM_BASE */
+
#define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE
#define ARM_SHARED_RAM_SIZE UL(0x00001000) /* 4 KB */
@@ -149,8 +153,12 @@
ARM_TZC_DRAM1_SIZE)
#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \
ARM_NS_DRAM1_SIZE - 1U)
-
+#ifdef PLAT_ARM_DRAM1_BASE
+#define ARM_DRAM1_BASE PLAT_ARM_DRAM1_BASE
+#else
#define ARM_DRAM1_BASE ULL(0x80000000)
+#endif /* PLAT_ARM_DRAM1_BASE */
+
#define ARM_DRAM1_SIZE ULL(0x80000000)
#define ARM_DRAM1_END (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - 1U)
@@ -312,16 +320,44 @@
ARM_BL_REGIONS)
/* Memory mapped Generic timer interfaces */
+#ifdef PLAT_ARM_SYS_CNTCTL_BASE
+#define ARM_SYS_CNTCTL_BASE PLAT_ARM_SYS_CNTCTL_BASE
+#else
#define ARM_SYS_CNTCTL_BASE UL(0x2a430000)
+#endif
+
+#ifdef PLAT_ARM_SYS_CNTREAD_BASE
+#define ARM_SYS_CNTREAD_BASE PLAT_ARM_SYS_CNTREAD_BASE
+#else
#define ARM_SYS_CNTREAD_BASE UL(0x2a800000)
+#endif
+
+#ifdef PLAT_ARM_SYS_TIMCTL_BASE
+#define ARM_SYS_TIMCTL_BASE PLAT_ARM_SYS_TIMCTL_BASE
+#else
#define ARM_SYS_TIMCTL_BASE UL(0x2a810000)
+#endif
+
+#ifdef PLAT_ARM_SYS_CNT_BASE_S
+#define ARM_SYS_CNT_BASE_S PLAT_ARM_SYS_CNT_BASE_S
+#else
#define ARM_SYS_CNT_BASE_S UL(0x2a820000)
+#endif
+
+#ifdef PLAT_ARM_SYS_CNT_BASE_NS
+#define ARM_SYS_CNT_BASE_NS PLAT_ARM_SYS_CNT_BASE_NS
+#else
#define ARM_SYS_CNT_BASE_NS UL(0x2a830000)
+#endif
#define ARM_CONSOLE_BAUDRATE 115200
/* Trusted Watchdog constants */
+#ifdef PLAT_ARM_SP805_TWDG_BASE
+#define ARM_SP805_TWDG_BASE PLAT_ARM_SP805_TWDG_BASE
+#else
#define ARM_SP805_TWDG_BASE UL(0x2a490000)
+#endif
#define ARM_SP805_TWDG_CLK_HZ 32768
/* The TBBR document specifies a watchdog timeout of 256 seconds. SP805
* asserts reset after two consecutive countdowns (2 x 128 = 256 sec) */
@@ -379,9 +415,14 @@
* addresses.
******************************************************************************/
#define BL1_RO_BASE PLAT_ARM_TRUSTED_ROM_BASE
+#ifdef PLAT_BL1_RO_LIMIT
+#define BL1_RO_LIMIT PLAT_BL1_RO_LIMIT
+#else
#define BL1_RO_LIMIT (PLAT_ARM_TRUSTED_ROM_BASE \
+ (PLAT_ARM_TRUSTED_ROM_SIZE - \
PLAT_ARM_MAX_ROMLIB_RO_SIZE))
+#endif
+
/*
* Put BL1 RW at the top of the Trusted SRAM.
*/
diff --git a/include/plat/arm/common/fconf_ethosn_getter.h b/include/plat/arm/common/fconf_ethosn_getter.h
index 0fd1f02..fcdc31f 100644
--- a/include/plat/arm/common/fconf_ethosn_getter.h
+++ b/include/plat/arm/common/fconf_ethosn_getter.h
@@ -14,7 +14,7 @@
#define hw_config__ethosn_config_getter(prop) ethosn_config.prop
#define hw_config__ethosn_core_addr_getter(idx) __extension__ ({ \
assert(idx < ethosn_config.num_cores); \
- ethosn_config.core_addr[idx]; \
+ ethosn_config.core[idx].addr; \
})
#define ETHOSN_STATUS_DISABLED U(0)
@@ -22,10 +22,13 @@
#define ETHOSN_CORE_NUM_MAX U(64)
+struct ethosn_core_t {
+ uint64_t addr;
+};
+
struct ethosn_config_t {
- uint8_t status;
uint32_t num_cores;
- uint64_t core_addr[ETHOSN_CORE_NUM_MAX];
+ struct ethosn_core_t core[ETHOSN_CORE_NUM_MAX];
};
int fconf_populate_arm_ethosn(uintptr_t config);
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index ab36d9e..85ff703 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -128,6 +128,16 @@
#define FFA_MEM_RETRIEVE_RESP FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_RESP)
#define FFA_MEM_RELINQUISH FFA_FID(SMC_32, FFA_FNUM_MEM_RELINQUISH)
#define FFA_MEM_RECLAIM FFA_FID(SMC_32, FFA_FNUM_MEM_RECLAIM)
+#define FFA_NOTIFICATION_BITMAP_CREATE \
+ FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BITMAP_CREATE)
+#define FFA_NOTIFICATION_BITMAP_DESTROY \
+ FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BITMAP_DESTROY)
+#define FFA_NOTIFICATION_BIND FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BIND)
+#define FFA_NOTIFICATION_UNBIND FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_UNBIND)
+#define FFA_NOTIFICATION_SET FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_SET)
+#define FFA_NOTIFICATION_GET FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_GET)
+#define FFA_NOTIFICATION_INFO_GET \
+ FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_INFO_GET)
#define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
/* FFA SMC64 FIDs */
@@ -145,6 +155,8 @@
FFA_FID(SMC_64, FFA_FNUM_MEM_RETRIEVE_REQ)
#define FFA_SECONDARY_EP_REGISTER_SMC64 \
FFA_FID(SMC_64, FFA_FNUM_SECONDARY_EP_REGISTER)
+#define FFA_NOTIFICATION_INFO_GET_SMC64 \
+ FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
/*
* Reserve a special value for traffic targeted to the Hypervisor or SPM.
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 469b430..f6a4209 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -107,6 +107,87 @@
b cpu_rev_var_ls
endfunc check_errata_2081180
+/* ---------------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2055002.
+ * This applies to revision r1p0, r2p0 of Cortex-A710 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------------
+ */
+func errata_a710_2055002_wa
+ /* Compare x0 against revision r2p0 */
+ mov x17, x30
+ bl check_errata_2055002
+ cbz x0, 1f
+ mrs x1, CORTEX_A710_CPUACTLR_EL1
+ orr x1, x1, CORTEX_A710_CPUACTLR_EL1_BIT_46
+ msr CORTEX_A710_CPUACTLR_EL1, x1
+1:
+ ret x17
+endfunc errata_a710_2055002_wa
+
+func check_errata_2055002
+ /* Applies to r1p0, r2p0 */
+ mov x1, #0x20
+ b cpu_rev_var_ls
+endfunc check_errata_2055002
+
+/* -------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2017096.
+ * This applies to revisions r0p0, r1p0 and r2p0 of Cortex-A710.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -------------------------------------------------------------
+ */
+func errata_a710_2017096_wa
+ /* Compare x0 against revision r0p0 to r2p0 */
+ mov x17, x30
+ bl check_errata_2017096
+ cbz x0, 1f
+ mrs x1, CORTEX_A710_CPUECTLR_EL1
+ orr x1, x1, CORTEX_A710_CPUECTLR_EL1_PFSTIDIS_BIT
+ msr CORTEX_A710_CPUECTLR_EL1, x1
+
+1:
+ ret x17
+endfunc errata_a710_2017096_wa
+
+func check_errata_2017096
+ /* Applies to r0p0, r1p0, r2p0 */
+ mov x1, #0x20
+ b cpu_rev_var_ls
+endfunc check_errata_2017096
+
+
+/* ---------------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2083908.
+ * This applies to revision r2p0 of Cortex-A710 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------------
+ */
+func errata_a710_2083908_wa
+ /* Compare x0 against revision r2p0 */
+ mov x17, x30
+ bl check_errata_2083908
+ cbz x0, 1f
+ mrs x1, CORTEX_A710_CPUACTLR5_EL1
+ orr x1, x1, CORTEX_A710_CPUACTLR5_EL1_BIT_13
+ msr CORTEX_A710_CPUACTLR5_EL1, x1
+1:
+ ret x17
+endfunc errata_a710_2083908_wa
+
+func check_errata_2083908
+ /* Applies to r2p0 */
+ mov x1, #CPU_REV(2, 0)
+ mov x2, #CPU_REV(2, 0)
+ b cpu_rev_var_range
+endfunc check_errata_2083908
+
/* ----------------------------------------------------
* HW will do the cache maintenance while powering down
* ----------------------------------------------------
@@ -123,10 +204,10 @@
ret
endfunc cortex_a710_core_pwr_dwn
- /*
- * Errata printing function for Cortex A710. Must follow AAPCS.
- */
#if REPORT_ERRATA
+ /*
+ * Errata printing function for Cortex-A710. Must follow AAPCS.
+ */
func cortex_a710_errata_report
stp x8, x30, [sp, #-16]!
@@ -139,6 +220,9 @@
*/
report_errata ERRATA_A710_1987031, cortex_a710, 1987031
report_errata ERRATA_A710_2081180, cortex_a710, 2081180
+ report_errata ERRATA_A710_2055002, cortex_a710, 2055002
+ report_errata ERRATA_A710_2017096, cortex_a710, 2017096
+ report_errata ERRATA_A710_2083908, cortex_a710, 2083908
ldp x8, x30, [sp], #16
ret
@@ -164,8 +248,22 @@
bl errata_a710_2081180_wa
#endif
+#if ERRATA_A710_2055002
+ mov x0, x18
+ bl errata_a710_2055002_wa
+#endif
+
+#if ERRATA_A710_2017096
+ mov x0, x18
+ bl errata_a710_2017096_wa
+#endif
+
+#if ERRATA_A710_2083908
+ mov x0, x18
+ bl errata_a710_2083908_wa
+#endif
isb
- ret x19
+ ret x19
endfunc cortex_a710_reset_func
/* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 3a74571..4e8a228 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -198,6 +198,35 @@
b cpu_rev_var_ls
endfunc check_errata_1952683
+/* --------------------------------------------------
+ * Errata Workaround for Cortex A78 Errata 2132060.
+ * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
+ * It is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_a78_2132060_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2132060
+ cbz x0, 1f
+
+ /* Apply the workaround. */
+ mrs x1, CORTEX_A78_CPUECTLR_EL1
+ mov x0, #CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV
+ bfi x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
+ msr CORTEX_A78_CPUECTLR_EL1, x1
+1:
+ ret x17
+endfunc errata_a78_2132060_wa
+
+func check_errata_2132060
+ /* Applies to r0p0, r0p1, r1p1, and r1p2 */
+ mov x1, #0x12
+ b cpu_rev_var_ls
+endfunc check_errata_2132060
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A78
* -------------------------------------------------
@@ -232,6 +261,11 @@
bl errata_a78_1952683_wa
#endif
+#if ERRATA_A78_2132060
+ mov x0, x18
+ bl errata_a78_2132060_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
@@ -291,6 +325,7 @@
report_errata ERRATA_A78_1951500, cortex_a78, 1951500
report_errata ERRATA_A78_1821534, cortex_a78, 1821534
report_errata ERRATA_A78_1952683, cortex_a78, 1952683
+ report_errata ERRATA_A78_2132060, cortex_a78, 2132060
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/cortex_hayes.S b/lib/cpus/aarch64/cortex_hayes.S
new file mode 100644
index 0000000..445a691
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_hayes.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_hayes.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex Hayes must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex Hayes supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+ /* ----------------------------------------------------
+ * HW will do the cache maintenance while powering down
+ * ----------------------------------------------------
+ */
+func cortex_hayes_core_pwr_dwn
+ /* ---------------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------------
+ */
+ mrs x0, CORTEX_HAYES_CPUPWRCTLR_EL1
+ orr x0, x0, #CORTEX_HAYES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+ msr CORTEX_HAYES_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+endfunc cortex_hayes_core_pwr_dwn
+
+ /*
+ * Errata printing function for Cortex Hayes. Must follow AAPCS.
+ */
+#if REPORT_ERRATA
+func cortex_hayes_errata_report
+ ret
+endfunc cortex_hayes_errata_report
+#endif
+
+func cortex_hayes_reset_func
+ /* Disable speculative loads */
+ msr SSBS, xzr
+ isb
+ ret
+endfunc cortex_hayes_reset_func
+
+ /* ---------------------------------------------
+ * This function provides Cortex Hayes specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.cortex_hayes_regs, "aS"
+cortex_hayes_regs: /* The ascii list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func cortex_hayes_cpu_reg_dump
+ adr x6, cortex_hayes_regs
+ mrs x8, CORTEX_HAYES_CPUECTLR_EL1
+ ret
+endfunc cortex_hayes_cpu_reg_dump
+
+declare_cpu_ops cortex_hayes, CORTEX_HAYES_MIDR, \
+ cortex_hayes_reset_func, \
+ cortex_hayes_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 44db0b3..330cc59 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -61,9 +61,160 @@
b cpu_rev_var_ls
endfunc check_errata_2002655
- /* -------------------------------------------------
+/* ---------------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2067956.
+ * This applies to revision r0p0 of Neoverse N2 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------
+ */
+func errata_n2_2067956_wa
+ /* Compare x0 against revision r0p0 */
+ mov x17, x30
+ bl check_errata_2067956
+ cbz x0, 1f
+ mrs x1, NEOVERSE_N2_CPUACTLR_EL1
+ orr x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_46
+ msr NEOVERSE_N2_CPUACTLR_EL1, x1
+1:
+ ret x17
+endfunc errata_n2_2067956_wa
+
+func check_errata_2067956
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2067956
+
+/* ---------------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2025414.
+ * This applies to revision r0p0 of Neoverse N2 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------
+ */
+func errata_n2_2025414_wa
+ /* Compare x0 against revision r0p0 */
+ mov x17, x30
+ bl check_errata_2025414
+ cbz x0, 1f
+ mrs x1, NEOVERSE_N2_CPUECTLR_EL1
+ orr x1, x1, NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT
+ msr NEOVERSE_N2_CPUECTLR_EL1, x1
+
+1:
+ ret x17
+endfunc errata_n2_2025414_wa
+
+func check_errata_2025414
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2025414
+
+/* ---------------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2189731.
+ * This applies to revision r0p0 of Neoverse N2 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------
+ */
+func errata_n2_2189731_wa
+ /* Compare x0 against revision r0p0 */
+ mov x17, x30
+ bl check_errata_2189731
+ cbz x0, 1f
+ mrs x1, NEOVERSE_N2_CPUACTLR5_EL1
+ orr x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_44
+ msr NEOVERSE_N2_CPUACTLR5_EL1, x1
+
+1:
+ ret x17
+endfunc errata_n2_2189731_wa
+
+func check_errata_2189731
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2189731
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2138956.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_n2_2138956_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2138956
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ ldr x0,=0x3
+ msr S3_6_c15_c8_0,x0
+ ldr x0,=0xF3A08002
+ msr S3_6_c15_c8_2,x0
+ ldr x0,=0xFFF0F7FE
+ msr S3_6_c15_c8_3,x0
+ ldr x0,=0x10002001003FF
+ msr S3_6_c15_c8_1,x0
+ ldr x0,=0x4
+ msr S3_6_c15_c8_0,x0
+ ldr x0,=0xBF200000
+ msr S3_6_c15_c8_2,x0
+ ldr x0,=0xFFEF0000
+ msr S3_6_c15_c8_3,x0
+ ldr x0,=0x10002001003F3
+ msr S3_6_c15_c8_1,x0
+ isb
+1:
+ ret x17
+endfunc errata_n2_2138956_wa
+
+func check_errata_2138956
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2138956
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2138953.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2138953_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2138953
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ mrs x1, NEOVERSE_N2_CPUECTLR2_EL1
+ mov x0, #NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV
+ bfi x1, x0, #CPUECTLR2_EL1_PF_MODE_LSB, #CPUECTLR2_EL1_PF_MODE_WIDTH
+ msr NEOVERSE_N2_CPUECTLR2_EL1, x1
+1:
+ ret x17
+endfunc errata_n2_2138953_wa
+
+func check_errata_2138953
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2138953
+
+ /* -------------------------------------------
* The CPU Ops reset function for Neoverse N2.
- * -------------------------------------------------
+ * -------------------------------------------
*/
func neoverse_n2_reset_func
mov x19, x30
@@ -81,6 +232,32 @@
orr x0, x0, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_2
msr NEOVERSE_N2_CPUACTLR2_EL1, x0
+#if ERRATA_N2_2067956
+ mov x0, x18
+ bl errata_n2_2067956_wa
+#endif
+
+#if ERRATA_N2_2025414
+ mov x0, x18
+ bl errata_n2_2025414_wa
+#endif
+
+#if ERRATA_N2_2189731
+ mov x0, x18
+ bl errata_n2_2189731_wa
+#endif
+
+
+#if ERRATA_N2_2138956
+ mov x0, x18
+ bl errata_n2_2138956_wa
+#endif
+
+#if ERRATA_N2_2138953
+ mov x0, x18
+ bl errata_n2_2138953_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, cptr_el3
@@ -97,9 +274,9 @@
#if NEOVERSE_Nx_EXTERNAL_LLC
/* Some systems may have External LLC, core needs to be made aware */
- mrs x0, NEOVERSE_N2_CPUECTLR_EL1
- orr x0, x0, NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT
- msr NEOVERSE_N2_CPUECTLR_EL1, x0
+ mrs x0, NEOVERSE_N2_CPUECTLR_EL1
+ orr x0, x0, NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT
+ msr NEOVERSE_N2_CPUECTLR_EL1, x0
#endif
bl cpu_get_rev_var
@@ -111,14 +288,14 @@
#endif
isb
- ret x19
+ ret x19
endfunc neoverse_n2_reset_func
func neoverse_n2_core_pwr_dwn
- /* ---------------------------------------------
+ /* ---------------------------------------------------
* Enable CPU power down bit in power control register
* No need to do cache maintenance here.
- * ---------------------------------------------
+ * ---------------------------------------------------
*/
mrs x0, NEOVERSE_N2_CPUPWRCTLR_EL1
orr x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT
@@ -142,6 +319,11 @@
* checking functions of each errata.
*/
report_errata ERRATA_N2_2002655, neoverse_n2, 2002655
+ report_errata ERRATA_N2_2067956, neoverse_n2, 2067956
+ report_errata ERRATA_N2_2025414, neoverse_n2, 2025414
+ report_errata ERRATA_N2_2189731, neoverse_n2, 2189731
+ report_errata ERRATA_N2_2138956, neoverse_n2, 2138956
+ report_errata ERRATA_N2_2138953, neoverse_n2, 2138953
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 0bcf52a..200f67d 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -259,6 +259,35 @@
b cpu_rev_var_ls
endfunc check_errata_2139242
+ /* --------------------------------------------------
+ * Errata Workaround for Neoverse V1 Errata #2108267.
+ * This applies to revisions r0p0, r1p0, and r1p1, it
+ * is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_neoverse_v1_2108267_wa
+ /* Check workaround compatibility. */
+ mov x17, x30
+ bl check_errata_2108267
+ cbz x0, 1f
+
+ /* Apply the workaround. */
+ mrs x1, NEOVERSE_V1_CPUECTLR_EL1
+ mov x0, #NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV
+ bfi x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
+ msr NEOVERSE_V1_CPUECTLR_EL1, x1
+1:
+ ret x17
+endfunc errata_neoverse_v1_2108267_wa
+
+func check_errata_2108267
+ /* Applies to r0p0, r1p0, r1p1 */
+ mov x1, #0x11
+ b cpu_rev_var_ls
+endfunc check_errata_2108267
+
/* ---------------------------------------------
* HW will do the cache maintenance while powering down
* ---------------------------------------------
@@ -296,6 +325,7 @@
report_errata ERRATA_V1_1940577, neoverse_v1, 1940577
report_errata ERRATA_V1_1966096, neoverse_v1, 1966096
report_errata ERRATA_V1_2139242, neoverse_v1, 2139242
+ report_errata ERRATA_V1_2108267, neoverse_v1, 2108267
ldp x8, x30, [sp], #16
ret
@@ -344,6 +374,11 @@
bl errata_neoverse_v1_2139242_wa
#endif
+#if ERRATA_V1_2108267
+ mov x0, x18
+ bl errata_neoverse_v1_2108267_wa
+#endif
+
ret x19
endfunc neoverse_v1_reset_func
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index ab50933..8e799ea 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -327,6 +327,10 @@
# to revision r0p0 of the A78 cpu and was fixed in the revision r1p0.
ERRATA_A78_1952683 ?=0
+# Flag to apply erratum 2132060 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
+ERRATA_A78_2132060 ?=0
+
# Flag to apply T32 CLREX workaround during reset. This erratum applies
# only to r0p0 and r1p0 of the Neoverse N1 cpu.
ERRATA_N1_1043202 ?=0
@@ -411,11 +415,15 @@
# Flag to apply erratum 1966096 workaround during reset. This erratum applies
# to revisions r1p0 and r1p1 of the Neoverse V1 CPU and is open. This issue
# exists in r0p0 as well but there is no workaround for that revision.
-ERRATA_V1_1966096 ?=0
+ERRATA_V1_1966096 ?=0
# Flag to apply erratum 2139242 workaround during reset. This erratum applies
# to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
-ERRATA_V1_2139242 ?=0
+ERRATA_V1_2139242 ?=0
+
+# Flag to apply erratum 2108267 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
+ERRATA_V1_2108267 ?=0
# Flag to apply erratum 1987031 workaround during reset. This erratum applies
# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
@@ -425,6 +433,38 @@
# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
ERRATA_A710_2081180 ?=0
+# Flag to apply erratum 2083908 workaround during reset. This erratum applies
+# to revision r2p0 of the Cortex-A710 cpu and is still open.
+ERRATA_A710_2083908 ?=0
+
+# Flag to apply erratum 2067956 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2067956 ?=0
+
+# Flag to apply erratum 2025414 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2025414 ?=0
+
+# Flag to apply erratum 2189731 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2189731 ?=0
+
+# Flag to apply erratum 2138956 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2138956 ?=0
+
+# Flag to apply erratum 2138953 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2138953 ?=0
+
+# Flag to apply erratum 2055002 workaround during reset. This erratum applies
+# to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open.
+ERRATA_A710_2055002 ?=0
+
+# Flag to apply erratum 2017096 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
+ERRATA_A710_2017096 ?=0
+
# Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
# Applying the workaround results in higher DSU power consumption on idle.
ERRATA_DSU_798953 ?=0
@@ -686,6 +726,10 @@
$(eval $(call assert_boolean,ERRATA_A78_1952683))
$(eval $(call add_define,ERRATA_A78_1952683))
+# Process ERRATA_A78_2132060 flag
+$(eval $(call assert_boolean,ERRATA_A78_2132060))
+$(eval $(call add_define,ERRATA_A78_2132060))
+
# Process ERRATA_N1_1043202 flag
$(eval $(call assert_boolean,ERRATA_N1_1043202))
$(eval $(call add_define,ERRATA_N1_1043202))
@@ -774,6 +818,10 @@
$(eval $(call assert_boolean,ERRATA_V1_2139242))
$(eval $(call add_define,ERRATA_V1_2139242))
+# Process ERRATA_V1_2108267 flag
+$(eval $(call assert_boolean,ERRATA_V1_2108267))
+$(eval $(call add_define,ERRATA_V1_2108267))
+
# Process ERRATA_A710_1987031 flag
$(eval $(call assert_boolean,ERRATA_A710_1987031))
$(eval $(call add_define,ERRATA_A710_1987031))
@@ -782,6 +830,38 @@
$(eval $(call assert_boolean,ERRATA_A710_2081180))
$(eval $(call add_define,ERRATA_A710_2081180))
+# Process ERRATA_A710_2083908 flag
+$(eval $(call assert_boolean,ERRATA_A710_2083908))
+$(eval $(call add_define,ERRATA_A710_2083908))
+
+# Process ERRATA_N2_2067956 flag
+$(eval $(call assert_boolean,ERRATA_N2_2067956))
+$(eval $(call add_define,ERRATA_N2_2067956))
+
+# Process ERRATA_N2_2025414 flag
+$(eval $(call assert_boolean,ERRATA_N2_2025414))
+$(eval $(call add_define,ERRATA_N2_2025414))
+
+# Process ERRATA_N2_2189731 flag
+$(eval $(call assert_boolean,ERRATA_N2_2189731))
+$(eval $(call add_define,ERRATA_N2_2189731))
+
+# Process ERRATA_N2_2138956 flag
+$(eval $(call assert_boolean,ERRATA_N2_2138956))
+$(eval $(call add_define,ERRATA_N2_2138956))
+
+# Process ERRATA_N2_2138953 flag
+$(eval $(call assert_boolean,ERRATA_N2_2138953))
+$(eval $(call add_define,ERRATA_N2_2138953))
+
+# Process ERRATA_A710_2055002 flag
+$(eval $(call assert_boolean,ERRATA_A710_2055002))
+$(eval $(call add_define,ERRATA_A710_2055002))
+
+# Process ERRATA_A710_2017096 flag
+$(eval $(call assert_boolean,ERRATA_A710_2017096))
+$(eval $(call add_define,ERRATA_A710_2017096))
+
# Process ERRATA_DSU_798953 flag
$(eval $(call assert_boolean,ERRATA_DSU_798953))
$(eval $(call add_define,ERRATA_DSU_798953))
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 81d793b..3ef378c 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -16,6 +16,8 @@
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/extensions/amu.h>
+#include <lib/extensions/sys_reg_trace.h>
+#include <lib/extensions/trf.h>
#include <lib/utils.h>
/*******************************************************************************
@@ -136,6 +138,14 @@
#if ENABLE_AMU
amu_enable(el2_unused);
#endif
+
+#if ENABLE_SYS_REG_TRACE_FOR_NS
+ sys_reg_trace_enable();
+#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
+
+#if ENABLE_TRF_FOR_NS
+ trf_enable();
+#endif /* ENABLE_TRF_FOR_NS */
#endif
}
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 40e7ddf..e270ad0 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -193,6 +193,11 @@
str x13, [x0, #CTX_SCXTNUM_EL2]
#endif
+#if ENABLE_FEAT_HCX
+ mrs x14, hcrx_el2
+ str x14, [x0, #CTX_HCRX_EL2]
+#endif
+
ret
endfunc el2_sysregs_context_save
@@ -362,6 +367,11 @@
msr scxtnum_el2, x13
#endif
+#if ENABLE_FEAT_HCX
+ ldr x14, [x0, #CTX_HCRX_EL2]
+ msr hcrx_el2, x14
+#endif
+
ret
endfunc el2_sysregs_context_restore
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 7c6f953..08022d4 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -22,6 +22,9 @@
#include <lib/extensions/mpam.h>
#include <lib/extensions/spe.h>
#include <lib/extensions/sve.h>
+#include <lib/extensions/sys_reg_trace.h>
+#include <lib/extensions/trbe.h>
+#include <lib/extensions/trf.h>
#include <lib/extensions/twed.h>
#include <lib/utils.h>
@@ -109,6 +112,14 @@
if (EP_GET_ST(ep->h.attr) != 0U)
scr_el3 |= SCR_ST_BIT;
+ /*
+ * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting
+ * SCR_EL3.HXEn.
+ */
+#if ENABLE_FEAT_HCX
+ scr_el3 |= SCR_HXEn_BIT;
+#endif
+
#if RAS_TRAP_LOWER_EL_ERR_ACCESS
/*
* SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
@@ -348,6 +359,19 @@
#if ENABLE_MPAM_FOR_LOWER_ELS
mpam_enable(el2_unused);
#endif
+
+#if ENABLE_TRBE_FOR_NS
+ trbe_enable();
+#endif /* ENABLE_TRBE_FOR_NS */
+
+#if ENABLE_SYS_REG_TRACE_FOR_NS
+ sys_reg_trace_enable(ctx);
+#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
+
+#if ENABLE_TRF_FOR_NS
+ trf_enable();
+#endif /* ENABLE_TRF_FOR_NS */
+
#endif
}
@@ -457,6 +481,8 @@
* CPTR_EL2.TTA: Set to zero so that Non-secure System
* register accesses to the trace registers from both
* Execution states do not trap to EL2.
+ * If PE trace unit System registers are not implemented
+ * then this bit is reserved, and must be set to zero.
*
* CPTR_EL2.TFP: Set to zero so that Non-secure accesses
* to SIMD and floating-point functionality from both
@@ -565,6 +591,11 @@
*
* MDCR_EL2.HPMN: Set to value of PMCR_EL0.N which is the
* architecturally-defined reset value.
+ *
+ * MDCR_EL2.E2TB: Set to zero so that the trace Buffer
+ * owning exception level is NS-EL1 and, tracing is
+ * prohibited at NS-EL2. These bits are RES0 when
+ * FEAT_TRBE is not implemented.
*/
mdcr_el2 = ((MDCR_EL2_RESET_VAL | MDCR_EL2_HLP |
MDCR_EL2_HPMD) |
@@ -574,7 +605,8 @@
MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT |
MDCR_EL2_TDA_BIT | MDCR_EL2_TDE_BIT |
MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT |
- MDCR_EL2_TPMCR_BIT);
+ MDCR_EL2_TPMCR_BIT |
+ MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1));
write_mdcr_el2(mdcr_el2);
diff --git a/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
new file mode 100644
index 0000000..89b8029
--- /dev/null
+++ b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/extensions/sys_reg_trace.h>
+
+static bool sys_reg_trace_supported(void)
+{
+ uint32_t features;
+
+ features = read_id_dfr0() >> ID_DFR0_COPTRC_SHIFT;
+ return ((features & ID_DFR0_COPTRC_MASK) ==
+ ID_DFR0_COPTRC_SUPPORTED);
+}
+
+void sys_reg_trace_enable(void)
+{
+ uint32_t val;
+
+ if (sys_reg_trace_supported()) {
+ /*
+ * NSACR.NSTRCDIS = b0
+ * enable NS system register access to implemented trace
+ * registers.
+ */
+ val = read_nsacr();
+ val &= ~NSTRCDIS_BIT;
+ write_nsacr(val);
+ }
+}
diff --git a/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
new file mode 100644
index 0000000..960d698
--- /dev/null
+++ b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/extensions/sys_reg_trace.h>
+
+static bool sys_reg_trace_supported(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEVER_SHIFT;
+ return ((features & ID_AA64DFR0_TRACEVER_MASK) ==
+ ID_AA64DFR0_TRACEVER_SUPPORTED);
+}
+
+void sys_reg_trace_enable(cpu_context_t *ctx)
+{
+ uint64_t val;
+
+ if (sys_reg_trace_supported()) {
+ /* Retrieve CPTR_EL3 value from the given context 'ctx',
+ * and update CPTR_EL3.TTA bit to 0.
+ * This function is called while switching context to NS to
+ * allow system trace register access to NS-EL2 and NS-EL1
+ * when NS-EL2 is implemented but not used.
+ */
+ val = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
+ val &= ~TTA_BIT;
+ write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, val);
+ }
+}
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
new file mode 100644
index 0000000..9f754d5
--- /dev/null
+++ b/lib/extensions/trbe/trbe.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/el3_runtime/pubsub.h>
+#include <lib/extensions/trbe.h>
+
+static void tsb_csync(void)
+{
+ /*
+ * The assembler does not yet understand the tsb csync mnemonic
+ * so use the equivalent hint instruction.
+ */
+ __asm__ volatile("hint #18");
+}
+
+static bool trbe_supported(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT;
+ return ((features & ID_AA64DFR0_TRACEBUFFER_MASK) ==
+ ID_AA64DFR0_TRACEBUFFER_SUPPORTED);
+}
+
+void trbe_enable(void)
+{
+ uint64_t val;
+
+ if (trbe_supported()) {
+ /*
+ * MDCR_EL3.NSTB = 0b11
+ * Allow access of trace buffer control registers from NS-EL1
+ * and NS-EL2, tracing is prohibited in Secure and Realm state
+ * (if implemented).
+ */
+ val = read_mdcr_el3();
+ val |= MDCR_NSTB(MDCR_NSTB_EL1);
+ write_mdcr_el3(val);
+ }
+}
+
+static void *trbe_drain_trace_buffers_hook(const void *arg __unused)
+{
+ if (trbe_supported()) {
+ /*
+ * Before switching from normal world to secure world
+ * the trace buffers need to be drained out to memory. This is
+ * required to avoid an invalid memory access when TTBR is switched
+ * for entry to S-EL1.
+ */
+ tsb_csync();
+ dsbnsh();
+ }
+
+ return (void *)0;
+}
+
+SUBSCRIBE_TO_EVENT(cm_entering_secure_world, trbe_drain_trace_buffers_hook);
diff --git a/lib/extensions/trf/aarch32/trf.c b/lib/extensions/trf/aarch32/trf.c
new file mode 100644
index 0000000..834092d
--- /dev/null
+++ b/lib/extensions/trf/aarch32/trf.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/extensions/trf.h>
+
+static bool trf_supported(void)
+{
+ uint32_t features;
+
+ features = read_id_dfr0() >> ID_DFR0_TRACEFILT_SHIFT;
+ return ((features & ID_DFR0_TRACEFILT_MASK) ==
+ ID_DFR0_TRACEFILT_SUPPORTED);
+}
+
+void trf_enable(void)
+{
+ uint32_t val;
+
+ if (trf_supported()) {
+ /*
+ * Allow access of trace filter control registers from
+ * non-monitor mode
+ */
+ val = read_sdcr();
+ val &= ~SDCR_TTRF_BIT;
+ write_sdcr(val);
+ }
+}
diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c
new file mode 100644
index 0000000..1da5dce
--- /dev/null
+++ b/lib/extensions/trf/aarch64/trf.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/extensions/trf.h>
+
+static bool trf_supported(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT;
+ return ((features & ID_AA64DFR0_TRACEFILT_MASK) ==
+ ID_AA64DFR0_TRACEFILT_SUPPORTED);
+}
+
+void trf_enable(void)
+{
+ uint64_t val;
+
+ if (trf_supported()) {
+ /*
+ * MDCR_EL3.TTRF = b0
+ * Allow access of trace filter control registers from NS-EL2
+ * and NS-EL1 when NS-EL2 is implemented but not used
+ */
+ val = read_mdcr_el3();
+ val &= ~MDCR_TTRF_BIT;
+ write_mdcr_el3(val);
+ }
+}
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 0ad1082..d090b38 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -47,25 +47,24 @@
/*******************************************************************************
* Check if it is a valid tee header
- * Return 1 if valid
- * Return 0 if invalid
+ * Return true if valid
+ * Return false if invalid
******************************************************************************/
-static inline int tee_validate_header(optee_header_t *header)
+static bool tee_validate_header(optee_header_t *header)
{
- int valid = 0;
-
if ((header->magic == TEE_MAGIC_NUM_OPTEE) &&
(header->version == 2u) &&
(header->nb_images > 0u) &&
(header->nb_images <= OPTEE_MAX_NUM_IMAGES)) {
- valid = 1;
+ return true;
}
- else {
- WARN("Not a known TEE, use default loading options.\n");
- }
+ return false;
+}
- return valid;
+bool optee_header_is_valid(uintptr_t header_base)
+{
+ return tee_validate_header((optee_header_t *)header_base);
}
/*******************************************************************************
diff --git a/lib/xlat_mpu/aarch64/enable_mpu.S b/lib/xlat_mpu/aarch64/enable_mpu.S
new file mode 100644
index 0000000..3791f2d
--- /dev/null
+++ b/lib/xlat_mpu/aarch64/enable_mpu.S
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+
+ .global enable_mpu_direct_el2
+
+ /* void enable_mmu_direct_el2(unsigned int flags) */
+func enable_mpu_direct_el2
+#if ENABLE_ASSERTIONS
+ mrs x1, sctlr_el2
+ tst x1, #SCTLR_M_BIT
+ ASM_ASSERT(eq)
+#endif
+ mov x7, x0
+ adrp x0, mmu_cfg_params
+ add x0, x0, :lo12:mmu_cfg_params
+
+ /* (MAIRs are already set up) */
+
+ /* TCR */
+ ldr x2, [x0, #(MMU_CFG_TCR << 3)]
+ msr tcr_el2, x2
+
+ /*
+ * Ensure all translation table writes have drained into memory, the TLB
+ * invalidation is complete, and translation register writes are
+ * committed before enabling the MMU
+ */
+ dsb ish
+ isb
+
+ /* Set and clear required fields of SCTLR */
+ mrs x4, sctlr_el2
+ mov_imm x5, SCTLR_WXN_BIT | SCTLR_C_BIT | SCTLR_M_BIT
+ orr x4, x4, x5
+
+ /* Additionally, amend SCTLR fields based on flags */
+ bic x5, x4, #SCTLR_C_BIT
+ tst x7, #DISABLE_DCACHE
+ csel x4, x5, x4, ne
+
+ msr sctlr_el2, x4
+ isb
+
+ ret
+endfunc enable_mpu_direct_el2
diff --git a/lib/xlat_mpu/aarch64/xlat_mpu_arch.c b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
new file mode 100644
index 0000000..5068eb8
--- /dev/null
+++ b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "../xlat_mpu_private.h"
+#include <arch.h>
+#include <arch_features.h>
+#include <lib/cassert.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <fvp_r_arch_helpers.h>
+
+#warning "xlat_mpu library is currently experimental and its API may change in future."
+
+#if ENABLE_ASSERTIONS
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+ uintptr_t ret;
+
+ if (is_armv8_4_ttst_present()) {
+ ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
+ } else {
+ ret = MIN_VIRT_ADDR_SPACE_SIZE;
+ }
+ return ret;
+}
+#endif /* ENABLE_ASSERTIONS*/
+
+bool is_mpu_enabled_ctx(const xlat_ctx_t *ctx)
+{
+ if (ctx->xlat_regime == EL1_EL0_REGIME) {
+ assert(xlat_arch_current_el() >= 1U);
+ return (read_sctlr_el1() & SCTLR_M_BIT) != 0U;
+ } else {
+ assert(xlat_arch_current_el() >= 2U);
+ return (read_sctlr_el2() & SCTLR_M_BIT) != 0U;
+ }
+}
+
+bool is_dcache_enabled(void)
+{
+ unsigned int el = get_current_el();
+
+ if (el == 1U) {
+ return (read_sctlr_el1() & SCTLR_C_BIT) != 0U;
+ } else { /* must be EL2 */
+ return (read_sctlr_el2() & SCTLR_C_BIT) != 0U;
+ }
+}
+
+unsigned int xlat_arch_current_el(void)
+{
+ unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
+
+ assert(el > 0U);
+
+ return el;
+}
+
diff --git a/lib/xlat_mpu/ro_xlat_mpu.mk b/lib/xlat_mpu/ro_xlat_mpu.mk
new file mode 100644
index 0000000..23f1d46
--- /dev/null
+++ b/lib/xlat_mpu/ro_xlat_mpu.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2021, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${USE_DEBUGFS}, 1)
+ $(error "Debugfs requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+endif
+
+ifeq (${ARCH},aarch32)
+ $(error "The xlat_mpu library does not currently support AArch32.")
+endif
diff --git a/lib/xlat_mpu/xlat_mpu.mk b/lib/xlat_mpu/xlat_mpu.mk
new file mode 100644
index 0000000..041b91c
--- /dev/null
+++ b/lib/xlat_mpu/xlat_mpu.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+XLAT_MPU_LIB_V1_SRCS := $(addprefix lib/xlat_mpu/, \
+ ${ARCH}/enable_mpu.S \
+ ${ARCH}/xlat_mpu_arch.c \
+ xlat_mpu_context.c \
+ xlat_mpu_core.c \
+ xlat_mpu_utils.c)
+
+XLAT_MPU_LIB_V1 := 1
+$(eval $(call add_define,XLAT_MPU_LIB_V1))
+
+ifeq (${ALLOW_XLAT_MPU}, 1)
+ include lib/xlat_mpu_v2/ro_xlat_mpu.mk
+endif
diff --git a/lib/xlat_mpu/xlat_mpu_context.c b/lib/xlat_mpu/xlat_mpu_context.c
new file mode 100644
index 0000000..28c463b
--- /dev/null
+++ b/lib/xlat_mpu/xlat_mpu_context.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+
+#include "lib/xlat_mpu/xlat_mpu.h"
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include "xlat_mpu_private.h"
+
+#include <fvp_r_arch_helpers.h>
+#include <platform_def.h>
+
+#warning "xlat_mpu library is currently experimental and its API may change in future."
+
+
+/*
+ * MMU configuration register values for the active translation context. Used
+ * from the MMU assembly helpers.
+ */
+uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
+
+/*
+ * Allocate and initialise the default translation context for the BL image
+ * currently executing.
+ */
+REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
+ PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);
+
+void mmap_add(const mmap_region_t *mm)
+{
+ mmap_add_ctx(&tf_xlat_ctx, mm);
+}
+
+void __init init_xlat_tables(void)
+{
+ assert(tf_xlat_ctx.xlat_regime == EL_REGIME_INVALID);
+
+ unsigned int current_el = xlat_arch_current_el();
+
+ if (current_el == 1U) {
+ tf_xlat_ctx.xlat_regime = EL1_EL0_REGIME;
+ } else {
+ assert(current_el == 2U);
+ tf_xlat_ctx.xlat_regime = EL2_REGIME;
+ }
+ /* Note: If EL3 is supported in future v8-R64, add EL3 assignment */
+ init_xlat_tables_ctx(&tf_xlat_ctx);
+}
+
+int xlat_get_mem_attributes(uintptr_t base_va, uint32_t *attr)
+{
+ return xlat_get_mem_attributes_ctx(&tf_xlat_ctx, base_va, attr);
+}
+
+void enable_mpu_el2(unsigned int flags)
+{
+ /* EL2 is strictly MPU on v8-R64, so no need for setup_mpu_cfg() */
+ enable_mpu_direct_el2(flags);
+}
diff --git a/lib/xlat_mpu/xlat_mpu_core.c b/lib/xlat_mpu/xlat_mpu_core.c
new file mode 100644
index 0000000..6b4b0c2
--- /dev/null
+++ b/lib/xlat_mpu/xlat_mpu_core.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <arch_features.h>
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include "xlat_mpu_private.h"
+
+#include <fvp_r_arch_helpers.h>
+#include <platform_def.h>
+
+#warning "xlat_mpu library is currently experimental and its API may change in future."
+
+
+/* Helper function that cleans the data cache only if it is enabled. */
+static inline __attribute__((unused))
+ void xlat_clean_dcache_range(uintptr_t addr, size_t size)
+{
+ if (is_dcache_enabled()) {
+ clean_dcache_range(addr, size);
+ }
+}
+
+
+
+/* Calculate region-attributes byte for PRBAR part of MPU-region descriptor: */
+uint64_t prbar_attr_value(uint32_t attr)
+{
+ uint64_t retValue = UL(0);
+ uint64_t extract; /* temp var holding bit extracted from attr */
+
+ /* Extract and stuff SH: */
+ extract = (uint64_t) ((attr >> MT_SHAREABILITY_SHIFT)
+ & MT_SHAREABILITY_MASK);
+ retValue |= (extract << PRBAR_SH_SHIFT);
+
+ /* Extract and stuff AP: */
+ extract = (uint64_t) ((attr >> MT_PERM_SHIFT) & MT_PERM_MASK);
+ if (extract == 0U) {
+ retValue |= (UL(2) << PRBAR_AP_SHIFT);
+ } else /* extract == 1 */ {
+ retValue |= (UL(0) << PRBAR_AP_SHIFT);
+ }
+
+ /* Extract and stuff XN: */
+ extract = (uint64_t) ((attr >> MT_EXECUTE_SHIFT) & MT_EXECUTE_MASK);
+ retValue |= (extract << PRBAR_XN_SHIFT);
+ /* However, also don't execute in peripheral space: */
+ extract = (uint64_t) ((attr >> MT_TYPE_SHIFT) & MT_TYPE_MASK);
+ if (extract == 0U) {
+ retValue |= (UL(1) << PRBAR_XN_SHIFT);
+ }
+ return retValue;
+}
+
+/* Calculate region-attributes byte for PRLAR part of MPU-region descriptor: */
+uint64_t prlar_attr_value(uint32_t attr)
+{
+ uint64_t retValue = UL(0);
+ uint64_t extract; /* temp var holding bit extracted from attr */
+
+ /* Extract and stuff AttrIndx: */
+ extract = (uint64_t) ((attr >> MT_TYPE_SHIFT)
+ & MT_TYPE_MASK);
+ switch (extract) {
+ case UL(0):
+ retValue |= (UL(1) << PRLAR_ATTR_SHIFT);
+ break;
+ case UL(2):
+ /* 0, so OR in nothing */
+ break;
+ case UL(3):
+ retValue |= (UL(2) << PRLAR_ATTR_SHIFT);
+ break;
+ default:
+ retValue |= (extract << PRLAR_ATTR_SHIFT);
+ break;
+ }
+
+ /* Stuff EN: */
+ retValue |= (UL(1) << PRLAR_EN_SHIFT);
+
+ /* Force NS to 0 (Secure); v8-R64 only supports Secure: */
+ extract = ~(1U << PRLAR_NS_SHIFT);
+ retValue &= extract;
+
+ return retValue;
+}
+
+/*
+ * Function that writes an MPU "translation" into the MPU registers. If not
+ * possible (e.g., if no more MPU regions available) boot is aborted.
+ */
+static void mpu_map_region(mmap_region_t *mm)
+{
+ uint64_t prenr_el2_value = 0UL;
+ uint64_t prbar_attrs = 0UL;
+ uint64_t prlar_attrs = 0UL;
+ int region_to_use = 0;
+
+ /* If all MPU regions in use, then abort boot: */
+ prenr_el2_value = read_prenr_el2();
+ assert(prenr_el2_value != 0xffffffff);
+
+ /* Find and select first-available MPU region (PRENR has an enable bit
+ * for each MPU region, 1 for in-use or 0 for unused):
+ */
+ for (region_to_use = 0; region_to_use < N_MPU_REGIONS;
+ region_to_use++) {
+ if (((prenr_el2_value >> region_to_use) & 1) == 0) {
+ break;
+ }
+ }
+ write_prselr_el2((uint64_t) (region_to_use));
+ isb();
+
+ /* Set base and limit addresses: */
+ write_prbar_el2(mm->base_pa & PRBAR_PRLAR_ADDR_MASK);
+ write_prlar_el2((mm->base_pa + mm->size - 1UL)
+ & PRBAR_PRLAR_ADDR_MASK);
+ dsbsy();
+ isb();
+
+ /* Set attributes: */
+ prbar_attrs = prbar_attr_value(mm->attr);
+ write_prbar_el2(read_prbar_el2() | prbar_attrs);
+ prlar_attrs = prlar_attr_value(mm->attr);
+ write_prlar_el2(read_prlar_el2() | prlar_attrs);
+ dsbsy();
+ isb();
+
+ /* Mark this MPU region as used: */
+ prenr_el2_value |= (1 << region_to_use);
+ write_prenr_el2(prenr_el2_value);
+ isb();
+}
+
+/*
+ * Function that verifies that a region can be mapped.
+ * Returns:
+ * 0: Success, the mapping is allowed.
+ * EINVAL: Invalid values were used as arguments.
+ * ERANGE: The memory limits were surpassed.
+ * ENOMEM: There is not enough memory in the mmap array.
+ * EPERM: Region overlaps another one in an invalid way.
+ */
+static int mmap_add_region_check(const xlat_ctx_t *ctx, const mmap_region_t *mm)
+{
+ unsigned long long base_pa = mm->base_pa;
+ uintptr_t base_va = mm->base_va;
+ size_t size = mm->size;
+
+ unsigned long long end_pa = base_pa + size - 1U;
+ uintptr_t end_va = base_va + size - 1U;
+
+ if (base_pa != base_va) {
+ return -EINVAL; /* MPU does not perform address translation */
+ }
+ if ((base_pa % 64ULL) != 0ULL) {
+ return -EINVAL; /* MPU requires 64-byte alignment */
+ }
+ /* Check for overflows */
+ if ((base_pa > end_pa) || (base_va > end_va)) {
+ return -ERANGE;
+ }
+ if (end_pa > ctx->pa_max_address) {
+ return -ERANGE;
+ }
+ /* Check that there is space in the ctx->mmap array */
+ if (ctx->mmap[ctx->mmap_num - 1].size != 0U) {
+ return -ENOMEM;
+ }
+ /* Check for PAs and VAs overlaps with all other regions */
+ for (const mmap_region_t *mm_cursor = ctx->mmap;
+ mm_cursor->size != 0U; ++mm_cursor) {
+
+ uintptr_t mm_cursor_end_va =
+ mm_cursor->base_va + mm_cursor->size - 1U;
+
+ /*
+ * Check if one of the regions is completely inside the other
+ * one.
+ */
+ bool fully_overlapped_va =
+ ((base_va >= mm_cursor->base_va) &&
+ (end_va <= mm_cursor_end_va)) ||
+ ((mm_cursor->base_va >= base_va) &&
+ (mm_cursor_end_va <= end_va));
+
+ /*
+ * Full VA overlaps are only allowed if both regions are
+ * identity mapped (zero offset) or have the same VA to PA
+ * offset. Also, make sure that it's not the exact same area.
+ * This can only be done with static regions.
+ */
+ if (fully_overlapped_va) {
+
+#if PLAT_XLAT_TABLES_DYNAMIC
+ if (((mm->attr & MT_DYNAMIC) != 0U) ||
+ ((mm_cursor->attr & MT_DYNAMIC) != 0U)) {
+ return -EPERM;
+ }
+#endif /* PLAT_XLAT_TABLES_DYNAMIC */
+ if ((mm_cursor->base_va - mm_cursor->base_pa)
+ != (base_va - base_pa)) {
+ return -EPERM;
+ }
+ if ((base_va == mm_cursor->base_va) &&
+ (size == mm_cursor->size)) {
+ return -EPERM;
+ }
+ } else {
+ /*
+ * If the regions do not have fully overlapping VAs,
+ * then they must have fully separated VAs and PAs.
+ * Partial overlaps are not allowed
+ */
+
+ unsigned long long mm_cursor_end_pa =
+ mm_cursor->base_pa + mm_cursor->size - 1U;
+
+ bool separated_pa = (end_pa < mm_cursor->base_pa) ||
+ (base_pa > mm_cursor_end_pa);
+ bool separated_va = (end_va < mm_cursor->base_va) ||
+ (base_va > mm_cursor_end_va);
+
+ if (!separated_va || !separated_pa) {
+ return -EPERM;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
+{
+ mmap_region_t *mm_cursor = ctx->mmap, *mm_destination;
+ const mmap_region_t *mm_end = ctx->mmap + ctx->mmap_num;
+ const mmap_region_t *mm_last;
+ unsigned long long end_pa = mm->base_pa + mm->size - 1U;
+ uintptr_t end_va = mm->base_va + mm->size - 1U;
+ int ret;
+
+ /* Ignore empty regions */
+ if (mm->size == 0U) {
+ return;
+ }
+
+ /* Static regions must be added before initializing the xlat tables. */
+ assert(!ctx->initialized);
+
+ ret = mmap_add_region_check(ctx, mm);
+ if (ret != 0) {
+ ERROR("mmap_add_region_check() failed. error %d\n", ret);
+ assert(false);
+ return;
+ }
+
+ /*
+ * Find the last entry marker in the mmap
+ */
+ mm_last = ctx->mmap;
+ while ((mm_last->size != 0U) && (mm_last < mm_end)) {
+ ++mm_last;
+ }
+
+ /*
+ * Check if we have enough space in the memory mapping table.
+ * This shouldn't happen as we have checked in mmap_add_region_check
+ * that there is free space.
+ */
+ assert(mm_last->size == 0U);
+
+ /* Make room for new region by moving other regions up by one place */
+ mm_destination = mm_cursor + 1;
+ (void)memmove(mm_destination, mm_cursor,
+ (uintptr_t)mm_last - (uintptr_t)mm_cursor);
+
+ /*
+ * Check we haven't lost the empty sentinel from the end of the array.
+ * This shouldn't happen as we have checked in mmap_add_region_check
+ * that there is free space.
+ */
+ assert(mm_end->size == 0U);
+
+ *mm_cursor = *mm;
+
+ if (end_pa > ctx->max_pa) {
+ ctx->max_pa = end_pa;
+ }
+ if (end_va > ctx->max_va) {
+ ctx->max_va = end_va;
+ }
+}
+
+void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
+{
+ const mmap_region_t *mm_cursor = mm;
+
+ while (mm_cursor->granularity != 0U) {
+ mmap_add_region_ctx(ctx, mm_cursor);
+ mm_cursor++;
+ }
+}
+
+void __init init_xlat_tables_ctx(xlat_ctx_t *ctx)
+{
+ uint64_t mair = UL(0);
+
+ assert(ctx != NULL);
+ assert(!ctx->initialized);
+ assert((ctx->xlat_regime == EL2_REGIME) ||
+ (ctx->xlat_regime == EL1_EL0_REGIME));
+ /* Note: Add EL3_REGIME if EL3 is supported in future v8-R64 cores. */
+ assert(!is_mpu_enabled_ctx(ctx));
+
+ mmap_region_t *mm = ctx->mmap;
+
+ assert(ctx->va_max_address >=
+ (xlat_get_min_virt_addr_space_size() - 1U));
+ assert(ctx->va_max_address <= (MAX_VIRT_ADDR_SPACE_SIZE - 1U));
+ assert(IS_POWER_OF_TWO(ctx->va_max_address + 1U));
+
+ xlat_mmap_print(mm);
+
+ /* All tables must be zeroed before mapping any region. */
+
+ for (unsigned int i = 0U; i < ctx->base_table_entries; i++)
+ ctx->base_table[i] = INVALID_DESC;
+
+ /* Also mark all MPU regions as invalid in the MPU hardware itself: */
+ write_prenr_el2(0);
+ /* Sufficient for current, max-32-region implementations. */
+ dsbsy();
+ isb();
+ while (mm->size != 0U) {
+ if (read_prenr_el2() == ALL_MPU_EL2_REGIONS_USED) {
+ ERROR("Not enough MPU regions to map region:\n"
+ " VA:0x%lx PA:0x%llx size:0x%zx attr:0x%x\n",
+ mm->base_va, mm->base_pa, mm->size, mm->attr);
+ panic();
+ } else {
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ xlat_clean_dcache_range((uintptr_t)mm->base_va,
+ mm->size);
+#endif
+ mpu_map_region(mm);
+ }
+ mm++;
+ }
+
+ ctx->initialized = true;
+
+ xlat_tables_print(ctx);
+
+ /* Set attributes in the right indices of the MAIR */
+ mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
+ mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,
+ ATTR_IWBWA_OWBWA_NTR_INDEX);
+ mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE,
+ ATTR_NON_CACHEABLE_INDEX);
+ write_mair_el2(mair);
+ dsbsy();
+ isb();
+}
+
+/*
+ * Function to wipe clean and disable all MPU regions. This function expects
+ * that the MPU has already been turned off, and caching concerns addressed,
+ * but it nevertheless also explicitly turns off the MPU.
+ */
+void clear_all_mpu_regions(void)
+{
+ uint64_t sctlr_el2_value = 0UL;
+ uint64_t region_n = 0UL;
+
+ /*
+ * MPU should already be disabled, but explicitly disable it
+ * nevertheless:
+ */
+ sctlr_el2_value = read_sctlr_el2() & ~(1UL);
+ write_sctlr_el2(sctlr_el2_value);
+
+ /* Disable all regions: */
+ write_prenr_el2(0UL);
+
+ /* Sequence through all regions, zeroing them out and turning off: */
+ for (region_n = 0UL; region_n < N_MPU_REGIONS; region_n++) {
+ write_prselr_el2(region_n);
+ isb();
+ write_prbar_el2((uint64_t) 0);
+ write_prlar_el2((uint64_t) 0);
+ dsbsy();
+ isb();
+ }
+}
diff --git a/lib/xlat_mpu/xlat_mpu_private.h b/lib/xlat_mpu/xlat_mpu_private.h
new file mode 100644
index 0000000..e0e479d
--- /dev/null
+++ b/lib/xlat_mpu/xlat_mpu_private.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef XLAT_MPU_PRIVATE_H
+#define XLAT_MPU_PRIVATE_H
+
+#include <stdbool.h>
+
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <platform_def.h>
+
+#if PLAT_XLAT_TABLES_DYNAMIC
+/*
+ * Private shifts and masks to access fields of an mmap attribute
+ */
+/* Dynamic or static */
+#define MT_DYN_SHIFT U(31)
+
+/*
+ * Memory mapping private attributes
+ *
+ * Private attributes not exposed in the public header.
+ */
+
+#endif /* PLAT_XLAT_TABLES_DYNAMIC */
+
+/* Calculate region-attributes byte for PRBAR part of MPU-region descriptor: */
+uint64_t prbar_attr_value(uint32_t attr);
+/* Calculate region-attributes byte for PRLAR part of MPU-region descriptor: */
+uint64_t prlar_attr_value(uint32_t attr);
+/* Calculates the attr value for a given PRBAR and PRLAR entry value: */
+uint32_t region_attr(uint64_t prbar_attr, uint64_t prlar_attr);
+
+#define PRBAR_PRLAR_ADDR_MASK UL(0xffffffffffc0)
+ /* mask for PRBAR & PRLAR MPU-region field */
+/* MPU region attribute bit fields: */
+#define PRBAR_SH_SHIFT UL(4)
+#define PRBAR_SH_MASK UL(0x3)
+#define PRBAR_AP_SHIFT UL(2)
+#define PRBAR_AP_MASK UL(0x3)
+#define PRBAR_XN_SHIFT UL(1)
+#define PRBAR_XN_MASK UL(0x3)
+#define PRLAR_NS_SHIFT UL(4)
+#define PRLAR_NS_MASK UL(0x3)
+#define PRBAR_ATTR_SHIFT UL(0)
+#define PRBAR_ATTR_MASK UL(0x3f)
+#define PRLAR_ATTR_SHIFT UL(1)
+#define PRLAR_ATTR_MASK UL(0x7)
+#define PRLAR_EN_SHIFT UL(0)
+#define PRLAR_EN_MASK UL(0x1)
+/* Aspects of the source attributes not defined elsewhere: */
+#define MT_PERM_MASK UL(0x1)
+#define MT_SEC_MASK UL(0x1)
+#define MT_EXECUTE_MASK UL(0x3)
+#define MT_TYPE_SHIFT UL(0)
+
+extern uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
+
+/*
+ * Return the execute-never mask that will prevent instruction fetch at the
+ * given translation regime.
+ */
+uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime);
+
+/* Print VA, PA, size and attributes of all regions in the mmap array. */
+void xlat_mmap_print(const mmap_region_t *mmap);
+
+/*
+ * Print the current state of the translation tables by reading them from
+ * memory.
+ */
+void xlat_tables_print(xlat_ctx_t *ctx);
+
+/*
+ * Returns a block/page table descriptor for the given level and attributes.
+ */
+uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
+ unsigned long long addr_pa, unsigned int level);
+
+/*
+ * Architecture-specific initialization code.
+ */
+
+/* Returns the current Exception Level. The returned EL must be 1 or higher. */
+unsigned int xlat_arch_current_el(void);
+
+/*
+ * Returns true if the MMU of the translation regime managed by the given
+ * xlat_ctx_t is enabled, false otherwise.
+ */
+bool is_mpu_enabled_ctx(const xlat_ctx_t *ctx);
+
+/*
+ * Returns minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void);
+
+#endif /* XLAT_MPU_PRIVATE_H */
diff --git a/lib/xlat_mpu/xlat_mpu_utils.c b/lib/xlat_mpu/xlat_mpu_utils.c
new file mode 100644
index 0000000..f305632
--- /dev/null
+++ b/lib/xlat_mpu/xlat_mpu_utils.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include "xlat_mpu_private.h"
+
+#include <fvp_r_arch_helpers.h>
+#include <platform_def.h>
+
+#warning "xlat_mpu library is currently experimental and its API may change in future."
+
+
+#if LOG_LEVEL < LOG_LEVEL_VERBOSE
+
+void xlat_mmap_print(__unused const mmap_region_t *mmap)
+{
+ /* Empty */
+}
+
+void xlat_tables_print(__unused xlat_ctx_t *ctx)
+{
+ /* Empty */
+}
+
+#else /* if LOG_LEVEL >= LOG_LEVEL_VERBOSE */
+
+static const char *invalid_descriptors_ommited =
+ "%s(%d invalid descriptors omitted)\n";
+
+void xlat_tables_print(xlat_ctx_t *ctx)
+{
+ const char *xlat_regime_str;
+ int used_page_tables;
+
+ if (ctx->xlat_regime == EL1_EL0_REGIME) {
+ xlat_regime_str = "1&0";
+ } else if (ctx->xlat_regime == EL2_REGIME) {
+ xlat_regime_str = "2";
+ } else {
+ assert(ctx->xlat_regime == EL3_REGIME);
+ xlat_regime_str = "3";
+ /* If no EL3 and EL3 tables generated, then need to know. */
+ }
+ VERBOSE("Translation tables state:\n");
+ VERBOSE(" Xlat regime: EL%s\n", xlat_regime_str);
+ VERBOSE(" Max allowed PA: 0x%llx\n", ctx->pa_max_address);
+ VERBOSE(" Max allowed VA: 0x%lx\n", ctx->va_max_address);
+ VERBOSE(" Max mapped PA: 0x%llx\n", ctx->max_pa);
+ VERBOSE(" Max mapped VA: 0x%lx\n", ctx->max_va);
+
+ VERBOSE(" Initial lookup level: %u\n", ctx->base_level);
+ VERBOSE(" Entries @initial lookup level: %u\n",
+ ctx->base_table_entries);
+
+ xlat_tables_print_internal(ctx, 0U, ctx->base_table,
+ ctx->base_table_entries, ctx->base_level);
+}
+
+#endif /* LOG_LEVEL >= LOG_LEVEL_VERBOSE */
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index c86412c..dc167e3 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -147,7 +147,7 @@
* exception level
******************************************************************************/
#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct) \
- void enable_mmu_el##_el(unsigned int flags) \
+ void enable_mmu_el##_el(unsigned int flags) \
{ \
uint64_t mair, tcr, ttbr; \
uint32_t sctlr; \
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index b69c670..a95ef07 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -203,8 +203,6 @@
assert(virtual_addr_space_size >=
xlat_get_min_virt_addr_space_size());
- assert(virtual_addr_space_size <=
- MAX_VIRT_ADDR_SPACE_SIZE);
assert(IS_POWER_OF_TWO(virtual_addr_space_size));
/*
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 72f84b5..8b350db 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -32,6 +32,9 @@
# Execute BL2 at EL3
BL2_AT_EL3 := 0
+# Only use SP packages if SP layout JSON is defined
+BL2_ENABLE_SP_LOAD := 0
+
# BL2 image is stored in XIP memory, for now, this option is only supported
# when BL2_AT_EL3 is 1.
BL2_IN_XIP_MEM := 0
@@ -121,6 +124,9 @@
# Use BRANCH_PROTECTION to enable PAUTH.
ENABLE_PAUTH := 0
+# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
+ENABLE_FEAT_HCX := 0
+
# By default BL31 encryption disabled
ENCRYPT_BL31 := 0
@@ -355,3 +361,24 @@
# Disable Firmware update support by default
PSA_FWU_SUPPORT := 0
+
+# By default, disable access of trace buffer control registers from NS
+# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_TRBE is implemented.
+# Note FEAT_TRBE is only supported on AArch64 - therefore do not enable in
+# AArch32.
+ifneq (${ARCH},aarch32)
+ ENABLE_TRBE_FOR_NS := 0
+else
+ override ENABLE_TRBE_FOR_NS := 0
+endif
+
+# By default, disable access of trace system registers from NS lower
+# ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
+# system register trace is implemented.
+ENABLE_SYS_REG_TRACE_FOR_NS := 0
+
+# By default, disable trace filter control registers access to NS
+# lower ELs, i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_TRF is implemented.
+ENABLE_TRF_FOR_NS := 0
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index f7cced4..293e854 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -68,8 +68,10 @@
# Add the BL2 CoT (image cert)
ifeq (${BL2_AT_EL3}, 0)
+ifneq (${PLAT},fvp_r)
$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
endif
+endif
# Add the SCP_BL2 CoT (key cert + img cert)
ifneq (${SCP_BL2},)
diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S
index d7cd008..b4bc7d8 100644
--- a/plat/arm/board/arm_fpga/build_axf.ld.S
+++ b/plat/arm/board/arm_fpga/build_axf.ld.S
@@ -17,6 +17,7 @@
INPUT(./bl31/bl31.elf)
INPUT(./rom_trampoline.o)
+INPUT(./kernel_trampoline.o)
TARGET(binary)
INPUT(./fdts/arm_fpga.dtb)
@@ -33,7 +34,6 @@
.bl31 (BL31_BASE): {
ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE is not page aligned");
*bl31.elf(.text* .data* .rodata* ro* .bss*)
- *bl31.elf(.stack)
}
.dtb (FPGA_PRELOADED_DTB_BASE): {
@@ -41,6 +41,12 @@
*arm_fpga.dtb
}
+ .kern_tramp (PRELOADED_BL33_BASE): {
+ *kernel_trampoline.o(.text*)
+ KEEP(*(.kern_tramp))
+ }
+
+ /DISCARD/ : { *(stacks) }
/DISCARD/ : { *(.debug_*) }
/DISCARD/ : { *(.note*) }
/DISCARD/ : { *(.comment*) }
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index 4a529c6..2b5ca4a 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -224,7 +224,7 @@
INFO("Adjusting GICR DT region to cover %u cores\n",
nr_cores);
err = fdt_adjust_gic_redist(fdt, nr_cores,
- 1U << GICR_PCPUBASE_SHIFT);
+ fpga_get_redist_size());
if (err < 0) {
ERROR("Error %d fixing up GIC DT node\n", err);
}
diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c
index bfc116b..4a97beb 100644
--- a/plat/arm/board/arm_fpga/fpga_gicv3.c
+++ b/plat/arm/board/arm_fpga/fpga_gicv3.c
@@ -8,6 +8,7 @@
#include <common/fdt_wrappers.h>
#include <drivers/arm/gicv3.h>
#include <drivers/arm/gic_common.h>
+#include <lib/mmio.h>
#include <libfdt.h>
#include <platform_def.h>
@@ -82,3 +83,11 @@
{
return gicv3_rdistif_get_number_frames(fpga_gicv3_driver_data.gicr_base);
}
+
+uintptr_t fpga_get_redist_size(void)
+{
+ uint64_t typer_val = mmio_read_64(fpga_gicv3_driver_data.gicr_base +
+ GICR_TYPER);
+
+ return gicv3_redist_size(typer_val);
+}
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
index 1ca241f..cc809c4 100644
--- a/plat/arm/board/arm_fpga/fpga_private.h
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -25,6 +25,7 @@
void fpga_pwr_gic_off(void);
unsigned int plat_fpga_calc_core_pos(uint32_t mpid);
unsigned int fpga_get_nr_gic_cores(void);
+uintptr_t fpga_get_redist_size(void);
#endif /* __ASSEMBLER__ */
diff --git a/plat/arm/board/arm_fpga/kernel_trampoline.S b/plat/arm/board/arm_fpga/kernel_trampoline.S
new file mode 100644
index 0000000..f4c08ef
--- /dev/null
+++ b/plat/arm/board/arm_fpga/kernel_trampoline.S
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * The traditional arm64 Linux kernel load address is 512KiB from the
+ * beginning of DRAM, caused by this having been the default value of the
+ * kernel's CONFIG_TEXT_OFFSET Kconfig value.
+ * However kernel version 5.8 changed the default offset (into a 2MB page)
+ * to 0, so TF-A's default assumption is no longer true. Fortunately the
+ * kernel got more relaxed about this offset at the same time, so it
+ * tolerates the wrong offset, but issues a warning:
+ * [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
+ *
+ * We cannot easily change the load address offset in TF-A to be 2MiB, because
+ * this would break older kernels - and they are not as forgiving in this
+ * respect.
+ *
+ * But we can allow users to load the kernel at the right offset, and
+ * offer this trampoline here to transition to this new load address.
+ * Any older kernels, or newer kernels misloaded, will overwrite this code
+ * here, so it does no harm in this case.
+ */
+
+#include <asm_macros.S>
+#include <common/bl_common.ld.h>
+
+.text
+.global _tramp_start
+
+_tramp_start:
+ adr x4, _tramp_start
+ orr x4, x4, #0x1fffff
+ add x4, x4, #1 /* align up to 2MB */
+ br x4
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index f80ea2f..1217425 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -89,6 +89,8 @@
# Allow detection of GIC-600
GICV3_SUPPORT_GIC600 := 1
+GIC_ENABLE_V4_EXTN := 1
+
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
@@ -116,10 +118,11 @@
${FPGA_GIC_SOURCES}
$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,31))
+$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,31))
$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,31))
-bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/build_axf.ld
+bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/kernel_trampoline.o ${BUILD_PLAT}/build_axf.ld
$(ECHO) " LD $@"
- $(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -o ${BUILD_PLAT}/bl31.axf
+ $(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -s -n -o ${BUILD_PLAT}/bl31.axf
all: bl31.axf
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 62ab27c..08d3c32 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -4,6 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <lib/libc/cdefs.h>
+
/dts-v1/;
/ {
@@ -74,6 +76,10 @@
secure-partitions {
compatible = "arm,sp";
+
+#ifdef ARM_BL2_SP_LIST_DTS
+ #include __XSTRING(ARM_BL2_SP_LIST_DTS)
+#else
#ifdef OPTEE_SP_FW_CONFIG
op-tee {
uuid = "486178e0-e7f8-11e3-bc5e-0002a5d5c51b";
@@ -104,6 +110,7 @@
owner = "Plat";
};
#endif
+#endif /* ARM_BL2_SP_LIST_DTS */
};
#if COT_DESC_IN_DTB
diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
index 07235b0..551efe6 100644
--- a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -16,7 +16,7 @@
/* Properties */
description = "op-tee";
ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
- uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>;
+ uuid = <0xe0786148 0xe311f8e7 0x02005ebc 0x1bc5d5a5>;
id = <1>;
execution-ctx-count = <8>;
exception-level = <2>; /* S-EL1 */
@@ -25,8 +25,9 @@
entrypoint-offset = <0x1000>;
xlat-granule = <0>; /* 4KiB */
boot-order = <0>;
- messaging-method = <3>; /* Direct messaging only */
- run-time-model = <1>; /* Run to completion */
+ messaging-method = <0x3>; /* Direct request/response supported. */
+ managed-exit;
+ run-time-model = <1>; /* SP pre-emptible. */
/* Boot protocol */
gp-register-num = <0x0>;
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 333d892..6b9d618 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -138,21 +138,37 @@
fvp_pwrc_clr_wen(mpidr);
}
-
/*******************************************************************************
* FVP handler called when a CPU is about to enter standby.
******************************************************************************/
static void fvp_cpu_standby(plat_local_state_t cpu_state)
{
+ u_register_t scr = read_scr_el3();
assert(cpu_state == ARM_LOCAL_STATE_RET);
/*
- * Enter standby state
- * dsb is good practice before using wfi to enter low power states
+ * Enable the Non-secure interrupt to wake the CPU.
+ * In GICv3 affinity routing mode, the Non-secure Group 1 interrupts
+ * use Physical FIQ at EL3 whereas in GICv2, Physical IRQ is used.
+ * Enabling both the bits works for both GICv2 mode and GICv3 affinity
+ * routing mode.
+ */
+ write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);
+ isb();
+
+ /*
+ * Enter standby state.
+ * dsb is good practice before using wfi to enter low power states.
*/
dsb();
wfi();
+
+ /*
+ * Restore SCR_EL3 to the original value, synchronisation of SCR_EL3
+ * is done by eret in el3_exit() to save some execution cycles.
+ */
+ write_scr_el3(scr);
}
/*******************************************************************************
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 3c70eed..73f09e5 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -138,7 +138,8 @@
lib/cpus/aarch64/cortex_demeter.S \
lib/cpus/aarch64/cortex_a65.S \
lib/cpus/aarch64/cortex_a65ae.S \
- lib/cpus/aarch64/cortex_a78c.S
+ lib/cpus/aarch64/cortex_a78c.S \
+ lib/cpus/aarch64/cortex_hayes.S
endif
# AArch64/AArch32 cores
FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \
@@ -378,3 +379,12 @@
# dynamically if TRUSTED_BOARD_BOOT is set.
DYN_DISABLE_AUTH := 1
endif
+
+# enable trace buffer control registers access to NS by default
+ENABLE_TRBE_FOR_NS := 1
+
+# enable trace system registers access to NS by default
+ENABLE_SYS_REG_TRACE_FOR_NS := 1
+
+# enable trace filter control registers access to NS by default
+ENABLE_TRF_FOR_NS := 1
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c
new file mode 100644
index 0000000..ae6af6c
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../../../../bl1/bl1_private.h"
+#include <arch.h>
+
+#include <fvp_r_arch_helpers.h>
+
+/*******************************************************************************
+ * Function that does the first bit of architectural setup that affects
+ * execution in the non-secure address space.
+ ******************************************************************************/
+void bl1_arch_setup(void)
+{
+ /* v8-R64 does not include SCRs. */
+}
+
+/*******************************************************************************
+ * Set the Secure EL1 required architectural state
+ ******************************************************************************/
+void bl1_arch_next_el_setup(void)
+{
+ u_register_t next_sctlr;
+
+ /* Use the same endianness than the current BL */
+ next_sctlr = (read_sctlr_el2() & SCTLR_EE_BIT);
+
+ /* Set SCTLR Secure EL1 */
+ next_sctlr |= SCTLR_EL1_RES1;
+
+ write_sctlr_el1(next_sctlr);
+}
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c
new file mode 100644
index 0000000..7ae853b
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include "../../../../bl1/bl1_private.h"
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+
+#include <plat/common/platform.h>
+
+
+void cm_prepare_el2_exit(uint32_t security_state);
+
+/* Following contains the cpu context pointers. */
+static void *bl1_cpu_context_ptr[2];
+
+void *cm_get_context(uint32_t security_state)
+{
+ assert(sec_state_is_valid(security_state));
+ return bl1_cpu_context_ptr[security_state];
+}
+
+void cm_set_context(void *context, uint32_t security_state)
+{
+ assert(sec_state_is_valid(security_state));
+ bl1_cpu_context_ptr[security_state] = context;
+}
+
+/*******************************************************************************
+ * This function prepares the context for Secure/Normal world images.
+ * Normal world images are transitioned to EL2(if supported) else EL1.
+ ******************************************************************************/
+void bl1_prepare_next_image(unsigned int image_id)
+{
+ /*
+ * Following array will be used for context management.
+ * There are 2 instances, for the Secure and Non-Secure contexts.
+ */
+ static cpu_context_t bl1_cpu_context[2];
+
+ unsigned int security_state, mode = MODE_EL1;
+ image_desc_t *desc;
+ entry_point_info_t *next_bl_ep;
+
+#if CTX_INCLUDE_AARCH32_REGS
+ /*
+ * Ensure that the build flag to save AArch32 system registers in CPU
+ * context is not set for AArch64-only platforms.
+ */
+ if (el_implemented(1) == EL_IMPL_A64ONLY) {
+ ERROR("EL1 supports AArch64-only. Please set build flag %s",
+ "CTX_INCLUDE_AARCH32_REGS = 0\n");
+ panic();
+ }
+#endif
+
+ /* Get the image descriptor. */
+ desc = bl1_plat_get_image_desc(image_id);
+ assert(desc != NULL);
+
+ /* Get the entry point info. */
+ next_bl_ep = &desc->ep_info;
+
+ /* Get the image security state. */
+ security_state = GET_SECURITY_STATE(next_bl_ep->h.attr);
+
+ /* Setup the Secure/Non-Secure context if not done already. */
+ if (cm_get_context(security_state) == NULL) {
+ cm_set_context(&bl1_cpu_context[security_state], security_state);
+ }
+ /* Prepare the SPSR for the next BL image. */
+ next_bl_ep->spsr = (uint32_t)SPSR_64((uint64_t) mode,
+ (uint64_t)MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+
+ /* Allow platform to make change */
+ bl1_plat_set_ep_info(image_id, next_bl_ep);
+
+ /* Indicate that image is in execution state. */
+ desc->state = IMAGE_STATE_EXECUTED;
+
+ print_entry_point_info(next_bl_ep);
+}
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S b/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S
new file mode 100644
index 0000000..19a685c
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <el2_common_macros.S>
+#include <lib/xlat_mpu/xlat_mpu.h>
+
+ .globl bl1_entrypoint
+ .globl bl1_run_next_image
+
+
+ /* -----------------------------------------------------
+ * bl1_entrypoint() is the entry point into the trusted
+ * firmware code when a cpu is released from warm or
+ * cold reset.
+ * -----------------------------------------------------
+ */
+
+func bl1_entrypoint
+ /* ---------------------------------------------------------------------
+ * If the reset address is programmable then bl1_entrypoint() is
+ * executed only on the cold boot path. Therefore, we can skip the warm
+ * boot mailbox mechanism.
+ * ---------------------------------------------------------------------
+ */
+ el2_entrypoint_common \
+ _init_sctlr=1 \
+ _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
+ _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
+ _init_memory=1 \
+ _init_c_runtime=1 \
+ _exception_vectors=bl1_exceptions \
+ _pie_fixup_size=0
+
+ /* --------------------------------------------------------------------
+ * Perform BL1 setup
+ * --------------------------------------------------------------------
+ */
+ bl bl1_setup
+
+#if ENABLE_PAUTH
+ /* --------------------------------------------------------------------
+ * Program APIAKey_EL1 and enable pointer authentication.
+ * --------------------------------------------------------------------
+ */
+ bl pauth_init_enable_el2
+#endif /* ENABLE_PAUTH */
+
+ /* --------------------------------------------------------------------
+ * Initialize platform and jump to our c-entry point
+ * for this type of reset.
+ * --------------------------------------------------------------------
+ */
+ bl bl1_main
+
+ /* ---------------------------------------------
+ * Should never reach this point.
+ * ---------------------------------------------
+ */
+ no_ret plat_panic_handler
+endfunc bl1_entrypoint
+
+func bl1_run_next_image
+ mov x20,x0
+
+ /* ---------------------------------------------
+ * MPU needs to be disabled because both BL1 and BL33 execute
+ * in EL2, and therefore share the same address space.
+ * BL33 will initialize the address space according to its
+ * own requirement.
+ * ---------------------------------------------
+ */
+ bl disable_mpu_icache_el2
+
+ /* ---------------------------------------------
+ * Wipe clean and disable all MPU regions. This function expects
+ * that the MPU has already been turned off, and caching concerns
+ * addressed, but it also explicitly turns off the MPU.
+ * ---------------------------------------------
+ */
+ bl clear_all_mpu_regions
+
+#if ENABLE_PAUTH
+ /* ---------------------------------------------
+ * Disable pointer authentication before jumping
+ * to next boot image.
+ * ---------------------------------------------
+ */
+ bl pauth_disable_el2
+#endif /* ENABLE_PAUTH */
+
+ /* --------------------------------------------------
+ * Do the transition to next boot image.
+ * --------------------------------------------------
+ */
+ ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
+ msr elr_el2, x0
+ msr spsr_el2, x1
+
+ ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
+ ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
+ ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
+ ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
+ exception_return
+endfunc bl1_run_next_image
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S b/plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S
new file mode 100644
index 0000000..43c2e01
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl1/bl1.h>
+#include <common/bl_common.h>
+#include <context.h>
+
+/* -----------------------------------------------------------------------------
+ * File contains an EL2 equivalent of the EL3 vector table from:
+ * .../bl1/aarch64/bl1_exceptions.S
+ * -----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------
+ * Very simple stackless exception handlers used by BL1.
+ * -----------------------------------------------------------------------------
+ */
+ .globl bl1_exceptions
+
+vector_base bl1_exceptions
+
+ /* -----------------------------------------------------
+ * Current EL with SP0 : 0x0 - 0x200
+ * -----------------------------------------------------
+ */
+vector_entry SynchronousExceptionSP0
+ mov x0, #SYNC_EXCEPTION_SP_EL0
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SynchronousExceptionSP0
+
+vector_entry IrqSP0
+ mov x0, #IRQ_SP_EL0
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry IrqSP0
+
+vector_entry FiqSP0
+ mov x0, #FIQ_SP_EL0
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry FiqSP0
+
+vector_entry SErrorSP0
+ mov x0, #SERROR_SP_EL0
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SErrorSP0
+
+ /* -----------------------------------------------------
+ * Current EL with SPx: 0x200 - 0x400
+ * -----------------------------------------------------
+ */
+vector_entry SynchronousExceptionSPx
+ mov x0, #SYNC_EXCEPTION_SP_ELX
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SynchronousExceptionSPx
+
+vector_entry IrqSPx
+ mov x0, #IRQ_SP_ELX
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry IrqSPx
+
+vector_entry FiqSPx
+ mov x0, #FIQ_SP_ELX
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry FiqSPx
+
+vector_entry SErrorSPx
+ mov x0, #SERROR_SP_ELX
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SErrorSPx
+
+ /* -----------------------------------------------------
+ * Lower EL using AArch64 : 0x400 - 0x600
+ * -----------------------------------------------------
+ */
+vector_entry SynchronousExceptionA64
+ /* The current v8-R64 implementation does not support conduit calls */
+ b el2_panic
+end_vector_entry SynchronousExceptionA64
+
+vector_entry IrqA64
+ mov x0, #IRQ_AARCH64
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry IrqA64
+
+vector_entry FiqA64
+ mov x0, #FIQ_AARCH64
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry FiqA64
+
+vector_entry SErrorA64
+ mov x0, #SERROR_AARCH64
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SErrorA64
+
+
+unexpected_sync_exception:
+ mov x0, #SYNC_EXCEPTION_AARCH64
+ bl plat_report_exception
+ no_ret plat_panic_handler
+
+ /* -----------------------------------------------------
+ * Save Secure/Normal world context and jump to
+ * BL1 SMC handler.
+ * -----------------------------------------------------
+ */
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_main.c b/plat/arm/board/fvp_r/fvp_r_bl1_main.c
new file mode 100644
index 0000000..2fd0e97
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_main.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include "../../../../bl1/bl1_private.h"
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <bl1/bl1.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/auth/auth_mod.h>
+#include <drivers/console.h>
+#include <lib/cpus/errata_report.h>
+#include <lib/utils.h>
+#include <smccc_helpers.h>
+#include <tools_share/uuid.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+
+void bl1_run_next_image(const struct entry_point_info *bl_ep_info);
+
+/*******************************************************************************
+ * Function to perform late architectural and platform specific initialization.
+ * It also queries the platform to load and run next BL image. Only called
+ * by the primary cpu after a cold boot.
+ ******************************************************************************/
+void bl1_transfer_bl33(void)
+{
+ unsigned int image_id;
+
+ /* Get the image id of next image to load and run. */
+ image_id = bl1_plat_get_next_image_id();
+
+#if ENABLE_PAUTH
+ /*
+ * Disable pointer authentication before running next boot image
+ */
+ pauth_disable_el2();
+#endif /* ENABLE_PAUTH */
+
+#if !ARM_DISABLE_TRUSTED_WDOG
+ /* Disable watchdog before leaving BL1 */
+ plat_arm_secure_wdt_stop();
+#endif
+
+ bl1_run_next_image(&bl1_plat_get_image_desc(image_id)->ep_info);
+}
+
+/*******************************************************************************
+ * This function locates and loads the BL33 raw binary image in the trusted SRAM.
+ * Called by the primary cpu after a cold boot.
+ * TODO: Add support for alternative image load mechanism e.g using virtio/elf
+ * loader etc.
+ ******************************************************************************/
+void bl1_load_bl33(void)
+{
+ image_desc_t *desc;
+ image_info_t *info;
+ int err;
+
+ /* Get the image descriptor */
+ desc = bl1_plat_get_image_desc(BL33_IMAGE_ID);
+ assert(desc != NULL);
+
+ /* Get the image info */
+ info = &desc->image_info;
+ INFO("BL1: Loading BL33\n");
+
+ err = bl1_plat_handle_pre_image_load(BL33_IMAGE_ID);
+ if (err != 0) {
+ ERROR("Failure in pre image load handling of BL33 (%d)\n", err);
+ plat_error_handler(err);
+ }
+
+ err = load_auth_image(BL33_IMAGE_ID, info);
+ if (err != 0) {
+ ERROR("Failed to load BL33 firmware.\n");
+ plat_error_handler(err);
+ }
+
+ /* Allow platform to handle image information. */
+ err = bl1_plat_handle_post_image_load(BL33_IMAGE_ID);
+ if (err != 0) {
+ ERROR("Failure in post image load handling of BL33 (%d)\n", err);
+ plat_error_handler(err);
+ }
+
+ NOTICE("BL1: Booting BL33\n");
+}
+
+static void bl1_load_bl2(void);
+
+#if ENABLE_PAUTH
+uint64_t bl1_apiakey[2];
+#endif
+
+/*******************************************************************************
+ * Helper utility to calculate the BL2 memory layout taking into consideration
+ * the BL1 RW data assuming that it is at the top of the memory layout.
+ ******************************************************************************/
+void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
+ meminfo_t *bl2_mem_layout)
+{
+ assert(bl1_mem_layout != NULL);
+ assert(bl2_mem_layout != NULL);
+
+ /*
+ * Remove BL1 RW data from the scope of memory visible to BL2.
+ * This is assuming BL1 RW data is at the top of bl1_mem_layout.
+ */
+ assert(bl1_mem_layout->total_base < BL1_RW_BASE);
+ bl2_mem_layout->total_base = bl1_mem_layout->total_base;
+ bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
+
+ flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t));
+}
+
+/*******************************************************************************
+ * Setup function for BL1.
+ ******************************************************************************/
+void bl1_setup(void)
+{
+ /* Perform early platform-specific setup */
+ bl1_early_platform_setup();
+
+ /* Perform late platform-specific setup */
+ bl1_plat_arch_setup();
+
+#if CTX_INCLUDE_PAUTH_REGS
+ /*
+ * Assert that the ARMv8.3-PAuth registers are present or an access
+ * fault will be triggered when they are being saved or restored.
+ */
+ assert(is_armv8_3_pauth_present());
+#endif /* CTX_INCLUDE_PAUTH_REGS */
+}
+
+/*******************************************************************************
+ * Function to perform late architectural and platform specific initialization.
+ * It also queries the platform to load and run next BL image. Only called
+ * by the primary cpu after a cold boot.
+ ******************************************************************************/
+void bl1_main(void)
+{
+ unsigned int image_id;
+
+ /* Announce our arrival */
+ NOTICE(FIRMWARE_WELCOME_STR);
+ NOTICE("BL1: %s\n", version_string);
+ NOTICE("BL1: %s\n", build_message);
+
+ INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT);
+
+ print_errata_status();
+
+#if ENABLE_ASSERTIONS
+ u_register_t val;
+ /*
+ * Ensure that MMU/Caches and coherency are turned on
+ */
+ val = read_sctlr_el2();
+
+ assert((val & SCTLR_M_BIT) != 0U);
+ assert((val & SCTLR_C_BIT) != 0U);
+ assert((val & SCTLR_I_BIT) != 0U);
+ /*
+ * Check that Cache Writeback Granule (CWG) in CTR_EL0 matches the
+ * provided platform value
+ */
+ val = (read_ctr_el0() >> CTR_CWG_SHIFT) & CTR_CWG_MASK;
+ /*
+ * If CWG is zero, then no CWG information is available but we can
+ * at least check the platform value is less than the architectural
+ * maximum.
+ */
+ if (val != 0) {
+ assert(SIZE_FROM_LOG2_WORDS(val) == CACHE_WRITEBACK_GRANULE);
+ } else {
+ assert(MAX_CACHE_LINE_SIZE >= CACHE_WRITEBACK_GRANULE);
+ }
+#endif /* ENABLE_ASSERTIONS */
+
+ /* Perform remaining generic architectural setup from ELmax */
+ bl1_arch_setup();
+
+#if TRUSTED_BOARD_BOOT
+ /* Initialize authentication module */
+ auth_mod_init();
+#endif /* TRUSTED_BOARD_BOOT */
+
+ /* Perform platform setup in BL1. */
+ bl1_platform_setup();
+
+#if ENABLE_PAUTH
+ /* Store APIAKey_EL1 key */
+ bl1_apiakey[0] = read_apiakeylo_el1();
+ bl1_apiakey[1] = read_apiakeyhi_el1();
+#endif /* ENABLE_PAUTH */
+
+ /* Get the image id of next image to load and run. */
+ image_id = bl1_plat_get_next_image_id();
+
+ /*
+ * We currently interpret any image id other than
+ * BL2_IMAGE_ID as the start of firmware update.
+ */
+ if (image_id == BL2_IMAGE_ID) {
+ bl1_load_bl2();
+ } else if (image_id == BL33_IMAGE_ID) {
+ bl1_load_bl33();
+ } else {
+ NOTICE("BL1-FWU: *******FWU Process Started*******\n");
+ }
+
+ bl1_prepare_next_image(image_id);
+
+ console_flush();
+
+ bl1_transfer_bl33();
+}
+
+/*******************************************************************************
+ * This function locates and loads the BL2 raw binary image in the trusted SRAM.
+ * Called by the primary cpu after a cold boot.
+ * TODO: Add support for alternative image load mechanism e.g using virtio/elf
+ * loader etc.
+ ******************************************************************************/
+static void bl1_load_bl2(void)
+{
+ image_desc_t *desc;
+ image_info_t *info;
+ int err;
+
+ /* Get the image descriptor */
+ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+ assert(desc != NULL);
+
+ /* Get the image info */
+ info = &desc->image_info;
+ INFO("BL1: Loading BL2\n");
+
+ err = bl1_plat_handle_pre_image_load(BL2_IMAGE_ID);
+ if (err != 0) {
+ ERROR("Failure in pre image load handling of BL2 (%d)\n", err);
+ plat_error_handler(err);
+ }
+
+ err = load_auth_image(BL2_IMAGE_ID, info);
+ if (err != 0) {
+ ERROR("Failed to load BL2 firmware.\n");
+ plat_error_handler(err);
+ }
+
+ /* Allow platform to handle image information. */
+ err = bl1_plat_handle_post_image_load(BL2_IMAGE_ID);
+ if (err != 0) {
+ ERROR("Failure in post image load handling of BL2 (%d)\n", err);
+ plat_error_handler(err);
+ }
+
+ NOTICE("BL1: Booting BL2\n");
+}
+
+/*******************************************************************************
+ * Function called just before handing over to the next BL to inform the user
+ * about the boot progress. In debug mode, also print details about the BL
+ * image's execution context.
+ ******************************************************************************/
+void bl1_print_next_bl_ep_info(const entry_point_info_t *bl_ep_info)
+{
+ NOTICE("BL1: Booting BL31\n");
+ print_entry_point_info(bl_ep_info);
+}
+
+#if SPIN_ON_BL1_EXIT
+void print_debug_loop_message(void)
+{
+ NOTICE("BL1: Debug loop, spinning forever\n");
+ NOTICE("BL1: Please connect the debugger to continue\n");
+}
+#endif
+
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
new file mode 100644
index 0000000..5e31d39
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Use the xlat_tables_v2 data structures: */
+#define XLAT_TABLES_LIB_V2 1
+
+#include <assert.h>
+
+#include "../../../../lib/xlat_mpu/xlat_mpu.h"
+#include <bl1/bl1.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/sp805.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+
+#include "fvp_r_private.h"
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#define MAP_BL1_TOTAL MAP_REGION_FLAT( \
+ bl1_tzram_layout.total_base, \
+ bl1_tzram_layout.total_size, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+/*
+ * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
+ * otherwise one region is defined containing both
+ */
+#if SEPARATE_CODE_AND_RODATA
+#define MAP_BL1_RO MAP_REGION_FLAT( \
+ BL_CODE_BASE, \
+ BL1_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE), \
+ MAP_REGION_FLAT( \
+ BL1_RO_DATA_BASE, \
+ BL1_RO_DATA_END \
+ - BL_RO_DATA_BASE, \
+ MT_RO_DATA | MT_SECURE)
+#else
+#define MAP_BL1_RO MAP_REGION_FLAT( \
+ BL_CODE_BASE, \
+ BL1_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE)
+#endif
+
+/* Data structure which holds the extents of the trusted SRAM for BL1*/
+static meminfo_t bl1_tzram_layout;
+
+struct meminfo *bl1_plat_sec_mem_layout(void)
+{
+ return &bl1_tzram_layout;
+}
+
+void arm_bl1_early_platform_setup(void)
+{
+
+#if !ARM_DISABLE_TRUSTED_WDOG
+ /* Enable watchdog */
+ plat_arm_secure_wdt_start();
+#endif
+
+ /* Initialize the console to provide early debug support */
+ arm_console_boot_init();
+
+ /* Allow BL1 to see the whole Trusted RAM */
+ bl1_tzram_layout.total_base = ARM_BL_RAM_BASE;
+ bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE;
+}
+
+/* Boolean variable to hold condition whether firmware update needed or not */
+static bool is_fwu_needed;
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+ arm_bl1_early_platform_setup();
+
+ /* Initialize the platform config for future decision making */
+ fvp_config_setup();
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ fvp_interconnect_init();
+ /*
+ * Enable coherency in Interconnect for the primary CPU's cluster.
+ */
+ fvp_interconnect_enable();
+}
+
+void arm_bl1_plat_arch_setup(void)
+{
+ const mmap_region_t bl_regions[] = {
+ MAP_BL1_TOTAL,
+ MAP_BL1_RO,
+#if USE_ROMLIB
+ ARM_MAP_ROMLIB_CODE,
+ ARM_MAP_ROMLIB_DATA,
+#endif
+#if ARM_CRYPTOCELL_INTEG
+ ARM_MAP_BL_COHERENT_RAM,
+#endif
+ /* DRAM1_region: */
+ MAP_REGION_FLAT( \
+ PLAT_ARM_DRAM1_BASE, \
+ PLAT_ARM_DRAM1_SIZE, \
+ MT_MEMORY | MT_SECURE | MT_EXECUTE \
+ | MT_RW | MT_NON_CACHEABLE),
+ /* NULL terminator: */
+ {0}
+ };
+
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
+ enable_mpu_el2(0);
+
+ arm_setup_romlib();
+}
+
+void plat_arm_secure_wdt_start(void)
+{
+ sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sp805_stop(ARM_SP805_TWDG_BASE);
+}
+
+/*
+ * Perform the platform specific architecture setup shared between
+ * ARM standard platforms.
+ */
+void arm_bl1_platform_setup(void)
+{
+ image_desc_t *desc;
+ uint32_t fw_config_max_size;
+
+ /* Initialise the IO layer and register platform IO devices */
+ plat_arm_io_setup();
+
+ /* Check if we need FWU before further processing */
+ is_fwu_needed = plat_arm_bl1_fwu_needed();
+ if (is_fwu_needed) {
+ ERROR("Skip platform setup as FWU detected\n");
+ return;
+ }
+
+ /* Set global DTB info for fixed fw_config information */
+ fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
+ set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
+
+ desc = bl1_plat_get_image_desc(BL33_IMAGE_ID);
+ assert(desc != NULL);
+
+ /*
+ * Allow access to the System counter timer module and program
+ * counter frequency for non secure images during FWU
+ */
+#ifdef ARM_SYS_TIMCTL_BASE
+ arm_configure_sys_timer();
+#endif
+#if (ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
+ write_cntfrq_el0(plat_get_syscnt_freq2());
+#endif
+}
+
+void bl1_platform_setup(void)
+{
+ arm_bl1_platform_setup();
+
+ /* Initialize System level generic or SP804 timer */
+ fvp_timer_init();
+}
+
+__dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
+{
+ /* Setup the watchdog to reset the system as soon as possible */
+ sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
+
+ while (true) {
+ wfi();
+ }
+}
+
+unsigned int bl1_plat_get_next_image_id(void)
+{
+ return is_fwu_needed ? NS_BL1U_IMAGE_ID : BL33_IMAGE_ID;
+}
+
+/*
+ * Returns BL33 image details.
+ */
+struct image_desc *bl1_plat_get_image_desc(unsigned int image_id)
+{
+ static image_desc_t bl33_img_desc = BL33_IMAGE_DESC;
+
+ return &bl33_img_desc;
+}
+
+/*
+ * This function populates the default arguments to BL33.
+ * The BL33 memory layout structure is allocated and the
+ * calculated layout is populated in arg1 to BL33.
+ */
+int bl1_plat_handle_post_image_load(unsigned int image_id)
+{
+ meminfo_t *bl33_secram_layout;
+ meminfo_t *bl1_secram_layout;
+ image_desc_t *image_desc;
+ entry_point_info_t *ep_info;
+
+ if (image_id != BL33_IMAGE_ID) {
+ return 0;
+ }
+ /* Get the image descriptor */
+ image_desc = bl1_plat_get_image_desc(BL33_IMAGE_ID);
+ assert(image_desc != NULL);
+
+ /* Get the entry point info */
+ ep_info = &image_desc->ep_info;
+
+ /* Find out how much free trusted ram remains after BL1 load */
+ bl1_secram_layout = bl1_plat_sec_mem_layout();
+
+ /*
+ * Create a new layout of memory for BL33 as seen by BL1 i.e.
+ * tell it the amount of total and free memory available.
+ * This layout is created at the first free address visible
+ * to BL33. BL33 will read the memory layout before using its
+ * memory for other purposes.
+ */
+ bl33_secram_layout = (meminfo_t *) bl1_secram_layout->total_base;
+
+ bl1_calc_bl2_mem_layout(bl1_secram_layout, bl33_secram_layout);
+
+ ep_info->args.arg1 = (uintptr_t)bl33_secram_layout;
+
+ VERBOSE("BL1: BL3 memory layout address = %p\n",
+ (void *) bl33_secram_layout);
+ return 0;
+}
diff --git a/plat/arm/board/fvp_r/fvp_r_common.c b/plat/arm/board/fvp_r/fvp_r_common.c
new file mode 100644
index 0000000..bce943d
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_common.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* This uses xlat_mpu, but tables are set up using V2 mmap_region_t */
+#define XLAT_TABLES_LIB_V2 1
+
+#include <assert.h>
+#include <common/debug.h>
+
+#include <drivers/arm/cci.h>
+#include <drivers/arm/ccn.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/sp804_delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <services/arm_arch_svc.h>
+
+#include "fvp_r_private.h"
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+
+/* Defines for GIC Driver build time selection */
+#define FVP_R_GICV3 2
+
+/*******************************************************************************
+ * arm_config holds the characteristics of the differences between the FVP_R
+ * platforms. It will be populated during cold boot at each boot stage by the
+ * primary before enabling the MPU (to allow interconnect configuration) &
+ * used thereafter. Each BL will have its own copy to allow independent
+ * operation.
+ ******************************************************************************/
+arm_config_t arm_config;
+
+#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
+ DEVICE0_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \
+ DEVICE1_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * Need to be mapped with write permissions in order to set a new non-volatile
+ * counter value.
+ */
+#define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \
+ DEVICE2_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * Table of memory regions for various BL stages to map using the MPU.
+ * This doesn't include Trusted SRAM as setup_page_tables() already takes care
+ * of mapping it.
+ *
+ * The flash needs to be mapped as writable in order to erase the FIP's Table of
+ * Contents in case of unrecoverable error (see plat_error_handler()).
+ */
+#ifdef IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_FLASH0_RW,
+ V2M_MAP_IOFPGA,
+ MAP_DEVICE0,
+ MAP_DEVICE1,
+#if TRUSTED_BOARD_BOOT
+ /* To access the Root of Trust Public Key registers. */
+ MAP_DEVICE2,
+#endif
+ {0}
+};
+#endif
+
+ARM_CASSERT_MMAP
+
+#if FVP_R_INTERCONNECT_DRIVER != FVP_R_CCN
+static const int fvp_cci400_map[] = {
+ PLAT_FVP_R_CCI400_CLUS0_SL_PORT,
+ PLAT_FVP_R_CCI400_CLUS1_SL_PORT,
+};
+
+static const int fvp_cci5xx_map[] = {
+ PLAT_FVP_R_CCI5XX_CLUS0_SL_PORT,
+ PLAT_FVP_R_CCI5XX_CLUS1_SL_PORT,
+};
+
+static unsigned int get_interconnect_master(void)
+{
+ unsigned int master;
+ u_register_t mpidr;
+
+ mpidr = read_mpidr_el1();
+ master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ?
+ MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);
+
+ assert(master < FVP_R_CLUSTER_COUNT);
+ return master;
+}
+#endif
+
+/*******************************************************************************
+ * Initialize the platform config for future decision making
+ ******************************************************************************/
+void __init fvp_config_setup(void)
+{
+ unsigned int rev, hbi, bld, arch, sys_id;
+
+ arm_config.flags |= ARM_CONFIG_BASE_MMAP;
+ sys_id = mmio_read_32(V2M_FVP_R_SYSREGS_BASE + V2M_SYS_ID);
+ rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK;
+ hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK;
+ bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK;
+ arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK;
+
+ if (arch != ARCH_MODEL) {
+ ERROR("This firmware is for FVP_R models\n");
+ panic();
+ }
+
+ /*
+ * The build field in the SYS_ID tells which variant of the GIC
+ * memory is implemented by the model.
+ */
+ switch (bld) {
+ case BLD_GIC_VE_MMAP:
+ ERROR("Legacy Versatile Express memory map for GIC %s",
+ "peripheral is not supported\n");
+ panic();
+ break;
+ case BLD_GIC_A53A57_MMAP:
+ break;
+ default:
+ ERROR("Unsupported board build %x\n", bld);
+ panic();
+ }
+
+ /*
+ * The hbi field in the SYS_ID is 0x020 for the Base FVP_R & 0x010
+ * for the Foundation FVP_R.
+ */
+ switch (hbi) {
+ case HBI_FOUNDATION_FVP_R:
+ arm_config.flags = 0;
+
+ /*
+ * Check for supported revisions of Foundation FVP_R
+ * Allow future revisions to run but emit warning diagnostic
+ */
+ switch (rev) {
+ case REV_FOUNDATION_FVP_R_V2_0:
+ case REV_FOUNDATION_FVP_R_V2_1:
+ case REV_FOUNDATION_FVP_R_v9_1:
+ case REV_FOUNDATION_FVP_R_v9_6:
+ break;
+ default:
+ WARN("Unrecognized Foundation FVP_R revision %x\n", rev);
+ break;
+ }
+ break;
+ case HBI_BASE_FVP_R:
+ arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC);
+
+ /*
+ * Check for supported revisions
+ * Allow future revisions to run but emit warning diagnostic
+ */
+ switch (rev) {
+ case REV_BASE_FVP_R_V0:
+ arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
+ break;
+ default:
+ WARN("Unrecognized Base FVP_R revision %x\n", rev);
+ break;
+ }
+ break;
+ default:
+ ERROR("Unsupported board HBI number 0x%x\n", hbi);
+ panic();
+ }
+
+ /*
+ * We assume that the presence of MT bit, and therefore shifted
+ * affinities, is uniform across the platform: either all CPUs, or no
+ * CPUs implement it.
+ */
+ if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U) {
+ arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
+ }
+}
+
+
+void __init fvp_interconnect_init(void)
+{
+#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN
+ if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
+ ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported");
+ panic();
+ }
+
+ plat_arm_interconnect_init();
+#else
+ uintptr_t cci_base = 0U;
+ const int *cci_map = NULL;
+ unsigned int map_size = 0U;
+
+ /* Initialize the right interconnect */
+ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) {
+ cci_base = PLAT_FVP_R_CCI5XX_BASE;
+ cci_map = fvp_cci5xx_map;
+ map_size = ARRAY_SIZE(fvp_cci5xx_map);
+ } else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) {
+ cci_base = PLAT_FVP_R_CCI400_BASE;
+ cci_map = fvp_cci400_map;
+ map_size = ARRAY_SIZE(fvp_cci400_map);
+ } else {
+ return;
+ }
+
+ assert(cci_base != 0U);
+ assert(cci_map != NULL);
+ cci_init(cci_base, cci_map, map_size);
+#endif
+}
+
+void fvp_interconnect_enable(void)
+{
+#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN
+ plat_arm_interconnect_enter_coherency();
+#else
+ unsigned int master;
+
+ if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
+ ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
+ master = get_interconnect_master();
+ cci_enable_snoop_dvm_reqs(master);
+ }
+#endif
+}
+
+void fvp_interconnect_disable(void)
+{
+#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN
+ plat_arm_interconnect_exit_coherency();
+#else
+ unsigned int master;
+
+ if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
+ ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
+ master = get_interconnect_master();
+ cci_disable_snoop_dvm_reqs(master);
+ }
+#endif
+}
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ assert(heap_addr != NULL);
+ assert(heap_size != NULL);
+
+ return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void fvp_timer_init(void)
+{
+#if USE_SP804_TIMER
+ /* Enable the clock override for SP804 timer 0, which means that no
+ * clock dividers are applied and the raw (35MHz) clock will be used.
+ */
+ mmio_write_32(V2M_SP810_BASE, FVP_R_SP810_CTRL_TIM0_OV);
+
+ /* Initialize delay timer driver using SP804 dual timer 0 */
+ sp804_timer_init(V2M_SP804_TIMER0_BASE,
+ SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV);
+#else
+ generic_delay_timer_init();
+
+ /* Enable System level generic timer */
+ mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
+ CNTCR_FCREQ(0U) | CNTCR_EN);
+#endif /* USE_SP804_TIMER */
+}
+
+/* Get SOC version */
+int32_t plat_get_soc_version(void)
+{
+ return (int32_t)
+ ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
+ | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
+ | FVP_R_SOC_ID);
+}
+
+/* Get SOC revision */
+int32_t plat_get_soc_revision(void)
+{
+ unsigned int sys_id;
+
+ sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
+ return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) &
+ V2M_SYS_ID_REV_MASK);
+}
diff --git a/plat/arm/board/fvp_r/fvp_r_context.S b/plat/arm/board/fvp_r/fvp_r_context.S
new file mode 100644
index 0000000..2746c2e
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_context.S
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+ .global el2_exit
+
+/* ------------------------------------------------------------------
+ * The mechanism, from el3_exit, is not used in this v8-R64 implementation.
+ * ------------------------------------------------------------------
+ */
+func el2_exit
+ exception_return
+endfunc el2_exit
diff --git a/plat/arm/board/fvp_r/fvp_r_context_mgmt.c b/plat/arm/board/fvp_r/fvp_r_context_mgmt.c
new file mode 100644
index 0000000..678b879
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_context_mgmt.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/el3_runtime/pubsub_events.h>
+
+#include <platform_def.h>
+
+
+/*******************************************************************************
+ * File contains EL2 equivalents of EL3 functions from
+ * .../lib/el3_runtime/aarch64/context_mgmt.c
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prepare the CPU system registers for first entry into secure or normal world
+ *
+ * The majority of the work needed is only for switching to non-secure, which
+ * is not available on v8-R64 cores, so this function is very simple.
+ ******************************************************************************/
+void cm_prepare_el2_exit(uint32_t security_state)
+{
+ cm_el1_sysregs_context_restore(security_state);
+ cm_set_next_eret_context(security_state);
+}
diff --git a/plat/arm/board/fvp_r/fvp_r_debug.S b/plat/arm/board/fvp_r/fvp_r_debug.S
new file mode 100644
index 0000000..8db1b09
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_debug.S
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/debug.h>
+
+ .globl el2_panic
+
+ /***********************************************************
+ * The common implementation of do_panic for all BL stages
+ ***********************************************************/
+
+.section .rodata.panic_str, "aS"
+ panic_msg: .asciz "PANIC at PC : 0x"
+
+/*
+ * el2_panic will be redefined by the
+ * crash reporting mechanism (if enabled)
+ */
+el2_panic:
+ mov x6, x30
+ bl plat_crash_console_init
+
+ /* Check if the console is initialized */
+ cbz x0, _panic_handler
+
+ /* The console is initialized */
+ adr x4, panic_msg
+ bl asm_print_str
+ mov x4, x6
+
+ /* The panic location is lr -4 */
+ sub x4, x4, #4
+ bl asm_print_hex
+
+ bl plat_crash_console_flush
+
+_panic_handler:
+ /* Pass to plat_panic_handler the address from where el2_panic was
+ * called, not the address of the call from el2_panic. */
+ mov x30, x6
+ b plat_panic_handler
diff --git a/plat/arm/board/fvp_r/fvp_r_def.h b/plat/arm/board/fvp_r/fvp_r_def.h
new file mode 100644
index 0000000..b9f6989
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_def.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_R_DEF_H
+#define FVP_R_DEF_H
+
+#include <lib/utils_def.h>
+
+#ifndef FVP_R_CLUSTER_COUNT
+#error "FVP_R_CLUSTER_COUNT is not set in makefile"
+#endif
+
+#ifndef FVP_R_MAX_CPUS_PER_CLUSTER
+#error "FVP_R_MAX_CPUS_PER_CLUSTER is not set in makefile"
+#endif
+
+#ifndef FVP_R_MAX_PE_PER_CPU
+#error "FVP_R_MAX_PE_PER_CPU is not set in makefile"
+#endif
+
+#define FVP_R_PRIMARY_CPU 0x0
+
+/* Defines for the Interconnect build selection */
+#define FVP_R_CCI 1
+#define FVP_R_CCN 2
+
+/******************************************************************************
+ * Definition of platform soc id
+ *****************************************************************************/
+#define FVP_R_SOC_ID 0
+
+/*******************************************************************************
+ * FVP_R memory map related constants
+ ******************************************************************************/
+
+#define FLASH1_BASE UL(0x8c000000)
+#define FLASH1_SIZE UL(0x04000000)
+
+#define PSRAM_BASE UL(0x94000000)
+#define PSRAM_SIZE UL(0x04000000)
+
+#define VRAM_BASE UL(0x98000000)
+#define VRAM_SIZE UL(0x02000000)
+
+/* Aggregate of all devices in the first GB */
+#define DEVICE0_BASE UL(0xa0000000)
+#define DEVICE0_SIZE UL(0x0c200000)
+
+/*
+ * In case of FVP_R models with CCN, the CCN register space overlaps into
+ * the NSRAM area.
+ */
+#define DEVICE1_BASE UL(0xae000000)
+#define DEVICE1_SIZE UL(0x1A00000)
+
+#define NSRAM_BASE UL(0xae000000)
+#define NSRAM_SIZE UL(0x10000)
+/* Devices in the second GB */
+#define DEVICE2_BASE UL(0xffe00000)
+#define DEVICE2_SIZE UL(0x00200000)
+
+#define PCIE_EXP_BASE UL(0xc0000000)
+#define TZRNG_BASE UL(0x7fe60000)
+
+/* Non-volatile counters */
+#define TRUSTED_NVCTR_BASE UL(0xffe70000)
+#define TFW_NVCTR_BASE (TRUSTED_NVCTR_BASE + UL(0x0000))
+#define TFW_NVCTR_SIZE UL(4)
+#define NTFW_CTR_BASE (TRUSTED_NVCTR_BASE + UL(0x0004))
+#define NTFW_CTR_SIZE UL(4)
+
+/* Keys */
+#define SOC_KEYS_BASE UL(0xffe80000)
+#define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + UL(0x0000))
+#define TZ_PUB_KEY_HASH_SIZE UL(32)
+#define HU_KEY_BASE (SOC_KEYS_BASE + UL(0x0020))
+#define HU_KEY_SIZE UL(16)
+#define END_KEY_BASE (SOC_KEYS_BASE + UL(0x0044))
+#define END_KEY_SIZE UL(32)
+
+/* Constants to distinguish FVP_R type */
+#define HBI_BASE_FVP_R U(0x020)
+#define REV_BASE_FVP_R_V0 U(0x0)
+#define REV_BASE_FVP_R_REVC U(0x2)
+
+#define HBI_FOUNDATION_FVP_R U(0x010)
+#define REV_FOUNDATION_FVP_R_V2_0 U(0x0)
+#define REV_FOUNDATION_FVP_R_V2_1 U(0x1)
+#define REV_FOUNDATION_FVP_R_v9_1 U(0x2)
+#define REV_FOUNDATION_FVP_R_v9_6 U(0x3)
+
+#define BLD_GIC_VE_MMAP U(0x0)
+#define BLD_GIC_A53A57_MMAP U(0x1)
+
+#define ARCH_MODEL U(0x1)
+
+/* FVP_R Power controller base address*/
+#define PWRC_BASE UL(0x1c100000)
+
+/* FVP_R SP804 timer frequency is 35 MHz*/
+#define SP804_TIMER_CLKMULT 1
+#define SP804_TIMER_CLKDIV 35
+
+/* SP810 controller. FVP_R specific flags */
+#define FVP_R_SP810_CTRL_TIM0_OV BIT_32(16)
+#define FVP_R_SP810_CTRL_TIM1_OV BIT_32(18)
+#define FVP_R_SP810_CTRL_TIM2_OV BIT_32(20)
+#define FVP_R_SP810_CTRL_TIM3_OV BIT_32(22)
+
+#endif /* FVP_R_DEF_H */
diff --git a/plat/arm/board/fvp_r/fvp_r_err.c b/plat/arm/board/fvp_r/fvp_r_err.c
new file mode 100644
index 0000000..7ee752b
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_err.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/arm/sp805.h>
+#include <drivers/cfi/v2m_flash.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+/*
+ * FVP_R error handler
+ */
+__dead2 void plat_arm_error_handler(int err)
+{
+ int ret;
+
+ switch (err) {
+ case -ENOENT:
+ case -EAUTH:
+ /* Image load or authentication error. Erase the ToC */
+ INFO("Erasing FIP ToC from flash...\n");
+ (void)nor_unlock(PLAT_ARM_FLASH_IMAGE_BASE);
+ ret = nor_word_program(PLAT_ARM_FLASH_IMAGE_BASE, 0);
+ if (ret != 0) {
+ ERROR("Cannot erase ToC\n");
+ } else {
+ INFO("Done\n");
+ }
+ break;
+ default:
+ /* Unexpected error */
+ break;
+ }
+
+ (void)console_flush();
+
+ /* Setup the watchdog to reset the system as soon as possible */
+ sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
+
+ while (true) {
+ wfi();
+ }
+}
diff --git a/plat/arm/board/fvp_r/fvp_r_helpers.S b/plat/arm/board/fvp_r/fvp_r_helpers.S
new file mode 100644
index 0000000..f7a04d8
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_helpers.S
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_pwrc.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+
+#include <platform_def.h>
+
+
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_get_my_entrypoint
+ .globl plat_is_my_cpu_primary
+ .globl plat_arm_calc_core_pos
+
+ /* -----------------------------------------------------
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ * TODO: Should we read the PSYS register to make sure
+ * that the request has gone through.
+ * -----------------------------------------------------
+ */
+func plat_secondary_cold_boot_setup
+ /* ---------------------------------------------
+ * Power down this cpu.
+ * TODO: Do we need to worry about powering the
+ * cluster down as well here? That will need
+ * locks which we won't have unless an elf-
+ * loader zeroes out the zi section.
+ * ---------------------------------------------
+ */
+ mrs x0, mpidr_el1
+ mov_imm x1, PWRC_BASE
+ str w0, [x1, #PPOFFR_OFF]
+
+ /* ---------------------------------------------
+ * There is no sane reason to come out of this
+ * wfi so panic if we do. This cpu will be pow-
+ * ered on and reset by the cpu_on pm api
+ * ---------------------------------------------
+ */
+ dsb sy
+ wfi
+ no_ret plat_panic_handler
+endfunc plat_secondary_cold_boot_setup
+
+ /* ---------------------------------------------------------------------
+ * uintptr_t plat_get_my_entrypoint (void);
+ *
+ * Main job of this routine is to distinguish between a cold and warm
+ * boot. On FVP_R, this information can be queried from the power
+ * controller. The Power Control SYS Status Register (PSYSR) indicates
+ * the wake-up reason for the CPU.
+ *
+ * For a cold boot, return 0.
+ * For a warm boot, read the mailbox and return the address it contains.
+ *
+ * TODO: PSYSR is a common register and should be
+ * accessed using locks. Since it is not possible
+ * to use locks immediately after a cold reset
+ * we are relying on the fact that after a cold
+ * reset all cpus will read the same WK field
+ * ---------------------------------------------------------------------
+ */
+func plat_get_my_entrypoint
+ /* ---------------------------------------------------------------------
+ * When bit PSYSR.WK indicates either "Wake by PPONR" or "Wake by GIC
+ * WakeRequest signal" then it is a warm boot.
+ * ---------------------------------------------------------------------
+ */
+ mrs x2, mpidr_el1
+ mov_imm x1, PWRC_BASE
+ str w2, [x1, #PSYSR_OFF]
+ ldr w2, [x1, #PSYSR_OFF]
+ ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH
+ cmp w2, #WKUP_PPONR
+ beq warm_reset
+ cmp w2, #WKUP_GICREQ
+ beq warm_reset
+
+ /* Cold reset */
+ mov x0, #0
+ ret
+
+warm_reset:
+ /* ---------------------------------------------------------------------
+ * A mailbox is maintained in the trusted SRAM. It is flushed out of the
+ * caches after every update using normal memory so it is safe to read
+ * it here with SO attributes.
+ * ---------------------------------------------------------------------
+ */
+ mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
+ ldr x0, [x0]
+ cbz x0, _panic_handler
+ ret
+
+ /* ---------------------------------------------------------------------
+ * The power controller indicates this is a warm reset but the mailbox
+ * is empty. This should never happen!
+ * ---------------------------------------------------------------------
+ */
+_panic_handler:
+ no_ret plat_panic_handler
+endfunc plat_get_my_entrypoint
+
+ /* -----------------------------------------------------
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu.
+ * -----------------------------------------------------
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ mov_imm x1, MPIDR_AFFINITY_MASK
+ and x0, x0, x1
+ cmp x0, #FVP_R_PRIMARY_CPU
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
+
+ /* ---------------------------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ *
+ * Function to calculate the core position on FVP_R.
+ *
+ * (ClusterId * FVP_R_MAX_CPUS_PER_CLUSTER * FVP_R_MAX_PE_PER_CPU) +
+ * (CPUId * FVP_R_MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * FVP_R_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_R_MAX_PE_PER_CPU)
+ * + ThreadId
+ * ---------------------------------------------------------------------
+ */
+func plat_arm_calc_core_pos
+ /*
+ * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+ * look as if in a multi-threaded implementation.
+ */
+ tst x0, #MPIDR_MT_MASK
+ lsl x3, x0, #MPIDR_AFFINITY_BITS
+ csel x3, x3, x0, eq
+
+ /* 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
+
+ /* Compute linear position */
+ mov x4, #FVP_R_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x4, x1
+ mov x5, #FVP_R_MAX_PE_PER_CPU
+ madd x0, x1, x5, x0
+ ret
+endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/fvp_r/fvp_r_io_storage.c b/plat/arm/board/fvp_r/fvp_r_io_storage.c
new file mode 100644
index 0000000..3b44828
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_io_storage.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_semihosting.h>
+#include <drivers/io/io_storage.h>
+#include <lib/semihosting.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/common_def.h>
+
+/* Semihosting filenames */
+#define BL33_IMAGE_NAME "bl33.bin"
+
+#if TRUSTED_BOARD_BOOT
+#define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
+#define NT_FW_KEY_CERT_NAME "nt_fw_key.crt"
+#define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt"
+#endif /* TRUSTED_BOARD_BOOT */
+
+/* IO devices */
+static const io_dev_connector_t *sh_dev_con;
+static uintptr_t sh_dev_handle;
+
+static const io_file_spec_t sh_file_spec[] = {
+ [BL33_IMAGE_ID] = {
+ .path = BL33_IMAGE_NAME,
+ .mode = FOPEN_MODE_RB
+ },
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_KEY_CERT_ID] = {
+ .path = TRUSTED_KEY_CERT_NAME,
+ .mode = FOPEN_MODE_RB
+ },
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {
+ .path = NT_FW_KEY_CERT_NAME,
+ .mode = FOPEN_MODE_RB
+ },
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+ .path = NT_FW_CONTENT_CERT_NAME,
+ .mode = FOPEN_MODE_RB
+ },
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+
+static int open_semihosting(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if the file exists on semi-hosting.*/
+ result = io_dev_init(sh_dev_handle, (uintptr_t)NULL);
+ if (result == 0) {
+ result = io_open(sh_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using Semi-hosting IO\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+void plat_arm_io_setup(void)
+{
+ int io_result;
+
+ io_result = arm_io_setup();
+ if (io_result < 0) {
+ panic();
+ }
+
+ /* Register the additional IO devices on this platform */
+ io_result = register_io_dev_sh(&sh_dev_con);
+ if (io_result < 0) {
+ panic();
+ }
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
+ if (io_result < 0) {
+ panic();
+ }
+}
+
+/*
+ * FVP_R provides semihosting as an alternative to load images
+ */
+int plat_arm_get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
+
+ if (result == 0) {
+ *dev_handle = sh_dev_handle;
+ *image_spec = (uintptr_t)&sh_file_spec[image_id];
+ }
+
+ return result;
+}
diff --git a/plat/arm/board/fvp_r/fvp_r_misc_helpers.S b/plat/arm/board/fvp_r/fvp_r_misc_helpers.S
new file mode 100644
index 0000000..67ad164
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_misc_helpers.S
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+ .globl disable_mpu_el2
+ .globl disable_mpu_icache_el2
+
+/* ---------------------------------------------------------------------------
+ * Disable the MPU at EL2.
+ * ---------------------------------------------------------------------------
+ */
+
+func disable_mpu_el2
+ mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT)
+do_disable_mpu_el2:
+ mrs x0, sctlr_el2
+ bic x0, x0, x1
+ msr sctlr_el2, x0
+ isb /* ensure MMU is off */
+ dsb sy
+ ret
+endfunc disable_mpu_el2
+
+
+func disable_mpu_icache_el2
+ mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT)
+ b do_disable_mpu_el2
+endfunc disable_mpu_icache_el2
diff --git a/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S b/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S
new file mode 100644
index 0000000..7e6bc3d
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <lib/el3_runtime/cpu_data.h>
+
+ .global pauth_init_enable_el2
+ .global pauth_disable_el2
+
+/* -------------------------------------------------------------
+ * File contains EL2 versions of EL3 funcs in:
+ * .../lib/extensions/pauth/pauth_helpers.S
+ * -------------------------------------------------------------
+ */
+
+/* -------------------------------------------------------------
+ * Program APIAKey_EL1 and enable pointer authentication in EL2
+ * -------------------------------------------------------------
+ */
+func pauth_init_enable_el2
+ stp x29, x30, [sp, #-16]!
+
+ /* Initialize platform key */
+ bl plat_init_apkey
+
+ /* Program instruction key A used by the Trusted Firmware */
+ msr APIAKeyLo_EL1, x0
+ msr APIAKeyHi_EL1, x1
+
+ /* Enable pointer authentication */
+ mrs x0, sctlr_el2
+ orr x0, x0, #SCTLR_EnIA_BIT
+
+#if ENABLE_BTI
+ /* Enable PAC branch type compatibility */
+ bic x0, x0, #SCTLR_BT_BIT
+#endif
+ msr sctlr_el2, x0
+ isb
+
+ ldp x29, x30, [sp], #16
+ ret
+endfunc pauth_init_enable_el2
+
+/* -------------------------------------------------------------
+ * Disable pointer authentication in EL2
+ * -------------------------------------------------------------
+ */
+func pauth_disable_el2
+ mrs x0, sctlr_el2
+ bic x0, x0, #SCTLR_EnIA_BIT
+ msr sctlr_el2, x0
+ isb
+ ret
+endfunc pauth_disable_el2
diff --git a/plat/arm/board/fvp_r/fvp_r_private.h b/plat/arm/board/fvp_r/fvp_r_private.h
new file mode 100644
index 0000000..48f6e89
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_private.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_R_PRIVATE_H
+#define FVP_R_PRIVATE_H
+
+#include <plat/arm/common/plat_arm.h>
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+
+void fvp_config_setup(void);
+
+void fvp_interconnect_init(void);
+void fvp_interconnect_enable(void);
+void fvp_interconnect_disable(void);
+void fvp_timer_init(void);
+
+#endif /* FVP_R_PRIVATE_H */
diff --git a/plat/arm/board/fvp_r/fvp_r_stack_protector.c b/plat/arm/board/fvp_r/fvp_r_stack_protector.c
new file mode 100644
index 0000000..69b6312
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_stack_protector.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <fvp_r_arch_helpers.h>
+#include <plat/common/platform.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t) 8092347823957523895ULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ /*
+ * Ideally, a random number should be returned instead of the
+ * combination of a timer's value and a compile-time constant. As the
+ * FVP_R does not have any random number generator, this is better than
+ * nothing but not necessarily really secure.
+ */
+ return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
+}
+
diff --git a/plat/arm/board/fvp_r/fvp_r_trusted_boot.c b/plat/arm/board/fvp_r/fvp_r_trusted_boot.c
new file mode 100644
index 0000000..de0b28f
--- /dev/null
+++ b/plat/arm/board/fvp_r/fvp_r_trusted_boot.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <lib/fconf/fconf.h>
+#include <lib/mmio.h>
+#include <tools_share/tbbr_oid.h>
+
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.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(cookie, key_ptr, key_len, flags);
+}
+
+/*
+ * Store a new non-volatile counter value.
+ *
+ * On some FVP_R versions, the non-volatile counters are read-only so this
+ * function will always fail.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ const char *oid;
+ uintptr_t nv_ctr_addr;
+
+ assert(cookie != NULL);
+
+ oid = (const char *)cookie;
+ if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+ TRUSTED_NV_CTR_ID);
+ } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+ NON_TRUSTED_NV_CTR_ID);
+ } else {
+ return 1;
+ }
+
+ mmio_write_32(nv_ctr_addr, nv_ctr);
+
+ /*
+ * If the FVP_R models a locked counter then its value cannot be updated
+ * and the above write operation has been silently ignored.
+ */
+ return (mmio_read_32(nv_ctr_addr) == nv_ctr) ? 0 : 1;
+}
diff --git a/plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h b/plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h
new file mode 100644
index 0000000..92bf484
--- /dev/null
+++ b/plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_R_ARCH_HELPERS_H
+#define FVP_R_ARCH_HELPERS_H
+
+#include <arch_helpers.h>
+
+/*******************************************************************************
+ * MPU register definitions
+ ******************************************************************************/
+#define MPUIR_EL2 S3_4_C0_C0_4
+#define PRBAR_EL2 S3_4_C6_C8_0
+#define PRLAR_EL2 S3_4_C6_C8_1
+#define PRSELR_EL2 S3_4_C6_C2_1
+#define PRENR_EL2 S3_4_C6_C1_1
+
+/* v8-R64 MPU registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpuir_el2, MPUIR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(prenr_el2, PRENR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(prselr_el2, PRSELR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(prbar_el2, PRBAR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(prlar_el2, PRLAR_EL2)
+
+#endif /* FVP_R_ARCH_HELPERS_H */
diff --git a/plat/arm/board/fvp_r/include/plat.ld.S b/plat/arm/board/fvp_r/include/plat.ld.S
new file mode 100644
index 0000000..e91a5a0
--- /dev/null
+++ b/plat/arm/board/fvp_r/include/plat.ld.S
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_LD_S
+#define PLAT_LD_S
+
+#include <plat/arm/common/arm_tzc_dram.ld.S>
+
+#endif /* PLAT_LD_S */
diff --git a/plat/arm/board/fvp_r/include/platform_def.h b/plat/arm/board/fvp_r/include/platform_def.h
new file mode 100644
index 0000000..4a6b441
--- /dev/null
+++ b/plat/arm/board/fvp_r/include/platform_def.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_R_PLATFORM_DEF_H
+#define FVP_R_PLATFORM_DEF_H
+
+#define PLAT_V2M_OFFSET 0x80000000
+
+#define BL33_IMAGE_DESC { \
+ .image_id = BL33_IMAGE_ID, \
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, \
+ VERSION_2, image_info_t, 0), \
+ .image_info.image_base = PLAT_ARM_DRAM1_BASE + 0x1000, \
+ .image_info.image_max_size = UL(0x3ffff000), \
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, \
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),\
+ .ep_info.pc = PLAT_ARM_DRAM1_BASE + 0x1000, \
+ .ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), \
+}
+
+#include "../fvp_r_def.h"
+#include <drivers/arm/tzc400.h>
+#include <lib/utils_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+
+/* These are referenced by arm_def.h #included next, so #define first. */
+#define PLAT_ARM_TRUSTED_ROM_BASE UL(0x80000000)
+#define PLAT_ARM_TRUSTED_SRAM_BASE UL(0x84000000)
+#define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x86000000)
+#define PLAT_ARM_DRAM1_BASE ULL(0x0)
+#define PLAT_ARM_DRAM2_BASE ULL(0x080000000)
+
+#define PLAT_HW_CONFIG_DTB_BASE ULL(0x12000000)
+#define PLAT_ARM_SYS_CNTCTL_BASE UL(0xaa430000)
+#define PLAT_ARM_SYS_CNTREAD_BASE UL(0xaa800000)
+#define PLAT_ARM_SYS_TIMCTL_BASE UL(0xaa810000)
+#define PLAT_ARM_SYS_CNT_BASE_S UL(0xaa820000)
+#define PLAT_ARM_SYS_CNT_BASE_NS UL(0xaa830000)
+#define PLAT_ARM_SP805_TWDG_BASE UL(0xaa490000)
+
+#include <plat/arm/common/arm_def.h>
+#include <plat/common/common_def.h>
+
+
+/* Required to create plat_regions: */
+#define MIN_LVL_BLOCK_DESC U(1)
+
+/* Required platform porting definitions */
+#define PLATFORM_CORE_COUNT (U(FVP_R_CLUSTER_COUNT) * \
+ U(FVP_R_MAX_CPUS_PER_CLUSTER) * \
+ U(FVP_R_MAX_PE_PER_CPU))
+
+#define PLAT_NUM_PWR_DOMAINS (U(FVP_R_CLUSTER_COUNT) + \
+ PLATFORM_CORE_COUNT + U(1))
+
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
+
+/*
+ * Other platform porting definitions are provided by included headers
+ */
+
+/*
+ * Required ARM standard platform porting definitions
+ */
+#define PLAT_ARM_CLUSTER_COUNT U(FVP_R_CLUSTER_COUNT)
+#define PLAT_ARM_DRAM1_SIZE ULL(0x7fffffff)
+#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00040000) /* 256 KB */
+#define PLAT_ARM_TRUSTED_ROM_SIZE UL(0x04000000) /* 64 MB */
+#define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */
+
+/* These two are defined thus in arm_def.h, but doesn't seem to see it... */
+#define PLAT_BL1_RO_LIMIT (BL1_RO_BASE \
+ + PLAT_ARM_TRUSTED_ROM_SIZE)
+
+#define PLAT_ARM_SYS_CNTCTL_BASE UL(0xaa430000)
+#define PLAT_ARM_SYS_CNTREAD_BASE UL(0xaa800000)
+#define PLAT_ARM_SYS_TIMCTL_BASE UL(0xaa810000)
+#define PLAT_ARM_SYS_CNT_BASE_S UL(0xaa820000)
+#define PLAT_ARM_SYS_CNT_BASE_NS UL(0xaa830000)
+#define PLAT_ARM_SP805_TWDG_BASE UL(0xaa490000)
+
+/* virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
+
+/* No SCP in FVP_R */
+#define PLAT_ARM_SCP_TZC_DRAM1_SIZE UL(0x0)
+
+#define PLAT_ARM_DRAM2_SIZE UL(0x80000000)
+
+#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000)
+
+#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \
+ PLAT_HW_CONFIG_DTB_BASE, \
+ PLAT_HW_CONFIG_DTB_SIZE, \
+ MT_MEMORY | MT_RO | MT_NS)
+
+#define V2M_FVP_R_SYSREGS_BASE UL(0x9c010000)
+
+/*
+ * Load address of BL33 for this platform port,
+ * U-Boot specifically must be loaded at a 4K aligned address.
+ */
+#define PLAT_ARM_NS_IMAGE_BASE (PLAT_ARM_DRAM1_BASE + 0x1000)
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#if !USE_ROMLIB
+# define PLAT_ARM_MMAP_ENTRIES 11
+# define MAX_XLAT_TABLES 5
+#else
+# define PLAT_ARM_MMAP_ENTRIES 12
+# define MAX_XLAT_TABLES 6
+#endif
+# define N_MPU_REGIONS 16 /* number of MPU regions */
+# define ALL_MPU_EL2_REGIONS_USED 0xffffffff
+ /* this is the PRENR_EL2 value if all MPU regions are in use */
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#define PLAT_ARM_MAX_BL1_RW_SIZE UL(0xB000)
+
+/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0x1000)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0xe000)
+#define FVP_R_BL2_ROMLIB_OPTIMIZATION UL(0x6000)
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0)
+#define FVP_R_BL2_ROMLIB_OPTIMIZATION UL(0)
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+#if COT_DESC_IN_DTB
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1E000) - FVP_R_BL2_ROMLIB_OPTIMIZATION)
+#else
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_R_BL2_ROMLIB_OPTIMIZATION)
+#endif
+#else
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - FVP_R_BL2_ROMLIB_OPTIMIZATION)
+#endif
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of
+ * BL2 and BL1-RW
+ */
+#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000)
+
+/*
+ * Size of cacheable stacks
+ */
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE UL(0x1000)
+# else
+# define PLATFORM_STACK_SIZE UL(0x500)
+# endif
+#endif
+
+#define MAX_IO_DEVICES 3
+#define MAX_IO_HANDLES 4
+
+/*
+ * These nominally reserve the last block of flash for PSCI MEM PROTECT flag,
+ * but no PSCI in FVP_R platform, so reserve nothing:
+ */
+#define PLAT_ARM_FLASH_IMAGE_BASE (PLAT_ARM_DRAM1_BASE + UL(0x40000000))
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE (PLAT_ARM_DRAM1_SIZE - UL(0x40000000))
+
+#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/*
+ * PL011 related constants
+ */
+#define PLAT_ARM_BOOT_UART_BASE V2M_IOFPGA_UART0_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE V2M_IOFPGA_UART1_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ V2M_IOFPGA_UART1_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ
+
+#define PLAT_ARM_TSP_UART_BASE V2M_IOFPGA_UART2_BASE
+#define PLAT_ARM_TSP_UART_CLK_IN_HZ V2M_IOFPGA_UART2_CLK_IN_HZ
+
+/* CCI related constants */
+#define PLAT_FVP_R_CCI400_BASE UL(0xac090000)
+#define PLAT_FVP_R_CCI400_CLUS0_SL_PORT 3
+#define PLAT_FVP_R_CCI400_CLUS1_SL_PORT 4
+
+/* CCI-500/CCI-550 on Base platform */
+#define PLAT_FVP_R_CCI5XX_BASE UL(0xaa000000)
+#define PLAT_FVP_R_CCI5XX_CLUS0_SL_PORT 5
+#define PLAT_FVP_R_CCI5XX_CLUS1_SL_PORT 6
+
+/* CCN related constants. Only CCN 502 is currently supported */
+#define PLAT_ARM_CCN_BASE UL(0xae000000)
+#define PLAT_ARM_CLUSTER_TO_CCN_ID_MAP 1, 5, 7, 11
+
+/* System timer related constants */
+#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
+
+/* Mailbox base address */
+#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
+
+
+/* TrustZone controller related constants
+ *
+ * Currently only filters 0 and 2 are connected on Base FVP_R.
+ * Filter 0 : CPU clusters (no access to DRAM by default)
+ * Filter 1 : not connected
+ * Filter 2 : LCDs (access to VRAM allowed by default)
+ * Filter 3 : not connected
+ * Programming unconnected filters will have no effect at the
+ * moment. These filter could, however, be connected in future.
+ * So care should be taken not to configure the unused filters.
+ *
+ * Allow only non-secure access to all DRAM to supported devices.
+ * Give access to the CPUs and Virtio. Some devices
+ * would normally use the default ID so allow that too.
+ */
+#define PLAT_ARM_TZC_BASE UL(0xaa4a0000)
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS ( \
+ TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_DEFAULT) | \
+ TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_PCI) | \
+ TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_AP) | \
+ TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_VIRTIO) | \
+ TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_VIRTIO_OLD))
+
+/*
+ * GIC related constants to cater for both GICv2 and GICv3 instances of an
+ * FVP_R. They could be overridden at runtime in case the FVP_R implements the
+ * legacy VE memory map.
+ */
+#define PLAT_ARM_GICD_BASE BASE_GICD_BASE
+#define PLAT_ARM_GICR_BASE BASE_GICR_BASE
+#define PLAT_ARM_GICC_BASE BASE_GICC_BASE
+
+#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \
+ PLAT_SP_IMAGE_NS_BUF_SIZE)
+
+#define PLAT_SP_PRI PLAT_RAS_PRI
+
+/*
+ * Physical and virtual address space limits for MPU in AARCH64 & AARCH32 modes
+ */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+
+#define ARM_SOC_CONTINUATION_SHIFT U(24)
+#define ARM_SOC_IDENTIFICATION_SHIFT U(16)
+
+#endif /* FVP_R_PLATFORM_DEF_H */
diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk
new file mode 100644
index 0000000..39509dd
--- /dev/null
+++ b/plat/arm/board/fvp_r/platform.mk
@@ -0,0 +1,125 @@
+#
+# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Only aarch64 ARCH supported for FVP_R
+ARCH := aarch64
+
+# Override to exclude BL2, BL2U, BL31, and BL33 for FVP_R
+override NEED_BL2 := no
+override NEED_BL2U := no
+override NEED_BL31 := no
+
+override CTX_INCLUDE_AARCH32_REGS := 0
+
+# Default cluster count for FVP_R
+FVP_R_CLUSTER_COUNT := 2
+
+# Default number of CPUs per cluster on FVP_R
+FVP_R_MAX_CPUS_PER_CLUSTER := 4
+
+# Default number of threads per CPU on FVP_R
+FVP_R_MAX_PE_PER_CPU := 1
+
+# Use MPU-based memory management:
+XLAT_MPU_LIB_V1 := 1
+
+# Pass FVP_R_CLUSTER_COUNT to the build system.
+$(eval $(call add_define,FVP_R_CLUSTER_COUNT))
+
+# Pass FVP_R_MAX_CPUS_PER_CLUSTER to the build system.
+$(eval $(call add_define,FVP_R_MAX_CPUS_PER_CLUSTER))
+
+# Pass FVP_R_MAX_PE_PER_CPU to the build system.
+$(eval $(call add_define,FVP_R_MAX_PE_PER_CPU))
+
+# Sanity check the cluster count and if FVP_R_CLUSTER_COUNT <= 2,
+# choose the CCI driver , else the CCN driver
+ifeq ($(FVP_R_CLUSTER_COUNT), 0)
+$(error "Incorrect cluster count specified for FVP_R port")
+else ifeq ($(FVP_R_CLUSTER_COUNT),$(filter $(FVP_R_CLUSTER_COUNT),1 2))
+FVP_R_INTERCONNECT_DRIVER := FVP_R_CCI
+else
+FVP_R_INTERCONNECT_DRIVER := FVP_R_CCN
+endif
+
+$(eval $(call add_define,FVP_R_INTERCONNECT_DRIVER))
+
+ifeq (${FVP_R_INTERCONNECT_DRIVER}, FVP_R_CCI)
+FVP_R_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c
+else ifeq (${FVP_R_INTERCONNECT_DRIVER}, FVP_R_CCN)
+FVP_R_INTERCONNECT_SOURCES := drivers/arm/ccn/ccn.c \
+ plat/arm/common/arm_ccn.c
+else
+$(error "Incorrect CCN driver chosen on FVP_R port")
+endif
+
+PLAT_INCLUDES := -Iplat/arm/board/fvp_r/include
+
+PLAT_BL_COMMON_SOURCES := plat/arm/board/fvp_r/fvp_r_common.c
+
+FVP_R_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S
+
+# select a different set of CPU files, depending on whether we compile for
+# hardware assisted coherency cores or not
+ifeq (${HW_ASSISTED_COHERENCY}, 0)
+# Cores used without DSU
+# FVP_R_CPU_LIBS += lib/cpus/aarch64/fvp_r.S
+else
+# Cores used with DSU only
+# FVP_R_CPU_LIBS += lib/cpus/aarch64/fvp_r.S
+endif
+
+BL1_SOURCES += drivers/arm/sp805/sp805.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/io/io_semihosting.c \
+ lib/semihosting/semihosting.c \
+ lib/semihosting/${ARCH}/semihosting_call.S \
+ plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c \
+ plat/arm/board/fvp_r/fvp_r_bl1_setup.c \
+ plat/arm/board/fvp_r/fvp_r_context_mgmt.c \
+ plat/arm/board/fvp_r/fvp_r_err.c \
+ plat/arm/board/fvp_r/fvp_r_io_storage.c \
+ plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c \
+ plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S \
+ plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S \
+ plat/arm/board/fvp_r/fvp_r_bl1_main.c \
+ plat/arm/board/fvp_r/fvp_r_context.S \
+ plat/arm/board/fvp_r/fvp_r_debug.S \
+ plat/arm/board/fvp_r/fvp_r_helpers.S \
+ plat/arm/board/fvp_r/fvp_r_misc_helpers.S \
+ plat/arm/board/fvp_r/fvp_r_pauth_helpers.S \
+ ${FVP_R_CPU_LIBS} \
+ ${FVP_R_INTERCONNECT_SOURCES}
+
+ifeq (${USE_SP804_TIMER},1)
+BL1_SOURCES += drivers/arm/sp804/sp804_delay_timer.c
+else
+BL1_SOURCES += drivers/delay_timer/generic_delay_timer.c
+endif
+
+# Enable Activity Monitor Unit extensions by default
+ENABLE_AMU := 1
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp_r/fvp_r_stack_protector.c
+endif
+
+NEED_BL32 := no
+
+ifneq (${BL2_AT_EL3}, 0)
+ override BL1_SOURCES =
+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_r/fvp_r_trusted_boot.c
+
+# FVP being a development platform, enable capability to disable Authentication
+# dynamically if TRUSTED_BOARD_BOOT is set.
+DYN_DISABLE_AUTH := 1
+endif
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 30a0c5c..194814f 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -44,6 +44,8 @@
#define TZC_NSAID_ALL_AP U(0)
#define TZC_NSAID_PCI U(1)
#define TZC_NSAID_HDLCD0 U(2)
+#define TZC_NSAID_DMA U(5)
+#define TZC_NSAID_DMA2 U(8)
#define TZC_NSAID_CLCD U(7)
#define TZC_NSAID_AP U(9)
#define TZC_NSAID_VIRTIO U(15)
@@ -52,6 +54,8 @@
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA2)) | \
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index 794f897..5b24c32 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-# RD-N2 platform uses GIC-Clayton which is based on GICv4.1
+# RD-N2 platform uses GIC-700 which is based on GICv4.1
GIC_ENABLE_V4_EXTN := 1
include plat/arm/css/sgi/sgi-common.mk
diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/rdv1/platform.mk
index 1ae85de..11f5212 100644
--- a/plat/arm/board/rdv1/platform.mk
+++ b/plat/arm/board/rdv1/platform.mk
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-# RD-V1 platform uses GIC-Clayton which is based on GICv4.1
+# RD-V1 platform uses GIC-700 which is based on GICv4.1
GIC_ENABLE_V4_EXTN := 1
include plat/arm/css/sgi/sgi-common.mk
diff --git a/plat/arm/board/tc/fdts/tc_fw_config.dts b/plat/arm/board/tc/fdts/tc_fw_config.dts
index 4b6abd4..a84c7f8 100644
--- a/plat/arm/board/tc/fdts/tc_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,7 +26,7 @@
hw-config {
load-address = <0x0 0x83000000>;
- max-size = <0x01000000>;
+ max-size = <0x8000>;
id = <HW_CONFIG_ID>;
};
};
diff --git a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
index 34b4e74..92e2ddd 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
@@ -36,7 +36,7 @@
#ifdef TS_SP_FW_CONFIG
vm2 {
is_ffa_partition;
- debug_name = "secure-storage";
+ debug_name = "internal-trusted-storage";
load_address = <0xfee00000>;
vcpu_count = <1>;
mem_size = <2097152>; /* 2MB TZC DRAM */
diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
index 28ed7ae..af80550 100644
--- a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
@@ -4,6 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <lib/libc/cdefs.h>
+
/dts-v1/;
/ {
@@ -27,8 +29,11 @@
secure-partitions {
compatible = "arm,sp";
+#ifdef ARM_BL2_SP_LIST_DTS
+ #include __XSTRING(ARM_BL2_SP_LIST_DTS)
+#else
#ifdef TS_SP_FW_CONFIG
- secure-storage {
+ internal-trusted-storage {
uuid = "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14";
load-address = <0xfee00000>;
};
@@ -60,5 +65,6 @@
load-address = <0xfe200000>;
};
#endif
+#endif /* ARM_BL2_SP_LIST_DTS */
};
};
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index c8edd2f..ccabced 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -55,6 +55,14 @@
TC_TZC_DRAM1_BASE, \
TC_TZC_DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
+
+#define PLAT_HW_CONFIG_DTB_BASE ULL(0x83000000)
+#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000)
+
+#define PLAT_DTB_DRAM_NS MAP_REGION_FLAT( \
+ PLAT_HW_CONFIG_DTB_BASE, \
+ PLAT_HW_CONFIG_DTB_SIZE, \
+ MT_MEMORY | MT_RO | MT_NS)
/*
* Max size of SPMC is 2MB for tc. With SPMD enabled this value corresponds to
* max size of BL32 image.
@@ -122,7 +130,7 @@
* calculated using the current BL31 PROGBITS debug size plus the sizes of
* BL2 and BL1-RW
*/
-#define PLAT_ARM_MAX_BL31_SIZE 0x3B000
+#define PLAT_ARM_MAX_BL31_SIZE 0x3F000
/*
* Size of cacheable stacks
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 8db764c..7ebf639 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -31,6 +31,9 @@
# GIC-600 configuration
GICV3_SUPPORT_GIC600 := 1
+# Enable SVE
+ENABLE_SVE_FOR_NS := 1
+ENABLE_SVE_FOR_SWD := 1
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
@@ -77,6 +80,7 @@
BL2_SOURCES += ${TC_BASE}/tc_security.c \
${TC_BASE}/tc_err.c \
${TC_BASE}/tc_trusted_boot.c \
+ ${TC_BASE}/tc_bl2_setup.c \
lib/utils/mem_region.c \
drivers/arm/tzc/tzc400.c \
plat/arm/common/arm_tzc400.c \
@@ -87,6 +91,9 @@
${ENT_GIC_SOURCES} \
${TC_BASE}/tc_bl31_setup.c \
${TC_BASE}/tc_topology.c \
+ common/fdt_wrappers.c \
+ lib/fconf/fconf.c \
+ lib/fconf/fconf_dyn_cfg_getter.c \
drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
diff --git a/plat/arm/board/tc/tc_bl2_setup.c b/plat/arm/board/tc/tc_bl2_setup.c
new file mode 100644
index 0000000..74ef569
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl2_setup.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+
+#include <plat/arm/common/plat_arm.h>
+
+/*******************************************************************************
+ * This function returns the list of executable images
+ ******************************************************************************/
+struct bl_params *plat_get_next_bl_params(void)
+{
+ struct bl_params *arm_bl_params = arm_get_next_bl_params();
+
+ const struct dyn_cfg_dtb_info_t *fw_config_info;
+ bl_mem_params_node_t *param_node;
+ uintptr_t fw_config_base = 0U;
+ entry_point_info_t *ep_info;
+
+ /* Get BL31 image node */
+ param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
+ assert(param_node != NULL);
+
+ /* Get fw_config load address */
+ fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+ assert(fw_config_info != NULL);
+
+ fw_config_base = fw_config_info->config_addr;
+ assert(fw_config_base != 0U);
+
+ /*
+ * Get the entry point info of BL31 image and override
+ * arg1 of entry point info with fw_config base address
+ */
+ ep_info = ¶m_node->ep_info;
+ ep_info->args.arg1 = (uint32_t)fw_config_base;
+
+ return arm_bl_params;
+}
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index ecec26c..0523ef8 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,8 @@
#include <common/debug.h>
#include <drivers/arm/css/css_mhu_doorbell.h>
#include <drivers/arm/css/scmi.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -42,6 +44,9 @@
u_register_t arg2, u_register_t arg3)
{
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+
+ /* Fill the properties struct with the info from the config dtb */
+ fconf_populate("FW_CONFIG", arg1);
}
void tc_bl31_common_platform_setup(void)
@@ -53,3 +58,16 @@
{
return css_scmi_override_pm_ops(ops);
}
+
+void __init bl31_plat_arch_setup(void)
+{
+ arm_bl31_plat_arch_setup();
+
+ /* HW_CONFIG was also loaded by BL2 */
+ const struct dyn_cfg_dtb_info_t *hw_config_info;
+
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+
+ fconf_populate("HW_CONFIG", hw_config_info->config_addr);
+}
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index 3863a0a..a9668e1 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -63,6 +63,7 @@
ARM_MAP_SHARED_RAM,
V2M_MAP_IOFPGA,
TC_MAP_DEVICE,
+ PLAT_DTB_DRAM_NS,
#if SPM_MM
ARM_SPM_BUF_EL3_MMAP,
#endif
diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c
index 124c1af..ce2c356 100644
--- a/plat/arm/common/arm_bl1_fwu.c
+++ b/plat/arm/common/arm_bl1_fwu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,8 @@
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#pragma weak bl1_plat_get_image_desc
+
/* Struct to keep track of usable memory */
typedef struct bl1_mem_info {
uintptr_t mem_base;
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 4b2a062..872de3e 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,9 +22,12 @@
#pragma weak bl1_early_platform_setup
#pragma weak bl1_plat_arch_setup
#pragma weak bl1_plat_sec_mem_layout
+#pragma weak arm_bl1_early_platform_setup
#pragma weak bl1_plat_prepare_exit
#pragma weak bl1_plat_get_next_image_id
#pragma weak plat_arm_bl1_fwu_needed
+#pragma weak arm_bl1_plat_arch_setup
+#pragma weak arm_bl1_platform_setup
#define MAP_BL1_TOTAL MAP_REGION_FLAT( \
bl1_tzram_layout.total_base, \
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 26af383..5b26a1d 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -233,7 +233,7 @@
******************************************************************************/
int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
{
-#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD
/* For Secure Partitions we don't need post processing */
if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) &&
(image_id < MAX_NUMBER_IDS)) {
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 4d5e8b4..dc8c6d0 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -206,18 +206,22 @@
plat/arm/common/arm_console.c
ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
-PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
+PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/${ARCH}/xlat_tables.c
else
+ifeq (${XLAT_MPU_LIB_V1}, 1)
+include lib/xlat_mpu/xlat_mpu.mk
+PLAT_BL_COMMON_SOURCES += ${XLAT_MPU_LIB_V1_SRCS}
+else
include lib/xlat_tables_v2/xlat_tables.mk
-
-PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+endif
endif
ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c \
plat/arm/common/fconf/arm_fconf_io.c
ifeq (${SPD},spmd)
- ifeq (${SPMD_SPM_AT_SEL2},1)
+ ifeq (${BL2_ENABLE_SP_LOAD},1)
ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c
endif
endif
@@ -351,8 +355,13 @@
# Include the selected chain of trust sources.
ifeq (${COT},tbbr)
- BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \
+ ifeq (${PLAT},fvp_r)
+ BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \
+ drivers/auth/tbbr/tbbr_cot_bl1_r64.c
+ else
+ BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \
drivers/auth/tbbr/tbbr_cot_bl1.c
+ endif
ifneq (${COT_DESC_IN_DTB},0)
BL2_SOURCES += lib/fconf/fconf_cot_getter.c
else
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index ebf6dff..c411c6c 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,7 +32,7 @@
next_bl_params_cpy_ptr);
}
-#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD
/*******************************************************************************
* This function appends Secure Partitions to list of loadable images.
******************************************************************************/
@@ -76,7 +76,7 @@
******************************************************************************/
struct bl_load_info *plat_get_bl_image_load_info(void)
{
-#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD
bl_load_info_t *bl_load_info;
bl_load_info = get_bl_load_info_from_mem_params_desc();
diff --git a/plat/arm/common/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c
index 1ba9f3a..0af1a20 100644
--- a/plat/arm/common/fconf/fconf_ethosn_getter.c
+++ b/plat/arm/common/fconf/fconf_ethosn_getter.c
@@ -12,7 +12,7 @@
#include <libfdt.h>
#include <plat/arm/common/fconf_ethosn_getter.h>
-struct ethosn_config_t ethosn_config;
+struct ethosn_config_t ethosn_config = {.num_cores = 0};
static uint8_t fdt_node_get_status(const void *fdt, int node)
{
@@ -33,74 +33,86 @@
int fconf_populate_ethosn_config(uintptr_t config)
{
int ethosn_node;
- int sub_node;
- uint8_t ethosn_status;
- uint32_t core_count = 0U;
- uint32_t core_addr_idx = 0U;
const void *hw_conf_dtb = (const void *)config;
/* Find offset to node with 'ethosn' compatible property */
- ethosn_node = fdt_node_offset_by_compatible(hw_conf_dtb, -1, "ethosn");
- if (ethosn_node < 0) {
+ INFO("Probing Arm Ethos-N NPU\n");
+ uint32_t total_core_count = 0U;
+
+ fdt_for_each_compatible_node(hw_conf_dtb, ethosn_node, "ethosn") {
+ int sub_node;
+ uint8_t ethosn_status;
+ uint32_t device_core_count = 0U;
+
+ /* If the Arm Ethos-N NPU is disabled the core check can be skipped */
+ ethosn_status = fdt_node_get_status(hw_conf_dtb, ethosn_node);
+ if (ethosn_status == ETHOSN_STATUS_DISABLED) {
+ continue;
+ }
+
+ fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) {
+ int err;
+ uintptr_t core_addr;
+ uint8_t core_status;
+
+ if (total_core_count >= ETHOSN_CORE_NUM_MAX) {
+ ERROR("FCONF: Reached max number of Arm Ethos-N NPU cores\n");
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+
+ /* Check that the sub node is "ethosn-core" compatible */
+ if (fdt_node_check_compatible(hw_conf_dtb,
+ sub_node,
+ "ethosn-core") != 0) {
+ /* Ignore incompatible sub node */
+ continue;
+ }
+
+ core_status = fdt_node_get_status(hw_conf_dtb, sub_node);
+ if (core_status == ETHOSN_STATUS_DISABLED) {
+ continue;
+ }
+
+ err = fdt_get_reg_props_by_index(hw_conf_dtb,
+ ethosn_node,
+ device_core_count,
+ &core_addr,
+ NULL);
+ if (err < 0) {
+ ERROR(
+ "FCONF: Failed to read reg property for Arm Ethos-N NPU core %u\n",
+ device_core_count);
+ return err;
+ }
+
+ INFO("NPU core probed at address 0x%lx\n", core_addr);
+ ethosn_config.core[total_core_count].addr = core_addr;
+ total_core_count++;
+ device_core_count++;
+ }
+
+ if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
+ ERROR("FCONF: Failed to parse sub nodes\n");
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+
+ if (device_core_count == 0U) {
+ ERROR(
+ "FCONF: Enabled Arm Ethos-N NPU device must have at least one enabled core\n");
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ }
+
+ if (total_core_count == 0U) {
ERROR("FCONF: Can't find 'ethosn' compatible node in dtb\n");
- return ethosn_node;
+ return -FDT_ERR_BADSTRUCTURE;
}
- /* If the Arm Ethos-N NPU is disabled the core check can be skipped */
- ethosn_status = fdt_node_get_status(hw_conf_dtb, ethosn_node);
- if (ethosn_status == ETHOSN_STATUS_DISABLED) {
- return 0;
- }
+ ethosn_config.num_cores = total_core_count;
- fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) {
- int err;
- uintptr_t addr;
- uint8_t status;
-
- /* Check that the sub node is "ethosn-core" compatible */
- if (fdt_node_check_compatible(hw_conf_dtb, sub_node,
- "ethosn-core") != 0) {
- /* Ignore incompatible sub node */
- continue;
- }
-
- /* Including disabled cores */
- if (core_addr_idx >= ETHOSN_CORE_NUM_MAX) {
- ERROR("FCONF: Reached max number of Arm Ethos-N NPU cores\n");
- return -1;
- }
-
- status = fdt_node_get_status(hw_conf_dtb, ethosn_node);
- if (status == ETHOSN_STATUS_DISABLED) {
- ++core_addr_idx;
- continue;
- }
-
- err = fdt_get_reg_props_by_index(hw_conf_dtb, ethosn_node,
- core_addr_idx, &addr, NULL);
- if (err < 0) {
- ERROR("FCONF: Failed to read reg property for Arm Ethos-N NPU core %u\n",
- core_addr_idx);
- return err;
- }
-
- ethosn_config.core_addr[core_count++] = addr;
- ++core_addr_idx;
- }
-
- if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
- ERROR("FCONF: Failed to parse sub nodes\n");
- return sub_node;
- }
-
- /* The Arm Ethos-N NPU can't be used if no cores were found */
- if (core_count == 0) {
- ERROR("FCONF: No Arm Ethos-N NPU cores found\n");
- return -1;
- }
-
- ethosn_config.num_cores = core_count;
- ethosn_config.status = ethosn_status;
+ INFO("%d NPU core%s probed\n",
+ ethosn_config.num_cores,
+ ethosn_config.num_cores > 1 ? "s" : "");
return 0;
}
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S
index 04bfb77..ced59e8 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/css/sgi/aarch64/sgi_helper.S
@@ -9,6 +9,8 @@
#include <platform_def.h>
#include <cortex_a75.h>
#include <neoverse_n1.h>
+#include <neoverse_v1.h>
+#include <neoverse_n2.h>
#include <cpu_macros.S>
.globl plat_arm_calc_core_pos
@@ -66,6 +68,8 @@
func plat_reset_handler
jump_if_cpu_midr CORTEX_A75_MIDR, A75
jump_if_cpu_midr NEOVERSE_N1_MIDR, N1
+ jump_if_cpu_midr NEOVERSE_V1_MIDR, V1
+ jump_if_cpu_midr NEOVERSE_N2_MIDR, N2
ret
/* -----------------------------------------------------
@@ -85,4 +89,18 @@
msr NEOVERSE_N1_CPUPWRCTLR_EL1, x0
isb
ret
+
+V1:
+ mrs x0, NEOVERSE_V1_CPUPWRCTLR_EL1
+ bic x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+ msr NEOVERSE_V1_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+
+N2:
+ mrs x0, NEOVERSE_N2_CPUPWRCTLR_EL1
+ bic x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT
+ msr NEOVERSE_N2_CPUPWRCTLR_EL1, x0
+ isb
+ ret
endfunc plat_reset_handler
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_io_storage.c b/plat/imx/common/imx_io_storage.c
similarity index 93%
rename from plat/imx/imx8m/imx8mm/imx8mm_io_storage.c
rename to plat/imx/common/imx_io_storage.c
index ff6687e..bb35662 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_io_storage.c
+++ b/plat/imx/common/imx_io_storage.c
@@ -6,10 +6,10 @@
#include <assert.h>
+#include <common/debug.h>
#include <drivers/io/io_block.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_fip.h>
-#include <drivers/io/io_driver.h>
#include <drivers/io/io_memmap.h>
#include <drivers/mmc.h>
#include <lib/utils_def.h>
@@ -21,21 +21,21 @@
static const io_dev_connector_t *fip_dev_con;
static uintptr_t fip_dev_handle;
-#ifndef IMX8MM_FIP_MMAP
+#ifndef IMX_FIP_MMAP
static const io_dev_connector_t *mmc_dev_con;
static uintptr_t mmc_dev_handle;
static const io_block_spec_t mmc_fip_spec = {
- .offset = IMX8MM_FIP_MMC_BASE,
- .length = IMX8MM_FIP_SIZE
+ .offset = IMX_FIP_MMC_BASE,
+ .length = IMX_FIP_SIZE
};
static const io_block_dev_spec_t mmc_dev_spec = {
/* It's used as temp buffer in block driver. */
.buffer = {
- .offset = IMX8MM_FIP_BASE,
+ .offset = IMX_FIP_BASE,
/* do we need a new value? */
- .length = IMX8MM_FIP_SIZE
+ .length = IMX_FIP_SIZE
},
.ops = {
.read = mmc_read_blocks,
@@ -51,8 +51,8 @@
static uintptr_t memmap_dev_handle;
static const io_block_spec_t fip_block_spec = {
- .offset = IMX8MM_FIP_BASE,
- .length = IMX8MM_FIP_SIZE
+ .offset = IMX_FIP_BASE,
+ .length = IMX_FIP_SIZE
};
static int open_memmap(const uintptr_t spec);
#endif
@@ -113,6 +113,7 @@
};
#endif /* TRUSTED_BOARD_BOOT */
+/* TODO: this structure is replicated multiple times. rationalize it ! */
struct plat_io_policy {
uintptr_t *dev_handle;
uintptr_t image_spec;
@@ -120,7 +121,7 @@
};
static const struct plat_io_policy policies[] = {
-#ifndef IMX8MM_FIP_MMAP
+#ifndef IMX_FIP_MMAP
[FIP_IMAGE_ID] = {
&mmc_dev_handle,
(uintptr_t)&mmc_fip_spec,
@@ -219,7 +220,7 @@
return result;
}
-#ifndef IMX8MM_FIP_MMAP
+#ifndef IMX_FIP_MMAP
static int open_mmc(const uintptr_t spec)
{
int result;
@@ -270,11 +271,11 @@
return result;
}
-void plat_imx8mm_io_setup(void)
+void plat_imx_io_setup(void)
{
int result __unused;
-#ifndef IMX8MM_FIP_MMAP
+#ifndef IMX_FIP_MMAP
result = register_io_dev_block(&mmc_dev_con);
assert(result == 0);
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index 3a95772..fdde9a9 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -16,6 +16,7 @@
-Iplat/imx/imx7/include \
-Idrivers/imx/timer \
-Idrivers/imx/usdhc \
+ -Iinclude/common/tbbr
# Translation tables library
include lib/xlat_tables_v2/xlat_tables.mk
@@ -46,7 +47,7 @@
plat/imx/imx7/common/imx7_bl2_el3_common.c \
plat/imx/imx7/common/imx7_helpers.S \
plat/imx/imx7/common/imx7_image_load.c \
- plat/imx/imx7/common/imx7_io_storage.c \
+ plat/imx/common/imx_io_storage.c \
plat/imx/common/aarch32/imx_uart_console.S \
${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/imx/imx7/common/imx7_bl2_el3_common.c b/plat/imx/imx7/common/imx7_bl2_el3_common.c
index 7f156e3..4e5028c 100644
--- a/plat/imx/imx7/common/imx7_bl2_el3_common.c
+++ b/plat/imx/imx7/common/imx7_bl2_el3_common.c
@@ -173,7 +173,7 @@
console_set_scope(&console, console_scope);
/* Open handles to persistent storage */
- plat_imx7_io_setup();
+ plat_imx_io_setup();
/* Setup higher-level functionality CAAM, RTC etc */
imx_caam_init();
@@ -183,7 +183,7 @@
VERBOSE("\tOPTEE 0x%08x-0x%08x\n", IMX7_OPTEE_BASE, IMX7_OPTEE_LIMIT);
VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
- VERBOSE("\tFIP 0x%08x-0x%08x\n", IMX7_FIP_BASE, IMX7_FIP_LIMIT);
+ VERBOSE("\tFIP 0x%08x-0x%08x\n", IMX_FIP_BASE, IMX_FIP_LIMIT);
VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", IMX7_DTB_OVERLAY_BASE, IMX7_DTB_OVERLAY_LIMIT);
VERBOSE("\tDTB 0x%08x-0x%08x\n", IMX7_DTB_BASE, IMX7_DTB_LIMIT);
VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", IMX7_UBOOT_BASE, IMX7_UBOOT_LIMIT);
diff --git a/plat/imx/imx7/common/imx7_io_storage.c b/plat/imx/imx7/common/imx7_io_storage.c
deleted file mode 100644
index 977181d..0000000
--- a/plat/imx/imx7/common/imx7_io_storage.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <drivers/io/io_block.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_fip.h>
-#include <drivers/io/io_memmap.h>
-#include <drivers/mmc.h>
-#include <tools_share/firmware_image_package.h>
-
-static const io_dev_connector_t *fip_dev_con;
-static uintptr_t fip_dev_handle;
-
-#ifndef IMX7_FIP_MMAP
-static const io_dev_connector_t *mmc_dev_con;
-static uintptr_t mmc_dev_handle;
-
-static const io_block_spec_t mmc_fip_spec = {
- .offset = IMX7_FIP_MMC_BASE,
- .length = IMX7_FIP_SIZE
-};
-
-static const io_block_dev_spec_t mmc_dev_spec = {
- /* It's used as temp buffer in block driver. */
- .buffer = {
- .offset = IMX7_FIP_BASE,
- /* do we need a new value? */
- .length = IMX7_FIP_SIZE
- },
- .ops = {
- .read = mmc_read_blocks,
- .write = mmc_write_blocks,
- },
- .block_size = MMC_BLOCK_SIZE,
-};
-
-static int open_mmc(const uintptr_t spec);
-
-#else
-static const io_dev_connector_t *memmap_dev_con;
-static uintptr_t memmap_dev_handle;
-
-static const io_block_spec_t fip_block_spec = {
- .offset = IMX7_FIP_BASE,
- .length = IMX7_FIP_SIZE
-};
-static int open_memmap(const uintptr_t spec);
-#endif
-static int open_fip(const uintptr_t spec);
-
-static const io_uuid_spec_t bl32_uuid_spec = {
- .uuid = UUID_SECURE_PAYLOAD_BL32,
-};
-
-static const io_uuid_spec_t bl32_extra1_uuid_spec = {
- .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
-};
-
-static const io_uuid_spec_t bl32_extra2_uuid_spec = {
- .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
-};
-
-static const io_uuid_spec_t bl33_uuid_spec = {
- .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
-};
-
-#if TRUSTED_BOARD_BOOT
-static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
- .uuid = UUID_TRUSTED_BOOT_FW_CERT,
-};
-
-static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
- .uuid = UUID_TRUSTED_KEY_CERT,
-};
-
-static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
- .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
-};
-
-static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
- .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
-};
-
-static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
- .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
-};
-
-static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
- .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
-};
-#endif /* TRUSTED_BOARD_BOOT */
-
-/* TODO: this structure is replicated multiple times. rationalize it ! */
-struct plat_io_policy {
- uintptr_t *dev_handle;
- uintptr_t image_spec;
- int (*check)(const uintptr_t spec);
-};
-
-static const struct plat_io_policy policies[] = {
-#ifndef IMX7_FIP_MMAP
- [FIP_IMAGE_ID] = {
- &mmc_dev_handle,
- (uintptr_t)&mmc_fip_spec,
- open_mmc
- },
-#else
- [FIP_IMAGE_ID] = {
- &memmap_dev_handle,
- (uintptr_t)&fip_block_spec,
- open_memmap
- },
-#endif
- [BL32_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl32_uuid_spec,
- open_fip
- },
- [BL32_EXTRA1_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl32_extra1_uuid_spec,
- open_fip
- },
- [BL32_EXTRA2_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl32_extra2_uuid_spec,
- open_fip
- },
- [BL33_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl33_uuid_spec,
- open_fip
- },
-#if TRUSTED_BOARD_BOOT
- [TRUSTED_BOOT_FW_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&tb_fw_cert_uuid_spec,
- open_fip
- },
- [TRUSTED_KEY_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&trusted_key_cert_uuid_spec,
- open_fip
- },
- [TRUSTED_OS_FW_KEY_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&tos_fw_key_cert_uuid_spec,
- open_fip
- },
- [NON_TRUSTED_FW_KEY_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&nt_fw_key_cert_uuid_spec,
- open_fip
- },
- [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&tos_fw_cert_uuid_spec,
- open_fip
- },
- [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&nt_fw_cert_uuid_spec,
- open_fip
- },
-#endif /* TRUSTED_BOARD_BOOT */
-};
-
-static int open_fip(const uintptr_t spec)
-{
- int result;
- uintptr_t local_image_handle;
-
- /* See if a Firmware Image Package is available */
- result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
- if (result == 0) {
- result = io_open(fip_dev_handle, spec, &local_image_handle);
- if (result == 0) {
- VERBOSE("Using FIP\n");
- io_close(local_image_handle);
- }
- }
- return result;
-}
-
-#ifndef IMX7_FIP_MMAP
-static int open_mmc(const uintptr_t spec)
-{
- int result;
- uintptr_t local_handle;
-
- result = io_dev_init(mmc_dev_handle, (uintptr_t)NULL);
- if (result == 0) {
- result = io_open(mmc_dev_handle, spec, &local_handle);
- if (result == 0)
- io_close(local_handle);
- }
- return result;
-}
-#else
-static int open_memmap(const uintptr_t spec)
-{
- int result;
- uintptr_t local_image_handle;
-
- result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
- if (result == 0) {
- result = io_open(memmap_dev_handle, spec, &local_image_handle);
- if (result == 0) {
- VERBOSE("Using Memmap\n");
- io_close(local_image_handle);
- }
- }
- return result;
-}
-#endif
-
-int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
- uintptr_t *image_spec)
-{
- int result;
- const struct plat_io_policy *policy;
-
- assert(image_id < ARRAY_SIZE(policies));
-
- policy = &policies[image_id];
- result = policy->check(policy->image_spec);
- assert(result == 0);
-
- *image_spec = policy->image_spec;
- *dev_handle = *policy->dev_handle;
-
- return result;
-}
-
-void plat_imx7_io_setup(void)
-{
- int result __unused;
-
-#ifndef IMX7_FIP_MMAP
- result = register_io_dev_block(&mmc_dev_con);
- assert(result == 0);
-
- result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_dev_spec,
- &mmc_dev_handle);
- assert(result == 0);
-
-#else
- result = register_io_dev_memmap(&memmap_dev_con);
- assert(result == 0);
-
- result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
- &memmap_dev_handle);
- assert(result == 0);
-
-#endif
- result = register_io_dev_fip(&fip_dev_con);
- assert(result == 0);
-
- result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
- &fip_dev_handle);
- assert(result == 0);
-}
diff --git a/plat/imx/imx7/include/imx7_def.h b/plat/imx/imx7/include/imx7_def.h
index 77a8ca3..d92a2d1 100644
--- a/plat/imx/imx7/include/imx7_def.h
+++ b/plat/imx/imx7/include/imx7_def.h
@@ -13,7 +13,7 @@
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
-void plat_imx7_io_setup(void);
+void plat_imx_io_setup(void);
void imx7_platform_setup(u_register_t arg1, u_register_t arg2,
u_register_t arg3, u_register_t arg4);
diff --git a/plat/imx/imx7/picopi/include/platform_def.h b/plat/imx/imx7/picopi/include/platform_def.h
index 141571c..5f2975d 100644
--- a/plat/imx/imx7/picopi/include/platform_def.h
+++ b/plat/imx/imx7/picopi/include/platform_def.h
@@ -92,12 +92,12 @@
#define IMX7_UBOOT_LIMIT (IMX7_UBOOT_BASE + IMX7_UBOOT_SIZE)
/* Define FIP image absolute location 0x80000000 - 0x80100000 */
-#define IMX7_FIP_SIZE 0x00100000
-#define IMX7_FIP_BASE (DRAM_BASE)
-#define IMX7_FIP_LIMIT (IMX7_FIP_BASE + IMX7_FIP_SIZE)
+#define IMX_FIP_SIZE 0x00100000
+#define IMX_FIP_BASE (DRAM_BASE)
+#define IMX_FIP_LIMIT (IMX_FIP_BASE + IMX_FIP_SIZE)
/* Define FIP image location at 1MB offset */
-#define IMX7_FIP_MMC_BASE (1024 * 1024)
+#define IMX_FIP_MMC_BASE (1024 * 1024)
/* Define the absolute location of DTB 0x83000000 - 0x83100000 */
#define IMX7_DTB_SIZE 0x00100000
diff --git a/plat/imx/imx7/warp7/include/platform_def.h b/plat/imx/imx7/warp7/include/platform_def.h
index 4afcb54..683e50d 100644
--- a/plat/imx/imx7/warp7/include/platform_def.h
+++ b/plat/imx/imx7/warp7/include/platform_def.h
@@ -94,12 +94,12 @@
#define IMX7_UBOOT_LIMIT (IMX7_UBOOT_BASE + IMX7_UBOOT_SIZE)
/* Define FIP image absolute location 0x80000000 - 0x80100000 */
-#define IMX7_FIP_SIZE 0x00100000
-#define IMX7_FIP_BASE (DRAM_BASE)
-#define IMX7_FIP_LIMIT (IMX7_FIP_BASE + IMX7_FIP_SIZE)
+#define IMX_FIP_SIZE 0x00100000
+#define IMX_FIP_BASE (DRAM_BASE)
+#define IMX_FIP_LIMIT (IMX_FIP_BASE + IMX_FIP_SIZE)
/* Define FIP image location at 1MB offset */
-#define IMX7_FIP_MMC_BASE (1024 * 1024)
+#define IMX_FIP_MMC_BASE (1024 * 1024)
/* Define the absolute location of DTB 0x83000000 - 0x83100000 */
#define IMX7_DTB_SIZE 0x00100000
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_image_load.c b/plat/imx/imx8m/imx8m_image_load.c
similarity index 100%
rename from plat/imx/imx8m/imx8mm/imx8mm_image_load.c
rename to plat/imx/imx8m/imx8m_image_load.c
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c
index 937774c..c39dd93 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c
@@ -88,7 +88,7 @@
imx8mm_usdhc_setup();
/* Open handles to a FIP image */
- plat_imx8mm_io_setup();
+ plat_imx_io_setup();
}
void bl2_el3_plat_arch_setup(void)
diff --git a/plat/imx/imx8m/imx8mm/include/imx8mm_private.h b/plat/imx/imx8m/imx8mm/include/imx8mm_private.h
index 52d13f0..5e0ef97 100644
--- a/plat/imx/imx8m/imx8mm/include/imx8mm_private.h
+++ b/plat/imx/imx8m/imx8mm/include/imx8mm_private.h
@@ -10,6 +10,6 @@
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
-void plat_imx8mm_io_setup(void);
+void plat_imx_io_setup(void);
#endif /* IMX8MM_PRIVATE_H */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 940d22b..e86938b 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -41,12 +41,12 @@
#define BL2_LIMIT U(0x940000)
#define BL31_BASE U(0x900000)
#define BL31_LIMIT U(0x920000)
-#define IMX8MM_FIP_BASE U(0x40310000)
-#define IMX8MM_FIP_SIZE U(0x000300000)
-#define IMX8MM_FIP_LIMIT U(FIP_BASE + FIP_SIZE)
+#define IMX_FIP_BASE U(0x40310000)
+#define IMX_FIP_SIZE U(0x000300000)
+#define IMX_FIP_LIMIT U(FIP_BASE + FIP_SIZE)
/* Define FIP image location on eMMC */
-#define IMX8MM_FIP_MMC_BASE U(0x100000)
+#define IMX_FIP_MMC_BASE U(0x100000)
#define PLAT_IMX8MM_BOOT_MMC_BASE U(0x30B50000) /* SD */
#else
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 1863233..ac5a809 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -63,8 +63,8 @@
drivers/io/io_storage.c \
drivers/imx/usdhc/imx_usdhc.c \
plat/imx/imx8m/imx8mm/imx8mm_bl2_mem_params_desc.c \
- plat/imx/imx8m/imx8mm/imx8mm_io_storage.c \
- plat/imx/imx8m/imx8mm/imx8mm_image_load.c \
+ plat/imx/common/imx_io_storage.c \
+ plat/imx/imx8m/imx8m_image_load.c \
lib/optee/optee_utils.c
endif
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c
new file mode 100644
index 0000000..08cbeeb
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <context.h>
+#include <drivers/arm/tzc380.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/mmc.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
+#include <lib/optee_utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <imx8m_caam.h>
+#include "imx8mp_private.h"
+#include <imx_aipstz.h>
+#include <imx_rdc.h>
+#include <imx_uart.h>
+#include <plat/common/platform.h>
+#include <plat_imx8.h>
+#include <platform_def.h>
+
+
+static const struct aipstz_cfg aipstz[] = {
+ {IMX_AIPSTZ1, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ2, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ3, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ4, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {0},
+};
+
+void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ static console_t console;
+ unsigned int i;
+
+ /* Enable CSU NS access permission */
+ for (i = 0U; i < 64; i++) {
+ mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff);
+ }
+
+ imx_aipstz_init(aipstz);
+
+ console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+ IMX_CONSOLE_BAUDRATE, &console);
+
+ generic_delay_timer_init();
+
+ /* select the CKIL source to 32K OSC */
+ mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+
+ /* Open handles to a FIP image */
+ plat_imx_io_setup();
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+}
+
+void bl2_platform_setup(void)
+{
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ int err = 0;
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+ bl_mem_params_node_t *pager_mem_params = NULL;
+ bl_mem_params_node_t *paged_mem_params = NULL;
+
+ assert(bl_mem_params);
+
+ switch (image_id) {
+ case BL32_IMAGE_ID:
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params);
+
+ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+ assert(paged_mem_params);
+
+ err = parse_optee_header(&bl_mem_params->ep_info,
+ &pager_mem_params->image_info,
+ &paged_mem_params->image_info);
+ if (err != 0) {
+ WARN("OPTEE header parse error.\n");
+ }
+
+ break;
+ default:
+ /* Do nothing in default case */
+ break;
+ }
+
+ return err;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return COUNTER_FREQUENCY;
+}
+
+void bl2_plat_runtime_setup(void)
+{
+ return;
+}
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c b/plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c
new file mode 100644
index 0000000..f2f6808
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+ {
+ .image_id = BL31_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+ {
+ .image_id = BL32_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t,
+ SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+ image_info_t, 0),
+
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_SIZE,
+
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+ image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_SIZE,
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+ {
+ /* This is a zero sized image so we don't set base or size */
+ .image_id = BL32_EXTRA2_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+ {
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t,
+ NON_SECURE | EXECUTABLE),
+ # ifdef PRELOADED_BL33_BASE
+ .ep_info.pc = PLAT_NS_IMAGE_OFFSET,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+ # else
+ .ep_info.pc = PLAT_NS_IMAGE_OFFSET,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = PLAT_NS_IMAGE_OFFSET,
+ .image_info.image_max_size = PLAT_NS_IMAGE_SIZE,
+ # endif /* PRELOADED_BL33_BASE */
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs);
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_rotpk.S b/plat/imx/imx8m/imx8mp/imx8mp_rotpk.S
new file mode 100644
index 0000000..a4c7ce1
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/imx8mp_rotpk.S
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global imx8mp_rotpk_hash
+ .global imx8mp_rotpk_hash_end
+imx8mp_rotpk_hash:
+ /* DER header */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* SHA256 */
+ .incbin ROTPK_HASH
+imx8mp_rotpk_hash_end:
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c b/plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c
new file mode 100644
index 0000000..5d1a6c2
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+extern char imx8mp_rotpk_hash[], imx8mp_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = imx8mp_rotpk_hash;
+ *key_len = imx8mp_rotpk_hash_end - imx8mp_rotpk_hash;
+ *flags = ROTPK_IS_HASH;
+
+ return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ *nv_ctr = 0;
+
+ return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 1;
+}
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/imx/imx8m/imx8mp/include/imx8mp_private.h b/plat/imx/imx8m/imx8mp/include/imx8mp_private.h
new file mode 100644
index 0000000..0a02334
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/include/imx8mp_private.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8MP_PRIVATE_H
+#define IMX8MP_PRIVATE_H
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void plat_imx_io_setup(void);
+
+#endif /* IMX8MP_PRIVATE_H */
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 832bed1..14b7ea0 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -6,6 +6,7 @@
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
+#include <common/tbbr/tbbr_img_def.h>
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
@@ -34,8 +35,23 @@
#define PLAT_WAIT_RET_STATE U(1)
#define PLAT_STOP_OFF_STATE U(3)
+#if defined(NEED_BL2)
+#define BL2_BASE U(0x960000)
+#define BL2_LIMIT U(0x980000)
+#define BL31_BASE U(0x940000)
+#define BL31_LIMIT U(0x960000)
+#define IMX_FIP_BASE U(0x40310000)
+#define IMX_FIP_SIZE U(0x000300000)
+#define IMX_FIP_LIMIT U(FIP_BASE + FIP_SIZE)
+
+/* Define FIP image location on eMMC */
+#define IMX_FIP_MMC_BASE U(0x100000)
+
+#define PLAT_IMX8MP_BOOT_MMC_BASE U(0x30B50000) /* SD */
+#else
#define BL31_BASE U(0x960000)
#define BL31_LIMIT U(0x980000)
+#endif
#define PLAT_PRI_BITS U(3)
#define PLAT_SDEI_CRITICAL_PRI 0x10
@@ -44,6 +60,7 @@
/* non-secure uboot base */
#define PLAT_NS_IMAGE_OFFSET U(0x40200000)
+#define PLAT_NS_IMAGE_SIZE U(0x00200000)
/* GICv3 base address */
#define PLAT_GICD_BASE U(0x38800000)
@@ -150,6 +167,10 @@
#define IMX_WDOG_B_RESET
+#define MAX_IO_HANDLES 3U
+#define MAX_IO_DEVICES 2U
+#define MAX_IO_BLOCK_DEVICES 1U
+
#define GIC_MAP MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW)
#define AIPS_MAP MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */
#define OCRAM_S_MAP MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_MEMORY | MT_RW) /* OCRAM_S */
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 6be2f98..823b5d6 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -6,7 +6,9 @@
PLAT_INCLUDES := -Iplat/imx/common/include \
-Iplat/imx/imx8m/include \
- -Iplat/imx/imx8m/imx8mp/include
+ -Iplat/imx/imx8m/imx8mp/include \
+ -Idrivers/imx/usdhc \
+ -Iinclude/common/tbbr
# Translation tables library
include lib/xlat_tables_v2/xlat_tables.mk
@@ -40,6 +42,96 @@
${IMX_GIC_SOURCES} \
${XLAT_TABLES_LIB_SRCS}
+ifeq (${NEED_BL2},yes)
+BL2_SOURCES += common/desc_image_load.c \
+ plat/imx/common/imx8_helpers.S \
+ plat/imx/common/imx_uart_console.S \
+ plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c \
+ plat/imx/imx8m/imx8mp/gpc.c \
+ plat/imx/imx8m/imx_aipstz.c \
+ plat/imx/imx8m/imx_rdc.c \
+ plat/imx/imx8m/imx8m_caam.c \
+ plat/common/plat_psci_common.c \
+ lib/cpus/aarch64/cortex_a53.S \
+ drivers/arm/tzc/tzc380.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ ${PLAT_GIC_SOURCES} \
+ ${PLAT_DRAM_SOURCES} \
+ ${XLAT_TABLES_LIB_SRCS} \
+ drivers/mmc/mmc.c \
+ drivers/io/io_block.c \
+ drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ drivers/imx/usdhc/imx_usdhc.c \
+ plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c \
+ plat/imx/common/imx_io_storage.c \
+ plat/imx/imx8m/imx8m_image_load.c \
+ lib/optee/optee_utils.c
+endif
+
+# Add the build options to pack BLx images and kernel device tree
+# in the FIP if the platform requires.
+ifneq ($(BL2),)
+RESET_TO_BL31 := 0
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
+ifneq ($(HW_CONFIG),)
+$(eval $(call TOOL_ADD_IMG,HW_CONFIG,--hw-config))
+endif
+
+ifeq (${NEED_BL2},yes)
+$(eval $(call add_define,NEED_BL2))
+LOAD_IMAGE_V2 := 1
+# Non-TF Boot ROM
+BL2_AT_EL3 := 1
+endif
+
+ifneq (${TRUSTED_BOARD_BOOT},0)
+
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+include drivers/auth/mbedtls/mbedtls_x509.mk
+
+AUTH_SOURCES := drivers/auth/auth_mod.c \
+ drivers/auth/crypto_mod.c \
+ drivers/auth/img_parser_mod.c \
+ drivers/auth/tbbr/tbbr_cot_common.c \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
+
+BL2_SOURCES += ${AUTH_SOURCES} \
+ plat/common/tbbr/plat_tbbr.c \
+ plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c \
+ plat/imx/imx8m/imx8mp/imx8mp_rotpk.S
+
+ROT_KEY = $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(eval $(call MAKE_LIB_DIRS))
+
+$(BUILD_PLAT)/bl2/imx8mp_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+
+$(ROT_KEY): | $(BUILD_PLAT)
+ @echo " OPENSSL $@"
+ @if [ ! -f $(ROT_KEY) ]; then \
+ openssl genrsa 2048 > $@ 2>/dev/null; \
+ fi
+
+$(ROTPK_HASH): $(ROT_KEY)
+ @echo " OPENSSL $@"
+ $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ openssl dgst -sha256 -binary > $@ 2>/dev/null
+endif
+
USE_COHERENT_MEM := 1
RESET_TO_BL31 := 1
A53_DISABLE_NON_TEMPORAL_HINT := 0
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index 0a89742..9550452 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -13,7 +13,7 @@
PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common
MARVELL_DRV_BASE := drivers/marvell
MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common
-HANDLE_EA_EL3_FIRST := 1
+ERRATA_A53_1530924 := 1
include plat/marvell/marvell.mk
@@ -53,7 +53,6 @@
$(PLAT_COMMON_BASE)/dram_win.c \
$(PLAT_COMMON_BASE)/io_addr_dec.c \
$(PLAT_COMMON_BASE)/marvell_plat_config.c \
- $(PLAT_COMMON_BASE)/a3700_ea.c \
$(PLAT_FAMILY_BASE)/$(PLAT)/plat_bl31_setup.c \
$(MARVELL_COMMON_BASE)/marvell_cci.c \
$(MARVELL_COMMON_BASE)/marvell_ddr_info.c \
@@ -63,6 +62,10 @@
$(PLAT_COMMON_BASE)/a3700_sip_svc.c \
$(MARVELL_DRV)
+ifeq ($(HANDLE_EA_EL3_FIRST),1)
+BL31_SOURCES += $(PLAT_COMMON_BASE)/a3700_ea.c
+endif
+
ifeq ($(CM3_SYSTEM_RESET),1)
BL31_SOURCES += $(PLAT_COMMON_BASE)/cm3_system_reset.c
endif
diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c
index 3a4f720..4a58fc6 100644
--- a/plat/marvell/armada/a3k/common/a3700_ea.c
+++ b/plat/marvell/armada/a3k/common/a3700_ea.c
@@ -8,14 +8,79 @@
#include <common/debug.h>
#include <arch_helpers.h>
#include <plat/common/platform.h>
+#include <bl31/ea_handle.h>
-#define ADVK_SERROR_SYNDROME 0xbf000002
+#define A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS 0xbf000002
+#if !ENABLE_BACKTRACE
+static const char *get_el_str(unsigned int el)
+{
+ if (el == MODE_EL3) {
+ return "EL3";
+ } else if (el == MODE_EL2) {
+ return "EL2";
+ }
+ return "S-EL1";
+}
+#endif /* !ENABLE_BACKTRACE */
+
+/*
+ * This source file with custom plat_ea_handler function is compiled only when
+ * building TF-A with compile option HANDLE_EA_EL3_FIRST=1
+ */
void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
void *handle, uint64_t flags)
{
- if (syndrome == ADVK_SERROR_SYNDROME)
+ unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
+
+ /*
+ * Asynchronous External Abort with syndrome 0xbf000002 on Cortex A53
+ * core means SError interrupt caused by AXI SLVERR on external access.
+ *
+ * In most cases this indicates a bug in U-Boot or Linux kernel driver
+ * pci-aardvark.c which implements access to A3700 PCIe config space.
+ * Driver does not wait for PCIe PIO transfer completion and try to
+ * start a new PCIe PIO transfer while previous has not finished yet.
+ * A3700 PCIe controller in this case sends SLVERR via AXI which results
+ * in a fatal Asynchronous SError interrupt on Cortex A53 CPU.
+ *
+ * Following patches fix that bug in U-Boot and Linux kernel drivers:
+ * https://source.denx.de/u-boot/u-boot/-/commit/eccbd4ad8e4e182638eafbfb87ac139c04f24a01
+ * https://git.kernel.org/stable/c/f18139966d072dab8e4398c95ce955a9742e04f7
+ *
+ * As a hacky workaround for unpatched U-Boot and Linux kernel drivers
+ * ignore all asynchronous aborts with that syndrome value received on
+ * CPU from level lower than EL3.
+ *
+ * Because these aborts are delivered on CPU asynchronously, they are
+ * imprecise and we cannot check the real reason of abort and neither
+ * who and why sent this abort. We expect that on A3700 it is always
+ * PCIe controller.
+ *
+ * Hence ignoring all aborts with this syndrome value is just a giant
+ * hack that we need only because of bugs in old U-Boot and Linux kernel
+ * versions and because it was decided that TF-A would implement this
+ * hack for U-Boot and Linux kernel it in this way. New patched U-Boot
+ * and kernel versions do not need it anymore.
+ *
+ * Links to discussion about this workaround:
+ * https://lore.kernel.org/linux-pci/20190316161243.29517-1-repk@triplefau.lt/
+ * https://lore.kernel.org/linux-pci/971be151d24312cc533989a64bd454b4@www.loen.fr/
+ * https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/1541
+ */
+ if (level < MODE_EL3 && ea_reason == ERROR_EA_ASYNC &&
+ syndrome == A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS) {
+ ERROR_NL();
+ ERROR("Ignoring Asynchronous External Abort with"
+ " syndrome 0x%llx received on 0x%lx from %s\n",
+ syndrome, read_mpidr_el1(), get_el_str(level));
+ ERROR("SError interrupt: AXI SLVERR on external access\n");
+ ERROR("This indicates a bug in pci-aardvark.c driver\n");
+ ERROR("Please update U-Boot/Linux to the latest version\n");
+ ERROR_NL();
+ console_flush();
return;
+ }
plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);
}
diff --git a/plat/mediatek/mt8195/bl31_plat_setup.c b/plat/mediatek/mt8195/bl31_plat_setup.c
index 8745454..dff6670 100644
--- a/plat/mediatek/mt8195/bl31_plat_setup.c
+++ b/plat/mediatek/mt8195/bl31_plat_setup.c
@@ -16,6 +16,7 @@
#include <lib/coreboot.h>
/* Platform Includes */
+#include <emi_mpu.h>
#include <mt_gic_v3.h>
#include <mt_spm.h>
#include <mt_timer.h>
@@ -90,6 +91,9 @@
ERROR("Failed to set default dcm on!!\n");
}
+ /* Initialize EMI MPU */
+ emi_mpu_init();
+
/* Initialize the GIC driver, CPU and distributor interfaces */
mt_gic_driver_init();
mt_gic_init();
diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
new file mode 100644
index 0000000..4330b77
--- /dev/null
+++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <emi_mpu.h>
+
+#if ENABLE_EMI_MPU_SW_LOCK
+static unsigned char region_lock_state[EMI_MPU_REGION_NUM];
+#endif
+
+#define EMI_MPU_START_MASK (0x00FFFFFF)
+#define EMI_MPU_END_MASK (0x00FFFFFF)
+#define EMI_MPU_APC_SW_LOCK_MASK (0x00FFFFFF)
+#define EMI_MPU_APC_HW_LOCK_MASK (0x80FFFFFF)
+
+static int _emi_mpu_set_protection(unsigned int start, unsigned int end,
+ unsigned int apc)
+{
+ unsigned int dgroup;
+ unsigned int region;
+
+ region = (start >> 24) & 0xFF;
+ start &= EMI_MPU_START_MASK;
+ dgroup = (end >> 24) & 0xFF;
+ end &= EMI_MPU_END_MASK;
+
+ if ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) {
+ WARN("invalid region, domain\n");
+ return -1;
+ }
+
+#if ENABLE_EMI_MPU_SW_LOCK
+ if (region_lock_state[region] == 1) {
+ WARN("invalid region\n");
+ return -1;
+ }
+
+ if ((dgroup == 0) && ((apc >> 31) & 0x1)) {
+ region_lock_state[region] = 1;
+ }
+
+ apc &= EMI_MPU_APC_SW_LOCK_MASK;
+#else
+ apc &= EMI_MPU_APC_HW_LOCK_MASK;
+#endif
+
+ if ((start >= DRAM_OFFSET) && (end >= start)) {
+ start -= DRAM_OFFSET;
+ end -= DRAM_OFFSET;
+ } else {
+ WARN("invalid range\n");
+ return -1;
+ }
+
+ mmio_write_32(EMI_MPU_SA(region), start);
+ mmio_write_32(EMI_MPU_EA(region), end);
+ mmio_write_32(EMI_MPU_APC(region, dgroup), apc);
+
+#if defined(SUB_EMI_MPU_BASE)
+ mmio_write_32(SUB_EMI_MPU_SA(region), start);
+ mmio_write_32(SUB_EMI_MPU_EA(region), end);
+ mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), apc);
+#endif
+ return 1;
+}
+
+int emi_mpu_set_protection(struct emi_region_info_t *region_info)
+{
+ unsigned int start, end;
+ int i;
+
+ if (region_info->region >= EMI_MPU_REGION_NUM) {
+ WARN("invalid region\n");
+ return -1;
+ }
+
+ start = (unsigned int)(region_info->start >> EMI_MPU_ALIGN_BITS) |
+ (region_info->region << 24);
+
+ for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) {
+ end = (unsigned int)(region_info->end >> EMI_MPU_ALIGN_BITS) |
+ (i << 24);
+ _emi_mpu_set_protection(start, end, region_info->apc[i]);
+ }
+
+ return 0;
+}
+
+void emi_mpu_init(void)
+{
+ /* TODO: more setting for EMI MPU. */
+}
diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h
new file mode 100644
index 0000000..415146e
--- /dev/null
+++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EMI_MPU_H
+#define EMI_MPU_H
+
+#include <platform_def.h>
+
+#define ENABLE_EMI_MPU_SW_LOCK 1
+
+#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x000)
+#define EMI_MPU_DBG (EMI_MPU_BASE + 0x004)
+#define EMI_MPU_SA0 (EMI_MPU_BASE + 0x100)
+#define EMI_MPU_EA0 (EMI_MPU_BASE + 0x200)
+#define EMI_MPU_SA(region) (EMI_MPU_SA0 + (region * 4))
+#define EMI_MPU_EA(region) (EMI_MPU_EA0 + (region * 4))
+#define EMI_MPU_APC0 (EMI_MPU_BASE + 0x300)
+#define EMI_MPU_APC(region, dgroup) (EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100))
+#define EMI_MPU_CTRL_D0 (EMI_MPU_BASE + 0x800)
+#define EMI_MPU_CTRL_D(domain) (EMI_MPU_CTRL_D0 + (domain * 4))
+#define EMI_RG_MASK_D0 (EMI_MPU_BASE + 0x900)
+#define EMI_RG_MASK_D(domain) (EMI_RG_MASK_D0 + (domain * 4))
+#define EMI_MPU_START (0x000)
+#define EMI_MPU_END (0x93C)
+
+#define SUB_EMI_MPU_CTRL (SUB_EMI_MPU_BASE + 0x000)
+#define SUB_EMI_MPU_DBG (SUB_EMI_MPU_BASE + 0x004)
+#define SUB_EMI_MPU_SA0 (SUB_EMI_MPU_BASE + 0x100)
+#define SUB_EMI_MPU_EA0 (SUB_EMI_MPU_BASE + 0x200)
+#define SUB_EMI_MPU_SA(region) (SUB_EMI_MPU_SA0 + (region * 4))
+#define SUB_EMI_MPU_EA(region) (SUB_EMI_MPU_EA0 + (region * 4))
+#define SUB_EMI_MPU_APC0 (SUB_EMI_MPU_BASE + 0x300)
+#define SUB_EMI_MPU_APC(region, dgroup) (SUB_EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100))
+#define SUB_EMI_MPU_CTRL_D0 (SUB_EMI_MPU_BASE + 0x800)
+#define SUB_EMI_MPU_CTRL_D(domain) (SUB_EMI_MPU_CTRL_D0 + (domain * 4))
+#define SUB_EMI_RG_MASK_D0 (SUB_EMI_MPU_BASE + 0x900)
+#define SUB_EMI_RG_MASK_D(domain) (SUB_EMI_RG_MASK_D0 + (domain * 4))
+
+#define EMI_MPU_DOMAIN_NUM (16)
+#define EMI_MPU_REGION_NUM (32)
+#define EMI_MPU_ALIGN_BITS (16)
+#define DRAM_OFFSET (0x40000000 >> EMI_MPU_ALIGN_BITS)
+
+#define NO_PROTECTION 0
+#define SEC_RW 1
+#define SEC_RW_NSEC_R 2
+#define SEC_RW_NSEC_W 3
+#define SEC_R_NSEC_R 4
+#define FORBIDDEN 5
+#define SEC_R_NSEC_RW 6
+
+#define LOCK 1
+#define UNLOCK 0
+
+#define EMI_MPU_DGROUP_NUM (EMI_MPU_DOMAIN_NUM / 8)
+
+#if (EMI_MPU_DGROUP_NUM == 1)
+#define SET_ACCESS_PERMISSION(apc_ary, lock, d7, d6, d5, d4, d3, d2, d1, d0) \
+do { \
+ apc_ary[1] = 0; \
+ apc_ary[0] = \
+ (((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) | \
+ (((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) | \
+ (((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) | \
+ (((unsigned int) d1) << 3) | ((unsigned int) d0) | \
+ ((unsigned int) lock << 31); \
+} while (0)
+#elif (EMI_MPU_DGROUP_NUM == 2)
+#define SET_ACCESS_PERMISSION(apc_ary, lock, d15, d14, d13, d12, d11, d10, \
+ d9, d8, d7, d6, d5, d4, d3, d2, d1, d0) \
+do { \
+ apc_ary[1] = \
+ (((unsigned int) d15) << 21) | (((unsigned int) d14) << 18) | \
+ (((unsigned int) d13) << 15) | (((unsigned int) d12) << 12) | \
+ (((unsigned int) d11) << 9) | (((unsigned int) d10) << 6) | \
+ (((unsigned int) d9) << 3) | ((unsigned int) d8); \
+ apc_ary[0] = \
+ (((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) | \
+ (((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) | \
+ (((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) | \
+ (((unsigned int) d1) << 3) | ((unsigned int) d0) | \
+ ((unsigned int) lock << 31); \
+} while (0)
+#endif
+
+struct emi_region_info_t {
+ unsigned long long start;
+ unsigned long long end;
+ unsigned int region;
+ unsigned int apc[EMI_MPU_DGROUP_NUM];
+};
+
+void emi_mpu_init(void);
+
+#endif
diff --git a/plat/mediatek/mt8195/drivers/spm/build.mk b/plat/mediatek/mt8195/drivers/spm/build.mk
index d1ee092..28b2d07 100644
--- a/plat/mediatek/mt8195/drivers/spm/build.mk
+++ b/plat/mediatek/mt8195/drivers/spm/build.mk
@@ -30,7 +30,8 @@
${CUR_SPM_FOLDER}/constraints/mt_spm_rc_syspll.c \
${CUR_SPM_FOLDER}/mt_spm_cond.c \
${CUR_SPM_FOLDER}/mt_spm_suspend.c \
- ${CUR_SPM_FOLDER}/mt_spm_idle.c
+ ${CUR_SPM_FOLDER}/mt_spm_idle.c \
+ ${CUR_SPM_FOLDER}/mt_spm_vcorefs.c
ifeq (${MT_SPM_FEATURE_SUPPORT}, no)
PLAT_SPM_DEBUG_CFLAGS += -DATF_PLAT_SPM_UNSUPPORT
diff --git a/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c
new file mode 100644
index 0000000..6a85b5c
--- /dev/null
+++ b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stddef.h>
+#include <string.h>
+#include <common/debug.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <mt_spm.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_pmic_wrap.h>
+#include <mt_spm_reg.h>
+#include <mt_spm_vcorefs.h>
+#include <mtk_plat_common.h>
+#include <mtk_sip_svc.h>
+#include <platform_def.h>
+
+#define VCORE_MAX_OPP 4
+#define DRAM_MAX_OPP 7
+
+static bool spm_dvfs_init_done;
+static bool dvfs_enable_done;
+static int vcore_opp_0_uv = 750000;
+static int vcore_opp_1_uv = 650000;
+static int vcore_opp_2_uv = 600000;
+static int vcore_opp_3_uv = 550000;
+
+static struct reg_config dvfsrc_init_configs[] = {
+ { DVFSRC_HRT_REQ_UNIT, 0x0000001E },
+ { DVFSRC_DEBOUNCE_TIME, 0x19651965 },
+ { DVFSRC_TIMEOUT_NEXTREQ, 0x00000015 },
+ { DVFSRC_LEVEL_MASK, 0x000EE000 },
+ { DVFSRC_DDR_QOS0, 0x00000019 },
+ { DVFSRC_DDR_QOS1, 0x00000026 },
+ { DVFSRC_DDR_QOS2, 0x00000033 },
+ { DVFSRC_DDR_QOS3, 0x0000003B },
+ { DVFSRC_DDR_QOS4, 0x0000004C },
+ { DVFSRC_DDR_QOS5, 0x00000066 },
+ { DVFSRC_DDR_QOS6, 0x00660066 },
+ { DVFSRC_LEVEL_LABEL_0_1, 0x50436053 },
+ { DVFSRC_LEVEL_LABEL_2_3, 0x40335042 },
+ { DVFSRC_LEVEL_LABEL_4_5, 0x40314032 },
+ { DVFSRC_LEVEL_LABEL_6_7, 0x30223023 },
+ { DVFSRC_LEVEL_LABEL_8_9, 0x20133021 },
+ { DVFSRC_LEVEL_LABEL_10_11, 0x20112012 },
+ { DVFSRC_LEVEL_LABEL_12_13, 0x10032010 },
+ { DVFSRC_LEVEL_LABEL_14_15, 0x10011002 },
+ { DVFSRC_LEVEL_LABEL_16_17, 0x00131000 },
+ { DVFSRC_LEVEL_LABEL_18_19, 0x00110012 },
+ { DVFSRC_LEVEL_LABEL_20_21, 0x00000010 },
+ { DVFSRC_MD_LATENCY_IMPROVE, 0x00000040 },
+ { DVFSRC_DDR_REQUEST, 0x00004321 },
+ { DVFSRC_DDR_REQUEST3, 0x00000065 },
+ { DVFSRC_DDR_ADD_REQUEST, 0x66543210 },
+ { DVFSRC_HRT_REQUEST, 0x66654321 },
+ { DVFSRC_DDR_REQUEST5, 0x54321000 },
+ { DVFSRC_DDR_REQUEST7, 0x66000000 },
+ { DVFSRC_VCORE_USER_REQ, 0x00010A29 },
+ { DVFSRC_HRT_HIGH_3, 0x18A618A6 },
+ { DVFSRC_HRT_HIGH_2, 0x18A61183 },
+ { DVFSRC_HRT_HIGH_1, 0x0D690B80 },
+ { DVFSRC_HRT_HIGH, 0x070804B0 },
+ { DVFSRC_HRT_LOW_3, 0x18A518A5 },
+ { DVFSRC_HRT_LOW_2, 0x18A51182 },
+ { DVFSRC_HRT_LOW_1, 0x0D680B7F },
+ { DVFSRC_HRT_LOW, 0x070704AF },
+ { DVFSRC_BASIC_CONTROL_3, 0x00000006 },
+ { DVFSRC_INT_EN, 0x00000002 },
+ { DVFSRC_QOS_EN, 0x0000407C },
+ { DVFSRC_HRT_BW_BASE, 0x00000004 },
+ { DVFSRC_PCIE_VCORE_REQ, 0x65908101 },
+ { DVFSRC_CURRENT_FORCE, 0x00000001 },
+ { DVFSRC_BASIC_CONTROL, 0x6698444B },
+ { DVFSRC_BASIC_CONTROL, 0x6698054B },
+ { DVFSRC_CURRENT_FORCE, 0x00000000 },
+};
+
+static struct pwr_ctrl vcorefs_ctrl = {
+ .wake_src = R12_REG_CPU_WAKEUP,
+
+ /* default VCORE DVFS is disabled */
+ .pcm_flags = (SPM_FLAG_RUN_COMMON_SCENARIO |
+ SPM_FLAG_DISABLE_VCORE_DVS | SPM_FLAG_DISABLE_VCORE_DFS),
+
+ /* SPM_AP_STANDBY_CON */
+ /* [0] */
+ .reg_wfi_op = 0,
+ /* [1] */
+ .reg_wfi_type = 0,
+ /* [2] */
+ .reg_mp0_cputop_idle_mask = 0,
+ /* [3] */
+ .reg_mp1_cputop_idle_mask = 0,
+ /* [4] */
+ .reg_mcusys_idle_mask = 0,
+ /* [25] */
+ .reg_md_apsrc_1_sel = 0,
+ /* [26] */
+ .reg_md_apsrc_0_sel = 0,
+ /* [29] */
+ .reg_conn_apsrc_sel = 0,
+
+ /* SPM_SRC_REQ */
+ /* [0] */
+ .reg_spm_apsrc_req = 0,
+ /* [1] */
+ .reg_spm_f26m_req = 0,
+ /* [3] */
+ .reg_spm_infra_req = 0,
+ /* [4] */
+ .reg_spm_vrf18_req = 0,
+ /* [7] FIXME: default disable HW Auto S1*/
+ .reg_spm_ddr_en_req = 1,
+ /* [8] */
+ .reg_spm_dvfs_req = 0,
+ /* [9] */
+ .reg_spm_sw_mailbox_req = 0,
+ /* [10] */
+ .reg_spm_sspm_mailbox_req = 0,
+ /* [11] */
+ .reg_spm_adsp_mailbox_req = 0,
+ /* [12] */
+ .reg_spm_scp_mailbox_req = 0,
+
+ /* SPM_SRC_MASK */
+ /* [0] */
+ .reg_sspm_srcclkena_0_mask_b = 1,
+ /* [1] */
+ .reg_sspm_infra_req_0_mask_b = 1,
+ /* [2] */
+ .reg_sspm_apsrc_req_0_mask_b = 1,
+ /* [3] */
+ .reg_sspm_vrf18_req_0_mask_b = 1,
+ /* [4] */
+ .reg_sspm_ddr_en_0_mask_b = 1,
+ /* [5] */
+ .reg_scp_srcclkena_mask_b = 1,
+ /* [6] */
+ .reg_scp_infra_req_mask_b = 1,
+ /* [7] */
+ .reg_scp_apsrc_req_mask_b = 1,
+ /* [8] */
+ .reg_scp_vrf18_req_mask_b = 1,
+ /* [9] */
+ .reg_scp_ddr_en_mask_b = 1,
+ /* [10] */
+ .reg_audio_dsp_srcclkena_mask_b = 1,
+ /* [11] */
+ .reg_audio_dsp_infra_req_mask_b = 1,
+ /* [12] */
+ .reg_audio_dsp_apsrc_req_mask_b = 1,
+ /* [13] */
+ .reg_audio_dsp_vrf18_req_mask_b = 1,
+ /* [14] */
+ .reg_audio_dsp_ddr_en_mask_b = 1,
+ /* [15] */
+ .reg_apu_srcclkena_mask_b = 1,
+ /* [16] */
+ .reg_apu_infra_req_mask_b = 1,
+ /* [17] */
+ .reg_apu_apsrc_req_mask_b = 1,
+ /* [18] */
+ .reg_apu_vrf18_req_mask_b = 1,
+ /* [19] */
+ .reg_apu_ddr_en_mask_b = 1,
+ /* [20] */
+ .reg_cpueb_srcclkena_mask_b = 1,
+ /* [21] */
+ .reg_cpueb_infra_req_mask_b = 1,
+ /* [22] */
+ .reg_cpueb_apsrc_req_mask_b = 1,
+ /* [23] */
+ .reg_cpueb_vrf18_req_mask_b = 1,
+ /* [24] */
+ .reg_cpueb_ddr_en_mask_b = 1,
+ /* [25] */
+ .reg_bak_psri_srcclkena_mask_b = 0,
+ /* [26] */
+ .reg_bak_psri_infra_req_mask_b = 0,
+ /* [27] */
+ .reg_bak_psri_apsrc_req_mask_b = 0,
+ /* [28] */
+ .reg_bak_psri_vrf18_req_mask_b = 0,
+ /* [29] */
+ .reg_bak_psri_ddr_en_mask_b = 0,
+
+ /* SPM_SRC2_MASK */
+ /* [0] */
+ .reg_msdc0_srcclkena_mask_b = 1,
+ /* [1] */
+ .reg_msdc0_infra_req_mask_b = 1,
+ /* [2] */
+ .reg_msdc0_apsrc_req_mask_b = 1,
+ /* [3] */
+ .reg_msdc0_vrf18_req_mask_b = 1,
+ /* [4] */
+ .reg_msdc0_ddr_en_mask_b = 1,
+ /* [5] */
+ .reg_msdc1_srcclkena_mask_b = 1,
+ /* [6] */
+ .reg_msdc1_infra_req_mask_b = 1,
+ /* [7] */
+ .reg_msdc1_apsrc_req_mask_b = 1,
+ /* [8] */
+ .reg_msdc1_vrf18_req_mask_b = 1,
+ /* [9] */
+ .reg_msdc1_ddr_en_mask_b = 1,
+ /* [10] */
+ .reg_msdc2_srcclkena_mask_b = 1,
+ /* [11] */
+ .reg_msdc2_infra_req_mask_b = 1,
+ /* [12] */
+ .reg_msdc2_apsrc_req_mask_b = 1,
+ /* [13] */
+ .reg_msdc2_vrf18_req_mask_b = 1,
+ /* [14] */
+ .reg_msdc2_ddr_en_mask_b = 1,
+ /* [15] */
+ .reg_ufs_srcclkena_mask_b = 1,
+ /* [16] */
+ .reg_ufs_infra_req_mask_b = 1,
+ /* [17] */
+ .reg_ufs_apsrc_req_mask_b = 1,
+ /* [18] */
+ .reg_ufs_vrf18_req_mask_b = 1,
+ /* [19] */
+ .reg_ufs_ddr_en_mask_b = 1,
+ /* [20] */
+ .reg_usb_srcclkena_mask_b = 1,
+ /* [21] */
+ .reg_usb_infra_req_mask_b = 1,
+ /* [22] */
+ .reg_usb_apsrc_req_mask_b = 1,
+ /* [23] */
+ .reg_usb_vrf18_req_mask_b = 1,
+ /* [24] */
+ .reg_usb_ddr_en_mask_b = 1,
+ /* [25] */
+ .reg_pextp_p0_srcclkena_mask_b = 1,
+ /* [26] */
+ .reg_pextp_p0_infra_req_mask_b = 1,
+ /* [27] */
+ .reg_pextp_p0_apsrc_req_mask_b = 1,
+ /* [28] */
+ .reg_pextp_p0_vrf18_req_mask_b = 1,
+ /* [29] */
+ .reg_pextp_p0_ddr_en_mask_b = 1,
+
+ /* SPM_SRC3_MASK */
+ /* [0] */
+ .reg_pextp_p1_srcclkena_mask_b = 1,
+ /* [1] */
+ .reg_pextp_p1_infra_req_mask_b = 1,
+ /* [2] */
+ .reg_pextp_p1_apsrc_req_mask_b = 1,
+ /* [3] */
+ .reg_pextp_p1_vrf18_req_mask_b = 1,
+ /* [4] */
+ .reg_pextp_p1_ddr_en_mask_b = 1,
+ /* [5] */
+ .reg_gce0_infra_req_mask_b = 1,
+ /* [6] */
+ .reg_gce0_apsrc_req_mask_b = 1,
+ /* [7] */
+ .reg_gce0_vrf18_req_mask_b = 1,
+ /* [8] */
+ .reg_gce0_ddr_en_mask_b = 1,
+ /* [9] */
+ .reg_gce1_infra_req_mask_b = 1,
+ /* [10] */
+ .reg_gce1_apsrc_req_mask_b = 1,
+ /* [11] */
+ .reg_gce1_vrf18_req_mask_b = 1,
+ /* [12] */
+ .reg_gce1_ddr_en_mask_b = 1,
+ /* [13] */
+ .reg_spm_srcclkena_reserved_mask_b = 1,
+ /* [14] */
+ .reg_spm_infra_req_reserved_mask_b = 1,
+ /* [15] */
+ .reg_spm_apsrc_req_reserved_mask_b = 1,
+ /* [16] */
+ .reg_spm_vrf18_req_reserved_mask_b = 1,
+ /* [17] */
+ .reg_spm_ddr_en_reserved_mask_b = 1,
+ /* [18] */
+ .reg_disp0_apsrc_req_mask_b = 1,
+ /* [19] */
+ .reg_disp0_ddr_en_mask_b = 1,
+ /* [20] */
+ .reg_disp1_apsrc_req_mask_b = 1,
+ /* [21] */
+ .reg_disp1_ddr_en_mask_b = 1,
+ /* [22] */
+ .reg_disp2_apsrc_req_mask_b = 1,
+ /* [23] */
+ .reg_disp2_ddr_en_mask_b = 1,
+ /* [24] */
+ .reg_disp3_apsrc_req_mask_b = 1,
+ /* [25] */
+ .reg_disp3_ddr_en_mask_b = 1,
+ /* [26] */
+ .reg_infrasys_apsrc_req_mask_b = 0,
+ /* [27] */
+ .reg_infrasys_ddr_en_mask_b = 1,
+
+ /* [28] */
+ .reg_cg_check_srcclkena_mask_b = 1,
+ /* [29] */
+ .reg_cg_check_apsrc_req_mask_b = 1,
+ /* [30] */
+ .reg_cg_check_vrf18_req_mask_b = 1,
+ /* [31] */
+ .reg_cg_check_ddr_en_mask_b = 1,
+
+ /* SPM_SRC4_MASK */
+ /* [8:0] */
+ .reg_mcusys_merge_apsrc_req_mask_b = 0x11,
+ /* [17:9] */
+ .reg_mcusys_merge_ddr_en_mask_b = 0x11,
+ /* [19:18] */
+ .reg_dramc_md32_infra_req_mask_b = 0,
+ /* [21:20] */
+ .reg_dramc_md32_vrf18_req_mask_b = 0,
+ /* [23:22] */
+ .reg_dramc_md32_ddr_en_mask_b = 0,
+ /* [24] */
+ .reg_dvfsrc_event_trigger_mask_b = 1,
+
+ /* SPM_WAKEUP_EVENT_MASK2 */
+ /* [3:0] */
+ .reg_sc_sw2spm_wakeup_mask_b = 0,
+ /* [4] */
+ .reg_sc_adsp2spm_wakeup_mask_b = 0,
+ /* [8:5] */
+ .reg_sc_sspm2spm_wakeup_mask_b = 0,
+ /* [9] */
+ .reg_sc_scp2spm_wakeup_mask_b = 0,
+ /* [10] */
+ .reg_csyspwrup_ack_mask = 0,
+ /* [11] */
+ .reg_csyspwrup_req_mask = 1,
+
+ /* SPM_WAKEUP_EVENT_MASK */
+ /* [31:0] */
+ .reg_wakeup_event_mask = 0xEFFFFFFF,
+
+ /* SPM_WAKEUP_EVENT_EXT_MASK */
+ /* [31:0] */
+ .reg_ext_wakeup_event_mask = 0xFFFFFFFF,
+};
+
+struct spm_lp_scen __spm_vcorefs = {
+ .pwrctrl = &vcorefs_ctrl,
+};
+
+static void spm_vcorefs_pwarp_cmd(uint64_t cmd, uint64_t val)
+{
+ if (cmd < NR_IDX_ALL) {
+ mt_spm_pmic_wrap_set_cmd(PMIC_WRAP_PHASE_ALLINONE, cmd, val);
+ } else {
+ INFO("cmd out of range!\n");
+ }
+}
+
+void spm_dvfsfw_init(uint64_t boot_up_opp, uint64_t dram_issue)
+{
+ if (spm_dvfs_init_done == false) {
+ mmio_write_32(SPM_DVFS_MISC, (mmio_read_32(SPM_DVFS_MISC) &
+ ~(SPM_DVFS_FORCE_ENABLE_LSB)) | (SPM_DVFSRC_ENABLE_LSB));
+
+ mmio_write_32(SPM_DVFS_LEVEL, 0x00000001);
+ mmio_write_32(SPM_DVS_DFS_LEVEL, 0x00010001);
+
+ spm_dvfs_init_done = true;
+ }
+}
+
+void __spm_sync_vcore_dvfs_power_control(struct pwr_ctrl *dest_pwr_ctrl,
+ const struct pwr_ctrl *src_pwr_ctrl)
+{
+ uint32_t dvfs_mask = SPM_FLAG_DISABLE_VCORE_DVS |
+ SPM_FLAG_DISABLE_VCORE_DFS |
+ SPM_FLAG_ENABLE_VOLTAGE_BIN;
+
+ dest_pwr_ctrl->pcm_flags = (dest_pwr_ctrl->pcm_flags & (~dvfs_mask)) |
+ (src_pwr_ctrl->pcm_flags & dvfs_mask);
+
+ if (dest_pwr_ctrl->pcm_flags_cust) {
+ dest_pwr_ctrl->pcm_flags_cust = (dest_pwr_ctrl->pcm_flags_cust & (~dvfs_mask)) |
+ (src_pwr_ctrl->pcm_flags & dvfs_mask);
+ }
+}
+
+void spm_go_to_vcorefs(uint64_t spm_flags)
+{
+ __spm_set_power_control(__spm_vcorefs.pwrctrl);
+ __spm_set_wakeup_event(__spm_vcorefs.pwrctrl);
+ __spm_set_pcm_flags(__spm_vcorefs.pwrctrl);
+ __spm_send_cpu_wakeup_event();
+}
+
+uint64_t spm_vcorefs_args(uint64_t x1, uint64_t x2, uint64_t x3)
+{
+ uint64_t ret = 0U;
+ uint64_t cmd = x1;
+ uint64_t spm_flags;
+
+ switch (cmd) {
+ case VCOREFS_SMC_CMD_0:
+ spm_dvfsfw_init(x2, x3);
+ break;
+ case VCOREFS_SMC_CMD_1:
+ spm_flags = SPM_FLAG_RUN_COMMON_SCENARIO;
+ if (x2 & SPM_FLAG_DISABLE_VCORE_DVS)
+ spm_flags |= SPM_FLAG_DISABLE_VCORE_DVS;
+ if (x2 & SPM_FLAG_DISABLE_VCORE_DFS)
+ spm_flags |= SPM_FLAG_DISABLE_VCORE_DFS;
+ spm_go_to_vcorefs(spm_flags);
+ break;
+ case VCOREFS_SMC_CMD_3:
+ spm_vcorefs_pwarp_cmd(x2, x3);
+ break;
+ case VCOREFS_SMC_CMD_2:
+ case VCOREFS_SMC_CMD_4:
+ case VCOREFS_SMC_CMD_5:
+ case VCOREFS_SMC_CMD_7:
+ default:
+ break;
+ }
+ return ret;
+}
+
+static void dvfsrc_init(void)
+{
+ int i;
+ int count = ARRAY_SIZE(dvfsrc_init_configs);
+
+ if (dvfs_enable_done == false) {
+ for (i = 0; i < count; i++) {
+ mmio_write_32(dvfsrc_init_configs[i].offset,
+ dvfsrc_init_configs[i].val);
+ }
+
+ mmio_write_32(DVFSRC_QOS_EN, 0x0011007C);
+
+ dvfs_enable_done = true;
+ }
+}
+
+static void spm_vcorefs_vcore_setting(uint64_t flag)
+{
+ spm_vcorefs_pwarp_cmd(3, __vcore_uv_to_pmic(vcore_opp_3_uv));
+ spm_vcorefs_pwarp_cmd(2, __vcore_uv_to_pmic(vcore_opp_2_uv));
+ spm_vcorefs_pwarp_cmd(1, __vcore_uv_to_pmic(vcore_opp_1_uv));
+ spm_vcorefs_pwarp_cmd(0, __vcore_uv_to_pmic(vcore_opp_0_uv));
+}
+
+int spm_vcorefs_get_vcore(unsigned int gear)
+{
+ int ret_val;
+
+ switch (gear) {
+ case 3:
+ ret_val = vcore_opp_0_uv;
+ break;
+ case 2:
+ ret_val = vcore_opp_1_uv;
+ break;
+ case 1:
+ ret_val = vcore_opp_2_uv;
+ break;
+ case 0:
+ default:
+ ret_val = vcore_opp_3_uv;
+ break;
+ }
+ return ret_val;
+}
+
+uint64_t spm_vcorefs_v2_args(u_register_t x1, u_register_t x2, u_register_t x3, u_register_t *x4)
+{
+ uint64_t ret = 0U;
+ uint64_t cmd = x1;
+ uint64_t spm_flags;
+
+ switch (cmd) {
+ case VCOREFS_SMC_CMD_INIT:
+ /* vcore_dvfs init + kick */
+ spm_dvfsfw_init(0, 0);
+ spm_vcorefs_vcore_setting(x3 & 0xF);
+ spm_flags = SPM_FLAG_RUN_COMMON_SCENARIO;
+ if (x2 & 0x1) {
+ spm_flags |= SPM_FLAG_DISABLE_VCORE_DVS;
+ }
+ if (x2 & 0x2) {
+ spm_flags |= SPM_FLAG_DISABLE_VCORE_DFS;
+ }
+ spm_go_to_vcorefs(spm_flags);
+ dvfsrc_init();
+ *x4 = 0U;
+ break;
+ case VCOREFS_SMC_CMD_OPP_TYPE:
+ /* get dram type */
+ *x4 = 0U;
+ break;
+ case VCOREFS_SMC_CMD_FW_TYPE:
+ *x4 = 0U;
+ break;
+ case VCOREFS_SMC_CMD_GET_UV:
+ *x4 = spm_vcorefs_get_vcore(x2);
+ break;
+ case VCOREFS_SMC_CMD_GET_NUM_V:
+ *x4 = VCORE_MAX_OPP;
+ break;
+ case VCOREFS_SMC_CMD_GET_NUM_F:
+ *x4 = DRAM_MAX_OPP;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
diff --git a/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.h b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.h
new file mode 100644
index 0000000..b08fcce
--- /dev/null
+++ b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.h
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __MT_SPM_VCOREFS__H__
+#define __MT_SPM_VCOREFS__H__
+
+int spm_vcorefs_get_vcore(unsigned int gear);
+uint64_t spm_vcorefs_v2_args(u_register_t x1, u_register_t x2, u_register_t x3,
+ u_register_t *x4);
+
+enum vcorefs_smc_cmd {
+ VCOREFS_SMC_CMD_0 = 0,
+ VCOREFS_SMC_CMD_1,
+ VCOREFS_SMC_CMD_2,
+ VCOREFS_SMC_CMD_3,
+ VCOREFS_SMC_CMD_4,
+ /* check spmfw status */
+ VCOREFS_SMC_CMD_5,
+
+ /* get spmfw type */
+ VCOREFS_SMC_CMD_6,
+
+ /* get spm reg status */
+ VCOREFS_SMC_CMD_7,
+
+ NUM_VCOREFS_SMC_CMD,
+};
+
+enum vcorefs_smc_cmd_new {
+ VCOREFS_SMC_CMD_INIT = 0,
+ VCOREFS_SMC_CMD_KICK = 1,
+ VCOREFS_SMC_CMD_OPP_TYPE = 2,
+ VCOREFS_SMC_CMD_FW_TYPE = 3,
+ VCOREFS_SMC_CMD_GET_UV = 4,
+ VCOREFS_SMC_CMD_GET_FREQ = 5,
+ VCOREFS_SMC_CMD_GET_NUM_V = 6,
+ VCOREFS_SMC_CMD_GET_NUM_F = 7,
+ VCOREFS_SMC_CMD_FB_ACTION = 8,
+ /*chip specific setting */
+ VCOREFS_SMC_CMD_SET_FREQ = 16,
+ VCOREFS_SMC_CMD_SET_EFUSE = 17,
+ VCOREFS_SMC_CMD_GET_EFUSE = 18,
+ VCOREFS_SMC_CMD_DVFS_HOPPING = 19,
+ VCOREFS_SMC_CMD_DVFS_HOPPING_STATE = 20,
+};
+
+enum dvfsrc_channel {
+ DVFSRC_CHANNEL_1 = 1,
+ DVFSRC_CHANNEL_2,
+ DVFSRC_CHANNEL_3,
+ DVFSRC_CHANNEL_4,
+ NUM_DVFSRC_CHANNEL,
+};
+
+#define _VCORE_BASE_UV 400000
+#define _VCORE_STEP_UV 6250
+
+/* PMIC */
+#define __vcore_pmic_to_uv(pmic) \
+ (((pmic) * _VCORE_STEP_UV) + _VCORE_BASE_UV)
+
+#define __vcore_uv_to_pmic(uv) /* pmic >= uv */ \
+ ((((uv) - _VCORE_BASE_UV) + (_VCORE_STEP_UV - 1)) / _VCORE_STEP_UV)
+
+struct reg_config {
+ uint32_t offset;
+ uint32_t val;
+};
+
+#define DVFSRC_BASIC_CONTROL (DVFSRC_BASE + 0x0)
+#define DVFSRC_SW_REQ1 (DVFSRC_BASE + 0x4)
+#define DVFSRC_SW_REQ2 (DVFSRC_BASE + 0x8)
+#define DVFSRC_SW_REQ3 (DVFSRC_BASE + 0xC)
+#define DVFSRC_SW_REQ4 (DVFSRC_BASE + 0x10)
+#define DVFSRC_SW_REQ5 (DVFSRC_BASE + 0x14)
+#define DVFSRC_SW_REQ6 (DVFSRC_BASE + 0x18)
+#define DVFSRC_SW_REQ7 (DVFSRC_BASE + 0x1C)
+#define DVFSRC_SW_REQ8 (DVFSRC_BASE + 0x20)
+#define DVFSRC_EMI_REQUEST (DVFSRC_BASE + 0x24)
+#define DVFSRC_EMI_REQUEST2 (DVFSRC_BASE + 0x28)
+#define DVFSRC_EMI_REQUEST3 (DVFSRC_BASE + 0x2C)
+#define DVFSRC_EMI_REQUEST4 (DVFSRC_BASE + 0x30)
+#define DVFSRC_EMI_REQUEST5 (DVFSRC_BASE + 0x34)
+#define DVFSRC_EMI_REQUEST6 (DVFSRC_BASE + 0x38)
+#define DVFSRC_EMI_HRT (DVFSRC_BASE + 0x3C)
+#define DVFSRC_EMI_HRT2 (DVFSRC_BASE + 0x40)
+#define DVFSRC_EMI_HRT3 (DVFSRC_BASE + 0x44)
+#define DVFSRC_EMI_QOS0 (DVFSRC_BASE + 0x48)
+#define DVFSRC_EMI_QOS1 (DVFSRC_BASE + 0x4C)
+#define DVFSRC_EMI_QOS2 (DVFSRC_BASE + 0x50)
+#define DVFSRC_EMI_MD2SPM0 (DVFSRC_BASE + 0x54)
+#define DVFSRC_EMI_MD2SPM1 (DVFSRC_BASE + 0x58)
+#define DVFSRC_EMI_MD2SPM2 (DVFSRC_BASE + 0x5C)
+#define DVFSRC_EMI_MD2SPM0_T (DVFSRC_BASE + 0x60)
+#define DVFSRC_EMI_MD2SPM1_T (DVFSRC_BASE + 0x64)
+#define DVFSRC_EMI_MD2SPM2_T (DVFSRC_BASE + 0x68)
+#define DVFSRC_VCORE_REQUEST (DVFSRC_BASE + 0x6C)
+#define DVFSRC_VCORE_REQUEST2 (DVFSRC_BASE + 0x70)
+#define DVFSRC_VCORE_REQUEST3 (DVFSRC_BASE + 0x74)
+#define DVFSRC_VCORE_REQUEST4 (DVFSRC_BASE + 0x78)
+#define DVFSRC_VCORE_HRT (DVFSRC_BASE + 0x7C)
+#define DVFSRC_VCORE_HRT2 (DVFSRC_BASE + 0x80)
+#define DVFSRC_VCORE_HRT3 (DVFSRC_BASE + 0x84)
+#define DVFSRC_VCORE_QOS0 (DVFSRC_BASE + 0x88)
+#define DVFSRC_VCORE_QOS1 (DVFSRC_BASE + 0x8C)
+#define DVFSRC_VCORE_QOS2 (DVFSRC_BASE + 0x90)
+#define DVFSRC_VCORE_MD2SPM0 (DVFSRC_BASE + 0x94)
+#define DVFSRC_VCORE_MD2SPM1 (DVFSRC_BASE + 0x98)
+#define DVFSRC_VCORE_MD2SPM2 (DVFSRC_BASE + 0x9C)
+#define DVFSRC_VCORE_MD2SPM0_T (DVFSRC_BASE + 0xA0)
+#define DVFSRC_VCORE_MD2SPM1_T (DVFSRC_BASE + 0xA4)
+#define DVFSRC_VCORE_MD2SPM2_T (DVFSRC_BASE + 0xA8)
+#define DVFSRC_MD_VSRAM_REMAP (DVFSRC_BASE + 0xBC)
+#define DVFSRC_HALT_SW_CONTROL (DVFSRC_BASE + 0xC0)
+#define DVFSRC_INT (DVFSRC_BASE + 0xC4)
+#define DVFSRC_INT_EN (DVFSRC_BASE + 0xC8)
+#define DVFSRC_INT_CLR (DVFSRC_BASE + 0xCC)
+#define DVFSRC_BW_MON_WINDOW (DVFSRC_BASE + 0xD0)
+#define DVFSRC_BW_MON_THRES_1 (DVFSRC_BASE + 0xD4)
+#define DVFSRC_BW_MON_THRES_2 (DVFSRC_BASE + 0xD8)
+#define DVFSRC_MD_TURBO (DVFSRC_BASE + 0xDC)
+#define DVFSRC_PCIE_VCORE_REQ (DVFSRC_BASE + 0xE0)
+#define DVFSRC_VCORE_USER_REQ (DVFSRC_BASE + 0xE4)
+#define DVFSRC_DEBOUNCE_FOUR (DVFSRC_BASE + 0xF0)
+#define DVFSRC_DEBOUNCE_RISE_FALL (DVFSRC_BASE + 0xF4)
+#define DVFSRC_TIMEOUT_NEXTREQ (DVFSRC_BASE + 0xF8)
+#define DVFSRC_LEVEL_LABEL_0_1 (DVFSRC_BASE + 0x100)
+#define DVFSRC_LEVEL_LABEL_2_3 (DVFSRC_BASE + 0x104)
+#define DVFSRC_LEVEL_LABEL_4_5 (DVFSRC_BASE + 0x108)
+#define DVFSRC_LEVEL_LABEL_6_7 (DVFSRC_BASE + 0x10C)
+#define DVFSRC_LEVEL_LABEL_8_9 (DVFSRC_BASE + 0x110)
+#define DVFSRC_LEVEL_LABEL_10_11 (DVFSRC_BASE + 0x114)
+#define DVFSRC_LEVEL_LABEL_12_13 (DVFSRC_BASE + 0x118)
+#define DVFSRC_LEVEL_LABEL_14_15 (DVFSRC_BASE + 0x11C)
+#define DVFSRC_MM_BW_0 (DVFSRC_BASE + 0x200)
+#define DVFSRC_MM_BW_1 (DVFSRC_BASE + 0x204)
+#define DVFSRC_MM_BW_2 (DVFSRC_BASE + 0x208)
+#define DVFSRC_MM_BW_3 (DVFSRC_BASE + 0x20C)
+#define DVFSRC_MM_BW_4 (DVFSRC_BASE + 0x210)
+#define DVFSRC_MM_BW_5 (DVFSRC_BASE + 0x214)
+#define DVFSRC_MM_BW_6 (DVFSRC_BASE + 0x218)
+#define DVFSRC_MM_BW_7 (DVFSRC_BASE + 0x21C)
+#define DVFSRC_MM_BW_8 (DVFSRC_BASE + 0x220)
+#define DVFSRC_MM_BW_9 (DVFSRC_BASE + 0x224)
+#define DVFSRC_MM_BW_10 (DVFSRC_BASE + 0x228)
+#define DVFSRC_MM_BW_11 (DVFSRC_BASE + 0x22C)
+#define DVFSRC_MM_BW_12 (DVFSRC_BASE + 0x230)
+#define DVFSRC_MM_BW_13 (DVFSRC_BASE + 0x234)
+#define DVFSRC_MM_BW_14 (DVFSRC_BASE + 0x238)
+#define DVFSRC_MM_BW_15 (DVFSRC_BASE + 0x23C)
+#define DVFSRC_MD_BW_0 (DVFSRC_BASE + 0x240)
+#define DVFSRC_MD_BW_1 (DVFSRC_BASE + 0x244)
+#define DVFSRC_MD_BW_2 (DVFSRC_BASE + 0x248)
+#define DVFSRC_MD_BW_3 (DVFSRC_BASE + 0x24C)
+#define DVFSRC_MD_BW_4 (DVFSRC_BASE + 0x250)
+#define DVFSRC_MD_BW_5 (DVFSRC_BASE + 0x254)
+#define DVFSRC_MD_BW_6 (DVFSRC_BASE + 0x258)
+#define DVFSRC_MD_BW_7 (DVFSRC_BASE + 0x25C)
+#define DVFSRC_SW_BW_0 (DVFSRC_BASE + 0x260)
+#define DVFSRC_SW_BW_1 (DVFSRC_BASE + 0x264)
+#define DVFSRC_SW_BW_2 (DVFSRC_BASE + 0x268)
+#define DVFSRC_SW_BW_3 (DVFSRC_BASE + 0x26C)
+#define DVFSRC_SW_BW_4 (DVFSRC_BASE + 0x270)
+#define DVFSRC_SW_BW_5 (DVFSRC_BASE + 0x274)
+#define DVFSRC_SW_BW_6 (DVFSRC_BASE + 0x278)
+#define DVFSRC_QOS_EN (DVFSRC_BASE + 0x280)
+#define DVFSRC_MD_BW_URG (DVFSRC_BASE + 0x284)
+#define DVFSRC_ISP_HRT (DVFSRC_BASE + 0x290)
+#define DVFSRC_HRT_BW_BASE (DVFSRC_BASE + 0x294)
+#define DVFSRC_SEC_SW_REQ (DVFSRC_BASE + 0x304)
+#define DVFSRC_EMI_MON_DEBOUNCE_TIME (DVFSRC_BASE + 0x308)
+#define DVFSRC_MD_LATENCY_IMPROVE (DVFSRC_BASE + 0x30C)
+#define DVFSRC_BASIC_CONTROL_3 (DVFSRC_BASE + 0x310)
+#define DVFSRC_DEBOUNCE_TIME (DVFSRC_BASE + 0x314)
+#define DVFSRC_LEVEL_MASK (DVFSRC_BASE + 0x318)
+#define DVFSRC_DEFAULT_OPP (DVFSRC_BASE + 0x31C)
+#define DVFSRC_95MD_SCEN_EMI0 (DVFSRC_BASE + 0x500)
+#define DVFSRC_95MD_SCEN_EMI1 (DVFSRC_BASE + 0x504)
+#define DVFSRC_95MD_SCEN_EMI2 (DVFSRC_BASE + 0x508)
+#define DVFSRC_95MD_SCEN_EMI3 (DVFSRC_BASE + 0x50C)
+#define DVFSRC_95MD_SCEN_EMI0_T (DVFSRC_BASE + 0x510)
+#define DVFSRC_95MD_SCEN_EMI1_T (DVFSRC_BASE + 0x514)
+#define DVFSRC_95MD_SCEN_EMI2_T (DVFSRC_BASE + 0x518)
+#define DVFSRC_95MD_SCEN_EMI3_T (DVFSRC_BASE + 0x51C)
+#define DVFSRC_95MD_SCEN_EMI4 (DVFSRC_BASE + 0x520)
+#define DVFSRC_95MD_SCEN_BW0 (DVFSRC_BASE + 0x524)
+#define DVFSRC_95MD_SCEN_BW1 (DVFSRC_BASE + 0x528)
+#define DVFSRC_95MD_SCEN_BW2 (DVFSRC_BASE + 0x52C)
+#define DVFSRC_95MD_SCEN_BW3 (DVFSRC_BASE + 0x530)
+#define DVFSRC_95MD_SCEN_BW0_T (DVFSRC_BASE + 0x534)
+#define DVFSRC_95MD_SCEN_BW1_T (DVFSRC_BASE + 0x538)
+#define DVFSRC_95MD_SCEN_BW2_T (DVFSRC_BASE + 0x53C)
+#define DVFSRC_95MD_SCEN_BW3_T (DVFSRC_BASE + 0x540)
+#define DVFSRC_95MD_SCEN_BW4 (DVFSRC_BASE + 0x544)
+#define DVFSRC_MD_LEVEL_SW_REG (DVFSRC_BASE + 0x548)
+#define DVFSRC_RSRV_0 (DVFSRC_BASE + 0x600)
+#define DVFSRC_RSRV_1 (DVFSRC_BASE + 0x604)
+#define DVFSRC_RSRV_2 (DVFSRC_BASE + 0x608)
+#define DVFSRC_RSRV_3 (DVFSRC_BASE + 0x60C)
+#define DVFSRC_RSRV_4 (DVFSRC_BASE + 0x610)
+#define DVFSRC_RSRV_5 (DVFSRC_BASE + 0x614)
+#define DVFSRC_SPM_RESEND (DVFSRC_BASE + 0x630)
+#define DVFSRC_DEBUG_STA_0 (DVFSRC_BASE + 0x700)
+#define DVFSRC_DEBUG_STA_1 (DVFSRC_BASE + 0x704)
+#define DVFSRC_DEBUG_STA_2 (DVFSRC_BASE + 0x708)
+#define DVFSRC_DEBUG_STA_3 (DVFSRC_BASE + 0x70C)
+#define DVFSRC_DEBUG_STA_4 (DVFSRC_BASE + 0x710)
+#define DVFSRC_DEBUG_STA_5 (DVFSRC_BASE + 0x714)
+#define DVFSRC_EMI_REQUEST7 (DVFSRC_BASE + 0x800)
+#define DVFSRC_EMI_HRT_1 (DVFSRC_BASE + 0x804)
+#define DVFSRC_EMI_HRT2_1 (DVFSRC_BASE + 0x808)
+#define DVFSRC_EMI_HRT3_1 (DVFSRC_BASE + 0x80C)
+#define DVFSRC_EMI_QOS3 (DVFSRC_BASE + 0x810)
+#define DVFSRC_EMI_QOS4 (DVFSRC_BASE + 0x814)
+#define DVFSRC_DDR_REQUEST (DVFSRC_BASE + 0xA00)
+#define DVFSRC_DDR_REQUEST2 (DVFSRC_BASE + 0xA04)
+#define DVFSRC_DDR_REQUEST3 (DVFSRC_BASE + 0xA08)
+#define DVFSRC_DDR_REQUEST4 (DVFSRC_BASE + 0xA0C)
+#define DVFSRC_DDR_REQUEST5 (DVFSRC_BASE + 0xA10)
+#define DVFSRC_DDR_REQUEST6 (DVFSRC_BASE + 0xA14)
+#define DVFSRC_DDR_REQUEST7 (DVFSRC_BASE + 0xA18)
+#define DVFSRC_DDR_HRT (DVFSRC_BASE + 0xA1C)
+#define DVFSRC_DDR_HRT2 (DVFSRC_BASE + 0xA20)
+#define DVFSRC_DDR_HRT3 (DVFSRC_BASE + 0xA24)
+#define DVFSRC_DDR_HRT_1 (DVFSRC_BASE + 0xA28)
+#define DVFSRC_DDR_HRT2_1 (DVFSRC_BASE + 0xA2C)
+#define DVFSRC_DDR_HRT3_1 (DVFSRC_BASE + 0xA30)
+#define DVFSRC_DDR_QOS0 (DVFSRC_BASE + 0xA34)
+#define DVFSRC_DDR_QOS1 (DVFSRC_BASE + 0xA38)
+#define DVFSRC_DDR_QOS2 (DVFSRC_BASE + 0xA3C)
+#define DVFSRC_DDR_QOS3 (DVFSRC_BASE + 0xA40)
+#define DVFSRC_DDR_QOS4 (DVFSRC_BASE + 0xA44)
+#define DVFSRC_DDR_MD2SPM0 (DVFSRC_BASE + 0xA48)
+#define DVFSRC_DDR_MD2SPM1 (DVFSRC_BASE + 0xA4C)
+#define DVFSRC_DDR_MD2SPM2 (DVFSRC_BASE + 0xA50)
+#define DVFSRC_DDR_MD2SPM0_T (DVFSRC_BASE + 0xA54)
+#define DVFSRC_DDR_MD2SPM1_T (DVFSRC_BASE + 0xA58)
+#define DVFSRC_DDR_MD2SPM2_T (DVFSRC_BASE + 0xA5C)
+#define DVFSRC_HRT_REQ_UNIT (DVFSRC_BASE + 0xA60)
+#define DVSFRC_HRT_REQ_MD_URG (DVFSRC_BASE + 0xA64)
+#define DVFSRC_HRT_REQ_MD_BW_0 (DVFSRC_BASE + 0xA68)
+#define DVFSRC_HRT_REQ_MD_BW_1 (DVFSRC_BASE + 0xA6C)
+#define DVFSRC_HRT_REQ_MD_BW_2 (DVFSRC_BASE + 0xA70)
+#define DVFSRC_HRT_REQ_MD_BW_3 (DVFSRC_BASE + 0xA74)
+#define DVFSRC_HRT_REQ_MD_BW_4 (DVFSRC_BASE + 0xA78)
+#define DVFSRC_HRT_REQ_MD_BW_5 (DVFSRC_BASE + 0xA7C)
+#define DVFSRC_HRT_REQ_MD_BW_6 (DVFSRC_BASE + 0xA80)
+#define DVFSRC_HRT_REQ_MD_BW_7 (DVFSRC_BASE + 0xA84)
+#define DVFSRC_HRT1_REQ_MD_BW_0 (DVFSRC_BASE + 0xA88)
+#define DVFSRC_HRT1_REQ_MD_BW_1 (DVFSRC_BASE + 0xA8C)
+#define DVFSRC_HRT1_REQ_MD_BW_2 (DVFSRC_BASE + 0xA90)
+#define DVFSRC_HRT1_REQ_MD_BW_3 (DVFSRC_BASE + 0xA94)
+#define DVFSRC_HRT1_REQ_MD_BW_4 (DVFSRC_BASE + 0xA98)
+#define DVFSRC_HRT1_REQ_MD_BW_5 (DVFSRC_BASE + 0xA9C)
+#define DVFSRC_HRT1_REQ_MD_BW_6 (DVFSRC_BASE + 0xAA0)
+#define DVFSRC_HRT1_REQ_MD_BW_7 (DVFSRC_BASE + 0xAA4)
+#define DVFSRC_HRT_REQ_MD_BW_8 (DVFSRC_BASE + 0xAA8)
+#define DVFSRC_HRT_REQ_MD_BW_9 (DVFSRC_BASE + 0xAAC)
+#define DVFSRC_HRT_REQ_MD_BW_10 (DVFSRC_BASE + 0xAB0)
+#define DVFSRC_HRT1_REQ_MD_BW_8 (DVFSRC_BASE + 0xAB4)
+#define DVFSRC_HRT1_REQ_MD_BW_9 (DVFSRC_BASE + 0xAB8)
+#define DVFSRC_HRT1_REQ_MD_BW_10 (DVFSRC_BASE + 0xABC)
+#define DVFSRC_HRT_REQ_BW_SW_REG (DVFSRC_BASE + 0xAC0)
+#define DVFSRC_HRT_REQUEST (DVFSRC_BASE + 0xAC4)
+#define DVFSRC_HRT_HIGH_2 (DVFSRC_BASE + 0xAC8)
+#define DVFSRC_HRT_HIGH_1 (DVFSRC_BASE + 0xACC)
+#define DVFSRC_HRT_HIGH (DVFSRC_BASE + 0xAD0)
+#define DVFSRC_HRT_LOW_2 (DVFSRC_BASE + 0xAD4)
+#define DVFSRC_HRT_LOW_1 (DVFSRC_BASE + 0xAD8)
+#define DVFSRC_HRT_LOW (DVFSRC_BASE + 0xADC)
+#define DVFSRC_DDR_ADD_REQUEST (DVFSRC_BASE + 0xAE0)
+#define DVFSRC_LAST (DVFSRC_BASE + 0xAE4)
+#define DVFSRC_LAST_L (DVFSRC_BASE + 0xAE8)
+#define DVFSRC_MD_SCENARIO (DVFSRC_BASE + 0xAEC)
+#define DVFSRC_RECORD_0_0 (DVFSRC_BASE + 0xAF0)
+#define DVFSRC_RECORD_0_1 (DVFSRC_BASE + 0xAF4)
+#define DVFSRC_RECORD_0_2 (DVFSRC_BASE + 0xAF8)
+#define DVFSRC_RECORD_0_3 (DVFSRC_BASE + 0xAFC)
+#define DVFSRC_RECORD_0_4 (DVFSRC_BASE + 0xB00)
+#define DVFSRC_RECORD_0_5 (DVFSRC_BASE + 0xB04)
+#define DVFSRC_RECORD_0_6 (DVFSRC_BASE + 0xB08)
+#define DVFSRC_RECORD_0_7 (DVFSRC_BASE + 0xB0C)
+#define DVFSRC_RECORD_0_L_0 (DVFSRC_BASE + 0xBF0)
+#define DVFSRC_RECORD_0_L_1 (DVFSRC_BASE + 0xBF4)
+#define DVFSRC_RECORD_0_L_2 (DVFSRC_BASE + 0xBF8)
+#define DVFSRC_RECORD_0_L_3 (DVFSRC_BASE + 0xBFC)
+#define DVFSRC_RECORD_0_L_4 (DVFSRC_BASE + 0xC00)
+#define DVFSRC_RECORD_0_L_5 (DVFSRC_BASE + 0xC04)
+#define DVFSRC_RECORD_0_L_6 (DVFSRC_BASE + 0xC08)
+#define DVFSRC_RECORD_0_L_7 (DVFSRC_BASE + 0xC0C)
+#define DVFSRC_EMI_REQUEST8 (DVFSRC_BASE + 0xCF0)
+#define DVFSRC_DDR_REQUEST8 (DVFSRC_BASE + 0xCF4)
+#define DVFSRC_EMI_HRT_2 (DVFSRC_BASE + 0xCF8)
+#define DVFSRC_EMI_HRT2_2 (DVFSRC_BASE + 0xCFC)
+#define DVFSRC_EMI_HRT3_2 (DVFSRC_BASE + 0xD00)
+#define DVFSRC_EMI_QOS5 (DVFSRC_BASE + 0xD04)
+#define DVFSRC_EMI_QOS6 (DVFSRC_BASE + 0xD08)
+#define DVFSRC_DDR_HRT_2 (DVFSRC_BASE + 0xD0C)
+#define DVFSRC_DDR_HRT2_2 (DVFSRC_BASE + 0xD10)
+#define DVFSRC_DDR_HRT3_2 (DVFSRC_BASE + 0xD14)
+#define DVFSRC_DDR_QOS5 (DVFSRC_BASE + 0xD18)
+#define DVFSRC_DDR_QOS6 (DVFSRC_BASE + 0xD1C)
+#define DVFSRC_VCORE_REQUEST5 (DVFSRC_BASE + 0xD20)
+#define DVFSRC_VCORE_HRT_1 (DVFSRC_BASE + 0xD24)
+#define DVFSRC_VCORE_HRT2_1 (DVFSRC_BASE + 0xD28)
+#define DVFSRC_VCORE_HRT3_1 (DVFSRC_BASE + 0xD2C)
+#define DVFSRC_VCORE_QOS3 (DVFSRC_BASE + 0xD30)
+#define DVFSRC_VCORE_QOS4 (DVFSRC_BASE + 0xD34)
+#define DVFSRC_HRT_HIGH_3 (DVFSRC_BASE + 0xD38)
+#define DVFSRC_HRT_LOW_3 (DVFSRC_BASE + 0xD3C)
+#define DVFSRC_BASIC_CONTROL_2 (DVFSRC_BASE + 0xD40)
+#define DVFSRC_CURRENT_LEVEL (DVFSRC_BASE + 0xD44)
+#define DVFSRC_TARGET_LEVEL (DVFSRC_BASE + 0xD48)
+#define DVFSRC_LEVEL_LABEL_16_17 (DVFSRC_BASE + 0xD4C)
+#define DVFSRC_LEVEL_LABEL_18_19 (DVFSRC_BASE + 0xD50)
+#define DVFSRC_LEVEL_LABEL_20_21 (DVFSRC_BASE + 0xD54)
+#define DVFSRC_LEVEL_LABEL_22_23 (DVFSRC_BASE + 0xD58)
+#define DVFSRC_LEVEL_LABEL_24_25 (DVFSRC_BASE + 0xD5C)
+#define DVFSRC_LEVEL_LABEL_26_27 (DVFSRC_BASE + 0xD60)
+#define DVFSRC_LEVEL_LABEL_28_29 (DVFSRC_BASE + 0xD64)
+#define DVFSRC_LEVEL_LABEL_30_31 (DVFSRC_BASE + 0xD68)
+#define DVFSRC_CURRENT_FORCE (DVFSRC_BASE + 0xD6C)
+#define DVFSRC_TARGET_FORCE (DVFSRC_BASE + 0xD70)
+#define DVFSRC_EMI_ADD_REQUEST (DVFSRC_BASE + 0xD74)
+
+#endif /* __MT_SPM_VCOREFS__H__ */
diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h
index b84e73f..44de8eb 100644
--- a/plat/mediatek/mt8195/include/platform_def.h
+++ b/plat/mediatek/mt8195/include/platform_def.h
@@ -31,6 +31,7 @@
#define VPPSYS1_BASE (IO_PHYS + 0x04f00000)
#define VDOSYS0_BASE (IO_PHYS + 0x0C01A000)
#define VDOSYS1_BASE (IO_PHYS + 0x0C100000)
+#define DVFSRC_BASE (IO_PHYS + 0x00012000)
/*******************************************************************************
* DP/eDP related constants
@@ -65,6 +66,12 @@
#define PMIC_WRAP_BASE (IO_PHYS + 0x00024000)
/*******************************************************************************
+ * EMI MPU related constants
+ ******************************************************************************/
+#define EMI_MPU_BASE (IO_PHYS + 0x00226000)
+#define SUB_EMI_MPU_BASE (IO_PHYS + 0x00225000)
+
+/*******************************************************************************
* System counter frequency related constants
******************************************************************************/
#define SYS_COUNTER_FREQ_IN_TICKS 13000000
diff --git a/plat/mediatek/mt8195/plat_sip_calls.c b/plat/mediatek/mt8195/plat_sip_calls.c
index 99e1eb3..ee36898 100644
--- a/plat/mediatek/mt8195/plat_sip_calls.c
+++ b/plat/mediatek/mt8195/plat_sip_calls.c
@@ -7,6 +7,8 @@
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <mt_dp.h>
+#include <mt_spm.h>
+#include <mt_spm_vcorefs.h>
#include <mtk_sip_svc.h>
#include "plat_sip_calls.h"
@@ -28,6 +30,11 @@
ret = dp_secure_handler(x1, x2, &ret_val);
SMC_RET2(handle, ret, ret_val);
break;
+ case MTK_SIP_VCORE_CONTROL_ARCH32:
+ case MTK_SIP_VCORE_CONTROL_ARCH64:
+ ret = spm_vcorefs_v2_args(x1, x2, x3, &x4);
+ SMC_RET2(handle, ret, x4);
+ break;
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break;
diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk
index f4604c4..48a2f72 100644
--- a/plat/mediatek/mt8195/platform.mk
+++ b/plat/mediatek/mt8195/platform.mk
@@ -16,6 +16,7 @@
-I${MTK_PLAT}/common/lpm/ \
-I${MTK_PLAT_SOC}/drivers/dcm \
-I${MTK_PLAT_SOC}/drivers/dp/ \
+ -I${MTK_PLAT_SOC}/drivers/emi_mpu/ \
-I${MTK_PLAT_SOC}/drivers/gpio/ \
-I${MTK_PLAT_SOC}/drivers/mcdi/ \
-I${MTK_PLAT_SOC}/drivers/pmic/ \
@@ -60,6 +61,7 @@
${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \
${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.c \
${MTK_PLAT_SOC}/drivers/dp/mt_dp.c \
+ ${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \
${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \
${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c \
${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm_cpc.c \
diff --git a/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h b/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h
index 08300b0..0a4228b 100644
--- a/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h
+++ b/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h
@@ -23,6 +23,9 @@
/* MMU 500 soc.c*/
#define NXP_SMMU_ADDR 0x05000000
+/* CCI400 base address */
+#define NXP_CCI_ADDR 0x04090000
+
#define NXP_SNVS_ADDR 0x01E90000
#define NXP_DCFG_ADDR 0x01E00000
@@ -81,4 +84,5 @@
#define NXP_CCN_HNI_ADDR 0x04080000
#define NXP_CCN_HN_F_0_ADDR 0x04200000
+#define NXP_EPU_ADDR 0x700060000
#endif /* SOC_DEFAULT_BASE_ADDR_H */
diff --git a/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h
index cdc823a..8de516e 100644
--- a/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h
+++ b/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h
@@ -39,6 +39,10 @@
#endif /* NXP_RESET_ADDR */
+/* secmon register offsets and bitfields */
+#define SECMON_HPCOMR_OFFSET 0x4
+#define SECMON_HPCOMR_NPSWAEN 0x80000000
+
/* Secure-Register-File register offsets and bit masks */
#ifdef NXP_RST_ADDR
/* Register Offset */
diff --git a/plat/nxp/common/include/default/plat_default_def.h b/plat/nxp/common/include/default/plat_default_def.h
index dd5dfe0..43320bb 100644
--- a/plat/nxp/common/include/default/plat_default_def.h
+++ b/plat/nxp/common/include/default/plat_default_def.h
@@ -40,8 +40,12 @@
#define NXP_NS_DRAM_ADDR NXP_DRAM0_ADDR
#endif
-/* 64M is reserved for Secure memory
- */
+/* 1 MB is reserved for dma of sd */
+#ifndef NXP_SD_BLOCK_BUF_SIZE
+#define NXP_SD_BLOCK_BUF_SIZE (1 * 1024 * 1024)
+#endif
+
+/* 64MB is reserved for Secure memory */
#ifndef NXP_SECURE_DRAM_SIZE
#define NXP_SECURE_DRAM_SIZE (64 * 1024 * 1024)
#endif
@@ -57,18 +61,22 @@
(NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE))
#endif
+#ifndef NXP_SD_BLOCK_BUF_ADDR
+#define NXP_SD_BLOCK_BUF_ADDR (NXP_NS_DRAM_ADDR)
+#endif
+
#ifndef NXP_SECURE_DRAM_ADDR
#ifdef TEST_BL31
#define NXP_SECURE_DRAM_ADDR 0
#else
#define NXP_SECURE_DRAM_ADDR (NXP_NS_DRAM_ADDR + PLAT_DEF_DRAM0_SIZE - \
- (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE))
+ (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE))
#endif
#endif
#ifndef NXP_SP_SHRD_DRAM_ADDR
-#define NXP_SP_SHRD_DRAM_ADDR (NXP_NS_DRAM_ADDR + PLAT_DEF_DRAM0_SIZE \
- - NXP_SP_SHRD_DRAM_SIZE)
+#define NXP_SP_SHRD_DRAM_ADDR (NXP_NS_DRAM_ADDR + PLAT_DEF_DRAM0_SIZE - \
+ NXP_SP_SHRD_DRAM_SIZE)
#endif
#ifndef BL31_BASE
diff --git a/plat/nxp/common/psci/aarch64/psci_utils.S b/plat/nxp/common/psci/aarch64/psci_utils.S
index ea2abbf..ec69aea 100644
--- a/plat/nxp/common/psci/aarch64/psci_utils.S
+++ b/plat/nxp/common/psci/aarch64/psci_utils.S
@@ -1,6 +1,6 @@
/*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -234,7 +234,7 @@
msr DAIFSet, #0xF
/* read cpuectlr and save current value */
- mrs x4, CORTEX_A72_ECTLR_EL1
+ mrs x4, CPUECTLR_EL1
mov x1, #CPUECTLR_DATA
mov x2, x4
mov x0, x10
@@ -242,7 +242,7 @@
/* remove the core from coherency */
bic x4, x4, #CPUECTLR_SMPEN_MASK
- msr CORTEX_A72_ECTLR_EL1, x4
+ msr CPUECTLR_EL1, x4
/* save scr_el3 */
mov x0, x10
@@ -339,7 +339,7 @@
mov x1, #CPUECTLR_DATA
bl _getCoreData
orr x0, x0, #CPUECTLR_SMPEN_MASK
- msr CORTEX_A72_ECTLR_EL1, x0
+ msr CPUECTLR_EL1, x0
/* x4 = core mask */
@@ -563,7 +563,7 @@
/* save cpuectlr */
mov x0, x6
mov x1, #CPUECTLR_DATA
- mrs x2, CORTEX_A72_ECTLR_EL1
+ mrs x2, CPUECTLR_EL1
bl _setCoreData
/* x6 = core mask */
@@ -640,7 +640,7 @@
bl _getCoreData
/* make sure smp is set */
orr x0, x0, #CPUECTLR_SMPEN_MASK
- msr CORTEX_A72_ECTLR_EL1, x0
+ msr CPUECTLR_EL1, x0
/* x5 = core mask */
@@ -780,13 +780,13 @@
/* save cpuectlr */
mov x0, x6
mov x1, #CPUECTLR_DATA
- mrs x2, CORTEX_A72_ECTLR_EL1
+ mrs x2, CPUECTLR_EL1
mov x4, x2
bl _setCoreData
/* remove core from coherency */
bic x4, x4, #CPUECTLR_SMPEN_MASK
- msr CORTEX_A72_ECTLR_EL1, x4
+ msr CPUECTLR_EL1, x4
/* x6 = core mask */
@@ -844,7 +844,7 @@
bl _getCoreData
/* make sure smp is set */
orr x0, x0, #CPUECTLR_SMPEN_MASK
- msr CORTEX_A72_ECTLR_EL1, x0
+ msr CPUECTLR_EL1, x0
/* x4 = core mask */
@@ -985,13 +985,13 @@
/* save cpuectlr */
mov x0, x6
mov x1, #CPUECTLR_DATA
- mrs x2, CORTEX_A72_ECTLR_EL1
+ mrs x2, CPUECTLR_EL1
mov x4, x2
bl _setCoreData
/* remove core from coherency */
bic x4, x4, #CPUECTLR_SMPEN_MASK
- msr CORTEX_A72_ECTLR_EL1, x4
+ msr CPUECTLR_EL1, x4
/* x6 = core mask */
@@ -1071,7 +1071,7 @@
/* make sure smp is set */
orr x0, x0, #CPUECTLR_SMPEN_MASK
- msr CORTEX_A72_ECTLR_EL1, x0
+ msr CPUECTLR_EL1, x0
/* x4 = core mask */
diff --git a/plat/nxp/common/psci/include/plat_psci.h b/plat/nxp/common/psci/include/plat_psci.h
index 97d4c97..7fc48fb 100644
--- a/plat/nxp/common/psci/include/plat_psci.h
+++ b/plat/nxp/common/psci/include/plat_psci.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -7,6 +7,8 @@
#ifndef PLAT_PSCI_H
#define PLAT_PSCI_H
+#include <cortex_a53.h>
+#include <cortex_a72.h>
/* core abort current op */
#define CORE_ABORT_OP 0x1
@@ -55,6 +57,7 @@
#define CPUECTLR_RET_SET 0x2
#define CPUECTLR_TIMER_MASK 0x7
#define CPUECTLR_TIMER_8TICKS 0x2
+#define CPUECTLR_TIMER_2TICKS 0x1
#define SCR_IRQ_MASK 0x2
#define SCR_FIQ_MASK 0x4
@@ -62,18 +65,53 @@
* value == 0x0, the soc code does not support this feature
* value != 0x0, the soc code supports this feature
*/
+#ifndef SOC_CORE_RELEASE
#define SOC_CORE_RELEASE 0x1
+#endif
+
+#ifndef SOC_CORE_RESTART
#define SOC_CORE_RESTART 0x1
+#endif
+
+#ifndef SOC_CORE_OFF
#define SOC_CORE_OFF 0x1
+#endif
+
+#ifndef SOC_CORE_STANDBY
#define SOC_CORE_STANDBY 0x1
+#endif
+
+#ifndef SOC_CORE_PWR_DWN
#define SOC_CORE_PWR_DWN 0x1
+#endif
+
+#ifndef SOC_CLUSTER_STANDBY
#define SOC_CLUSTER_STANDBY 0x1
+#endif
+
+#ifndef SOC_CLUSTER_PWR_DWN
#define SOC_CLUSTER_PWR_DWN 0x1
+#endif
+
+#ifndef SOC_SYSTEM_STANDBY
#define SOC_SYSTEM_STANDBY 0x1
+#endif
+
+#ifndef SOC_SYSTEM_PWR_DWN
#define SOC_SYSTEM_PWR_DWN 0x1
+#endif
+
+#ifndef SOC_SYSTEM_OFF
#define SOC_SYSTEM_OFF 0x1
+#endif
+
+#ifndef SOC_SYSTEM_RESET
#define SOC_SYSTEM_RESET 0x1
+#endif
+
+#ifndef SOC_SYSTEM_RESET2
#define SOC_SYSTEM_RESET2 0x1
+#endif
#ifndef __ASSEMBLER__
diff --git a/plat/nxp/common/setup/core.mk b/plat/nxp/common/setup/core.mk
index 9b81f2d..82ce30e 100644
--- a/plat/nxp/common/setup/core.mk
+++ b/plat/nxp/common/setup/core.mk
@@ -1,4 +1,4 @@
-# Copyright 2018-2020 NXP
+# Copyright 2018-2021 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -11,9 +11,11 @@
CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S
-ifeq (,$(filter $(CORE_TYPE),a53 a55 a57 a72 a75))
+ifeq (,$(filter $(CORE_TYPE),a53 a72))
$(error "CORE_TYPE not specified or incorrect")
else
+UPPER_CORE_TYPE=$(shell echo $(CORE_TYPE) | tr a-z A-Z)
+$(eval $(call add_define_val,CPUECTLR_EL1,CORTEX_$(UPPER_CORE_TYPE)_ECTLR_EL1))
CPU_LIBS += lib/cpus/${ARCH}/cortex_$(CORE_TYPE).S
endif
diff --git a/plat/nxp/common/setup/include/plat_common.h b/plat/nxp/common/setup/include/plat_common.h
index 18d36ca..97a9cb7 100644
--- a/plat/nxp/common/setup/include/plat_common.h
+++ b/plat/nxp/common/setup/include/plat_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -10,7 +10,9 @@
#include <stdbool.h>
+#include <dcfg.h>
#include <lib/el3_runtime/cpu_data.h>
+
#include <platform_def.h>
#ifdef IMAGE_BL31
@@ -129,18 +131,19 @@
#endif
);
-
/* Structure to define SoC personality */
struct soc_type {
char name[10];
- uint32_t personality;
- uint32_t num_clusters;
- uint32_t cores_per_cluster;
+ uint32_t version;
+ uint8_t num_clusters;
+ uint8_t cores_per_cluster;
};
+void get_cluster_info(const struct soc_type *soc_list, uint8_t ps_count,
+ uint8_t *num_clusters, uint8_t *cores_per_cluster);
#define SOC_ENTRY(n, v, ncl, nc) { \
.name = #n, \
- .personality = SVR_##v, \
+ .version = SVR_##v, \
.num_clusters = (ncl), \
.cores_per_cluster = (nc)}
diff --git a/plat/nxp/common/setup/ls_common.c b/plat/nxp/common/setup/ls_common.c
index a6946e1..e7ae060 100644
--- a/plat/nxp/common/setup/ls_common.c
+++ b/plat/nxp/common/setup/ls_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -238,3 +238,27 @@
{
return plat_ls_mmap;
}
+
+/*
+ * This function get the number of clusters and cores count per cluster
+ * in the SoC.
+ */
+void get_cluster_info(const struct soc_type *soc_list, uint8_t ps_count,
+ uint8_t *num_clusters, uint8_t *cores_per_cluster)
+{
+ const soc_info_t *soc_info = get_soc_info();
+ *num_clusters = NUMBER_OF_CLUSTERS;
+ *cores_per_cluster = CORES_PER_CLUSTER;
+ unsigned int i;
+
+ for (i = 0U; i < ps_count; i++) {
+ if (soc_list[i].version == soc_info->svr_reg.bf_ver.version) {
+ *num_clusters = soc_list[i].num_clusters;
+ *cores_per_cluster = soc_list[i].cores_per_cluster;
+ break;
+ }
+ }
+
+ VERBOSE("NUM of cluster = 0x%x, Cores per cluster = 0x%x\n",
+ *num_clusters, *cores_per_cluster);
+}
diff --git a/plat/nxp/common/soc_errata/errata.c b/plat/nxp/common/soc_errata/errata.c
new file mode 100644
index 0000000..fb1818a
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <common/debug.h>
+
+#include "errata_list.h"
+
+void soc_errata(void)
+{
+#ifdef ERRATA_SOC_A050426
+ INFO("SoC workaround for Errata A050426 was applied\n");
+ erratum_a050426();
+#endif
+ /*
+ * The following DDR Erratas workaround are implemented in DDR driver,
+ * but print information here.
+ */
+#if ERRATA_DDR_A011396
+ INFO("SoC workaround for DDR Errata A011396 was applied\n");
+#endif
+#if ERRATA_DDR_A050450
+ INFO("SoC workaround for DDR Errata A050450 was applied\n");
+#endif
+}
diff --git a/plat/nxp/common/soc_errata/errata.h b/plat/nxp/common/soc_errata/errata.h
new file mode 100644
index 0000000..b543b4b
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef ERRATA_H
+#define ERRATA_H
+
+void soc_errata(void);
+
+#endif /* ERRATA_H */
diff --git a/plat/nxp/common/soc_errata/errata.mk b/plat/nxp/common/soc_errata/errata.mk
new file mode 100644
index 0000000..2942615
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.mk
@@ -0,0 +1,23 @@
+#
+# Copyright 2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform Errata Build flags.
+# These should be enabled by the platform if the erratum workaround needs to be
+# applied.
+
+ERRATA := \
+ ERRATA_SOC_A050426
+
+define enable_errata
+ $(1) ?= 0
+ ifeq ($$($(1)),1)
+ $$(eval $$(call add_define,$(1)))
+ BL2_SOURCES += $(PLAT_COMMON_PATH)/soc_errata/errata_a$(shell echo $(1)|awk -F '_A' '{print $$NF}').c
+ endif
+endef
+
+$(foreach e,$(ERRATA),$(eval $(call enable_errata,$(strip $(e)))))
+
+BL2_SOURCES += $(PLAT_COMMON_PATH)/soc_errata/errata.c
diff --git a/plat/nxp/soc-lx2160a/erratas_soc.c b/plat/nxp/common/soc_errata/errata_a050426.c
similarity index 98%
rename from plat/nxp/soc-lx2160a/erratas_soc.c
rename to plat/nxp/common/soc_errata/errata_a050426.c
index 8f3aa9f..13a0000 100644
--- a/plat/nxp/soc-lx2160a/erratas_soc.c
+++ b/plat/nxp/common/soc_errata/errata_a050426.c
@@ -7,7 +7,6 @@
#include <mmio.h>
-#ifdef ERRATA_SOC_A050426
void erratum_a050426(void)
{
uint32_t i, val3, val4;
@@ -411,8 +410,6 @@
}
/* Disable BIST */
-
mmio_write_32(0x700117E60, val3);
mmio_write_32(0x700117E90, val4);
}
-#endif
diff --git a/plat/nxp/common/soc_errata/errata_list.h b/plat/nxp/common/soc_errata/errata_list.h
new file mode 100644
index 0000000..74d2315
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_list.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef ERRATA_LIST_H
+#define ERRATA_LIST_H
+
+#ifdef ERRATA_SOC_A050426
+void erratum_a050426(void);
+#endif
+
+#endif /* ERRATA_LIST_H */
diff --git a/plat/nxp/soc-ls1028a/aarch64/ls1028a.S b/plat/nxp/soc-ls1028a/aarch64/ls1028a.S
new file mode 100644
index 0000000..404c39e
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/aarch64/ls1028a.S
@@ -0,0 +1,1387 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .section .text, "ax"
+
+#include <asm_macros.S>
+
+#include <lib/psci/psci.h>
+#include <nxp_timer.h>
+#include <plat_gic.h>
+#include <pmu.h>
+
+#include <bl31_data.h>
+#include <plat_psci.h>
+#include <platform_def.h>
+
+ .global soc_init_lowlevel
+ .global soc_init_percpu
+ .global _set_platform_security
+ .global _soc_set_start_addr
+
+ .global _soc_core_release
+ .global _soc_ck_disabled
+ .global _soc_core_restart
+ .global _soc_core_prep_off
+ .global _soc_core_entr_off
+ .global _soc_core_exit_off
+ .global _soc_sys_reset
+ .global _soc_sys_off
+ .global _soc_core_prep_stdby
+ .global _soc_core_entr_stdby
+ .global _soc_core_exit_stdby
+ .global _soc_core_prep_pwrdn
+ .global _soc_core_entr_pwrdn
+ .global _soc_core_exit_pwrdn
+ .global _soc_clstr_prep_stdby
+ .global _soc_clstr_exit_stdby
+ .global _soc_clstr_prep_pwrdn
+ .global _soc_clstr_exit_pwrdn
+ .global _soc_sys_prep_stdby
+ .global _soc_sys_exit_stdby
+ .global _soc_sys_prep_pwrdn
+ .global _soc_sys_pwrdn_wfi
+ .global _soc_sys_exit_pwrdn
+
+ .equ TZPCDECPROT_0_SET_BASE, 0x02200804
+ .equ TZPCDECPROT_1_SET_BASE, 0x02200810
+ .equ TZPCDECPROT_2_SET_BASE, 0x0220081C
+
+ .equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110
+
+/*
+ * This function initialize the soc.
+ * in: void
+ * out: void
+ * uses x0 - x11
+ */
+func soc_init_lowlevel
+ /*
+ * Called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ /*
+ * Make sure the personality has been established by releasing cores
+ * that are marked "to-be-disabled" from reset
+ */
+ bl release_disabled /* 0-8 */
+
+ /* Set SCRATCHRW7 to 0x0 */
+ ldr x0, =DCFG_SCRATCHRW7_OFFSET
+ mov x1, xzr
+ bl _write_reg_dcfg
+
+ /* Restore the aarch32/64 non-volatile registers */
+ ldp x18, x30, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ ret
+endfunc soc_init_lowlevel
+
+/*
+ * void soc_init_percpu(void)
+ *
+ * This function performs any soc-specific initialization that is needed on
+ * a per-core basis
+ * in: none
+ * out: none
+ * uses x0 - x3
+ */
+func soc_init_percpu
+ stp x4, x30, [sp, #-16]!
+
+ bl plat_my_core_mask
+ mov x2, x0
+
+ /* x2 = core mask */
+
+ /* see if this core is marked for prefetch disable */
+ mov x0, #PREFETCH_DIS_OFFSET
+ bl _get_global_data /* 0-1 */
+ tst x0, x2
+ b.eq 1f
+ bl _disable_ldstr_pfetch_A72 /* 0 */
+1:
+ mov x0, #NXP_PMU_ADDR
+ bl enable_timer_base_to_cluster
+
+ ldp x4, x30, [sp], #16
+ ret
+endfunc soc_init_percpu
+
+/*
+ * This function determines if a core is disabled via COREDISABLEDSR
+ * in: w0 = core_mask_lsb
+ * out: w0 = 0, core not disabled
+ * w0 != 0, core disabled
+ * uses x0, x1
+ */
+func _soc_ck_disabled
+ /* get base addr of dcfg block */
+ ldr x1, =NXP_DCFG_ADDR
+
+ /* read COREDISABLEDSR */
+ ldr w1, [x1, #DCFG_COREDISABLEDSR_OFFSET]
+
+ /* test core bit */
+ and w0, w1, w0
+
+ ret
+endfunc _soc_ck_disabled
+
+/*
+ * This function sets the security mechanisms in the SoC to implement the
+ * Platform Security Policy
+ */
+func _set_platform_security
+ mov x3, x30
+
+#if (!SUPPRESS_TZC)
+ /* initialize the tzpc */
+ bl init_tzpc
+#endif
+
+#if (!SUPPRESS_SEC)
+ /* initialize secmon */
+ bl initSecMon
+#endif
+
+ mov x30, x3
+ ret
+endfunc _set_platform_security
+
+/*
+ * Part of CPU_ON
+ *
+ * This function releases a secondary core from reset
+ * in: x0 = core_mask_lsb
+ * out: none
+ * uses: x0 - x3
+ */
+_soc_core_release:
+ mov x3, x30
+
+ /*
+ * Write to CORE_HOLD to tell the bootrom that we want this core
+ * to run
+ */
+ ldr x1, =NXP_SEC_REGFILE_ADDR
+ str w0, [x1, #CORE_HOLD_OFFSET]
+
+ /* Read-modify-write BRRL to release core */
+ mov x1, #NXP_RESET_ADDR
+ ldr w2, [x1, #BRR_OFFSET]
+ orr w2, w2, w0
+ str w2, [x1, #BRR_OFFSET]
+ dsb sy
+ isb
+
+ /* Send event */
+ sev
+ isb
+
+ mov x30, x3
+ ret
+
+/*
+ * This function writes a 64-bit address to bootlocptrh/l
+ * in: x0, 64-bit address to write to BOOTLOCPTRL/H
+ * uses x0, x1, x2
+ */
+func _soc_set_start_addr
+ /* Get the 64-bit base address of the dcfg block */
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* Write the 32-bit BOOTLOCPTRL register */
+ mov x1, x0
+ str w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET]
+
+ /* Write the 32-bit BOOTLOCPTRH register */
+ lsr x1, x0, #32
+ str w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET]
+ ret
+endfunc _soc_set_start_addr
+
+/*
+ * Part of CPU_ON
+ *
+ * This function restarts a core shutdown via _soc_core_entr_off
+ * in: x0 = core mask lsb (of the target cpu)
+ * out: x0 == 0, on success
+ * x0 != 0, on failure
+ * uses x0 - x6
+ */
+_soc_core_restart:
+ mov x6, x30
+ mov x4, x0
+
+ /* pgm GICD_CTLR - enable secure grp0 */
+ mov x5, #NXP_GICD_ADDR
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ orr w2, w2, #GICD_CTLR_EN_GRP_0
+ str w2, [x5, #GICD_CTLR_OFFSET]
+ dsb sy
+ isb
+
+ /* Poll on RWP til write completes */
+4:
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ tst w2, #GICD_CTLR_RWP
+ b.ne 4b
+
+ /*
+ * x4 = core mask lsb
+ * x5 = gicd base addr
+ */
+
+ mov x0, x4
+ bl get_mpidr_value
+
+ /* Generate target list bit */
+ and x1, x0, #MPIDR_AFFINITY0_MASK
+ mov x2, #1
+ lsl x2, x2, x1
+
+ /* Get the affinity1 field */
+ and x1, x0, #MPIDR_AFFINITY1_MASK
+ lsl x1, x1, #8
+ orr x2, x2, x1
+
+ /* Insert the INTID for SGI15 */
+ orr x2, x2, #ICC_SGI0R_EL1_INTID
+
+ /* Fire the SGI */
+ msr ICC_SGI0R_EL1, x2
+ dsb sy
+ isb
+
+ /* Load '0' on success */
+ mov x0, xzr
+
+ mov x30, x6
+ ret
+
+/*
+ * Part of CPU_OFF
+ *
+ * This function programs SoC & GIC registers in preparation for shutting down
+ * the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0 - x7
+ */
+_soc_core_prep_off:
+ mov x8, x30
+ mov x7, x0
+
+ /* x7 = core mask lsb */
+
+ mrs x1, CPUECTLR_EL1
+
+ /* Set smp and disable L2 snoops in cpuectlr */
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
+ bic x1, x1, #CPUECTLR_INS_PREFETCH_MASK
+ bic x1, x1, #CPUECTLR_DAT_PREFETCH_MASK
+
+ /* Set retention control in cpuectlr */
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ orr x1, x1, #CPUECTLR_TIMER_2TICKS
+ msr CPUECTLR_EL1, x1
+
+ /* Get redistributor rd base addr for this core */
+ mov x0, x7
+ bl get_gic_rd_base
+ mov x6, x0
+
+ /* Get redistributor sgi base addr for this core */
+ mov x0, x7
+ bl get_gic_sgi_base
+ mov x5, x0
+
+ /*
+ * x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* Disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w3, #GICR_ICENABLER0_SGI15
+ str w3, [x5, #GICR_ICENABLER0_OFFSET]
+2:
+ /* Poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* Disable GRP1 interrupts at cpu interface */
+ msr ICC_IGRPEN1_EL3, xzr
+
+ /* Disable GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* Program the redistributor - poll on GICR_CTLR.RWP as needed */
+
+ /* Define SGI 15 as Grp0 - GICR_IGROUPR0 */
+ ldr w4, [x5, #GICR_IGROUPR0_OFFSET]
+ bic w4, w4, #GICR_IGROUPR0_SGI15
+ str w4, [x5, #GICR_IGROUPR0_OFFSET]
+
+ /* Define SGI 15 as Grp0 - GICR_IGRPMODR0 */
+ ldr w3, [x5, #GICR_IGRPMODR0_OFFSET]
+ bic w3, w3, #GICR_IGRPMODR0_SGI15
+ str w3, [x5, #GICR_IGRPMODR0_OFFSET]
+
+ /* Set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */
+ ldr w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+ bic w4, w4, #GICR_IPRIORITYR3_SGI15_MASK
+ str w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+
+ /* Enable SGI 15 at redistributor - GICR_ISENABLER0 */
+ mov w3, #GICR_ISENABLER0_SGI15
+ str w3, [x5, #GICR_ISENABLER0_OFFSET]
+ dsb sy
+ isb
+3:
+ /* Poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 3b
+
+ /* Quiesce the debug interfaces */
+ mrs x3, osdlr_el1
+ orr x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ /* Enable grp0 ints */
+ mov x3, #ICC_IGRPEN0_EL1_EN
+ msr ICC_IGRPEN0_EL1, x3
+
+ /*
+ * x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* Clear any pending interrupts */
+ mvn w1, wzr
+ str w1, [x5, #GICR_ICPENDR0_OFFSET]
+
+ /* Make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 4f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+4:
+ /* Enable the core timer and mask timer interrupt */
+ mov x1, #CNTP_CTL_EL0_EN
+ orr x1, x1, #CNTP_CTL_EL0_IMASK
+ msr cntp_ctl_el0, x1
+
+ isb
+ mov x30, x8
+ ret
+
+/*
+ * Part of CPU_OFF
+ *
+ * This function performs the final steps to shutdown the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0 - x5
+ */
+_soc_core_entr_off:
+ mov x5, x30
+ mov x4, x0
+
+ /* x4 = core mask */
+1:
+ /* Enter low-power state by executing wfi */
+ wfi
+
+ /* See if SGI15 woke us up */
+ mrs x2, ICC_IAR0_EL1
+ mov x3, #ICC_IAR0_EL1_SGI15
+ cmp x2, x3
+ b.ne 1b
+
+ /* Deactivate the int */
+ msr ICC_EOIR0_EL1, x2
+
+ /* x4 = core mask */
+2:
+ /* Check if core has been turned on */
+ mov x0, x4
+ bl _getCoreState
+
+ /* x0 = core state */
+
+ cmp x0, #CORE_WAKEUP
+ b.ne 1b
+
+ /* If we get here, then we have exited the wfi */
+ mov x30, x5
+ ret
+
+/*
+ * Part of CPU_OFF
+ *
+ * This function starts the process of starting a core back up
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_core_exit_off:
+ mov x6, x30
+ mov x5, x0
+
+ /* Disable forwarding of GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* Get redistributor sgi base addr for this core */
+ mov x0, x5
+ bl get_gic_sgi_base
+ mov x4, x0
+
+ /* x4 = gicr sgi base addr */
+ /* x5 = core mask */
+
+ /* Disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w1, #GICR_ICENABLER0_SGI15
+ str w1, [x4, #GICR_ICENABLER0_OFFSET]
+
+ /* Get redistributor rd base addr for this core */
+ mov x0, x5
+ bl get_gic_rd_base
+ mov x4, x0
+
+ /* x4 = gicr rd base addr */
+2:
+ /* Poll on rwp bit in GICR_CTLR */
+ ldr w2, [x4, #GICR_CTLR_OFFSET]
+ tst w2, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* x4 = gicr rd base addr */
+
+ /* Unlock the debug interfaces */
+ mrs x3, osdlr_el1
+ bic x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ dsb sy
+ isb
+ mov x30, x6
+ ret
+
+/*
+ * This function requests a reset of the entire SOC
+ * in: none
+ * out: none
+ * uses: x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_sys_reset:
+ mov x3, x30
+
+ /* Make sure the mask is cleared in the reset request mask register */
+ mov x0, #RST_RSTRQMR1_OFFSET
+ mov w1, wzr
+ bl _write_reg_reset
+
+ /* Set the reset request */
+ mov x4, #RST_RSTCR_OFFSET
+ mov x0, x4
+ mov w1, #RSTCR_RESET_REQ
+ bl _write_reg_reset
+
+ /* x4 = RST_RSTCR_OFFSET */
+
+ /*
+ * Just in case this address range is mapped as cacheable,
+ * flush the write out of the dcaches
+ */
+ mov x2, #NXP_RESET_ADDR
+ add x2, x2, x4
+ dc cvac, x2
+ dsb st
+ isb
+
+ /* This function does not return */
+1:
+ wfi
+ b 1b
+
+/*
+ * Part of SYSTEM_OFF
+ *
+ * This function turns off the SoC clocks
+ * Note: this function is not intended to return, and the only allowable
+ * recovery is POR
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_sys_off:
+ /*
+ * Disable sec, spi and flexspi
+ * TBD - Check if eNETC needs to be disabled
+ */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /* Set TPMWAKEMR0 */
+ ldr x0, =TPMWAKEMR0_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* Disable icache, dcache, mmu @ EL1 */
+ mov x1, #SCTLR_I_C_M_MASK
+ mrs x0, sctlr_el1
+ bic x0, x0, x1
+ msr sctlr_el1, x0
+
+ /* Disable L2 prefetches */
+ mrs x0, CPUECTLR_EL1
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ bic x0, x0, #CPUECTLR_TIMER_MASK
+ orr x0, x0, #CPUECTLR_TIMER_2TICKS
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+
+ /* Disable CCI snoop domain */
+ ldr x0, =NXP_CCI_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ bl get_pmu_idle_core_mask
+
+ /* x3 = pmu base addr */
+ mov x3, #NXP_PMU_ADDR
+4:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w0
+ b.ne 4b
+
+ bl get_pmu_idle_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+ str w0, [x3, #PMU_CLAINACTSETR_OFFSET]
+
+ bl get_pmu_idle_core_mask
+ mov x3, #NXP_PMU_ADDR
+1:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w0
+ b.ne 1b
+
+ bl get_pmu_flush_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+ str w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET]
+2:
+ ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET]
+ cmp w1, w0
+ b.ne 2b
+
+ str w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET]
+
+ str w0, [x3, #PMU_CLSINACTSETR_OFFSET]
+
+ mov x2, #DAIF_SET_MASK
+ mrs x1, spsr_el1
+ orr x1, x1, x2
+ msr spsr_el1, x1
+
+ mrs x1, spsr_el2
+ orr x1, x1, x2
+ msr spsr_el2, x1
+
+ /* Force the debug interface to be quiescent */
+ mrs x0, osdlr_el1
+ orr x0, x0, #0x1
+ msr osdlr_el1, x0
+
+ /* Invalidate all TLB entries at all 3 exception levels */
+ tlbi alle1
+ tlbi alle2
+ tlbi alle3
+
+ /* x3 = pmu base addr */
+
+ /* Request lpm20 */
+ ldr x0, =PMU_POWMGTCSR_OFFSET
+ ldr w1, =PMU_POWMGTCSR_VAL
+ str w1, [x3, x0]
+ isb
+ dsb sy
+5:
+ wfe
+ b.eq 5b
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_core_prep_stdby:
+ /* Clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function puts the calling core into standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_stdby:
+ /* X0 = core mask lsb */
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_stdby:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2
+ */
+_soc_core_prep_pwrdn:
+ /* Make sure system counter is enabled */
+ ldr x2, =NXP_TIMER_ADDR
+ ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+ /*
+ * Enable dynamic retention control (CPUECTLR[2:0])
+ * Set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_2TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x1
+
+ isb
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function puts the calling core into a power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_pwrdn:
+ /* X0 = core mask lsb */
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_pwrdn:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_clstr_prep_stdby:
+ /* Clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_stdby:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2
+ */
+_soc_clstr_prep_pwrdn:
+ /* Make sure system counter is enabled */
+ ldr x2, =NXP_TIMER_ADDR
+ ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+ /*
+ * Enable dynamic retention control (CPUECTLR[2:0])
+ * Set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_2TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x1
+
+ isb
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_pwrdn:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_prep_stdby:
+ /* Clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_sys_exit_stdby:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to
+ * suspend-to-power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4
+ */
+_soc_sys_prep_pwrdn:
+ /* Set retention control */
+ mrs x0, CPUECTLR_EL1
+ bic x0, x0, #CPUECTLR_TIMER_MASK
+ orr x0, x0, #CPUECTLR_TIMER_2TICKS
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function puts the calling core, and potentially the soc, into a
+ * low-power state
+ * in: x0 = core mask lsb
+ * out: x0 = 0, success
+ * x0 < 0, failure
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x13, x14, x15,
+ * x16, x17, x18
+ */
+_soc_sys_pwrdn_wfi:
+ mov x18, x30
+
+ mov x3, #NXP_PMU_ADDR
+
+ /* x3 = pmu base addr */
+
+ /* Backup epu registers to stack */
+ ldr x2, =NXP_EPU_ADDR
+ ldr w4, [x2, #EPU_EPIMCR10_OFFSET]
+ ldr w5, [x2, #EPU_EPCCR10_OFFSET]
+ ldr w6, [x2, #EPU_EPCTR10_OFFSET]
+ ldr w7, [x2, #EPU_EPGCR_OFFSET]
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+
+ /*
+ * x2 = epu base addr
+ * x3 = pmu base addr
+ */
+
+ /* Set up EPU event to receive the wake signal from PMU */
+ mov w4, #EPU_EPIMCR10_VAL
+ mov w5, #EPU_EPCCR10_VAL
+ mov w6, #EPU_EPCTR10_VAL
+ mov w7, #EPU_EPGCR_VAL
+ str w4, [x2, #EPU_EPIMCR10_OFFSET]
+ str w5, [x2, #EPU_EPCCR10_OFFSET]
+ str w6, [x2, #EPU_EPCTR10_OFFSET]
+ str w7, [x2, #EPU_EPGCR_OFFSET]
+
+ ldr x2, =NXP_GICD_ADDR
+
+ /*
+ * x2 = gicd base addr
+ * x3 = pmu base addr
+ */
+
+ /* Backup flextimer/mmc/usb interrupt router */
+ ldr x0, =GICD_IROUTER60_OFFSET
+ ldr x1, =GICD_IROUTER76_OFFSET
+ ldr w4, [x2, x0]
+ ldr w5, [x2, x1]
+ ldr x0, =GICD_IROUTER112_OFFSET
+ ldr x1, =GICD_IROUTER113_OFFSET
+ ldr w6, [x2, x0]
+ ldr w7, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+
+ /*
+ * x2 = gicd base addr
+ * x3 = pmu base addr
+ * x0 = GICD_IROUTER112_OFFSET
+ * x1 = GICD_IROUTER113_OFFSET
+ */
+
+ /* Re-route interrupt to cluster 1 */
+ ldr w4, =GICD_IROUTER_VALUE
+ str w4, [x2, x0]
+ str w4, [x2, x1]
+ ldr x0, =GICD_IROUTER60_OFFSET
+ ldr x1, =GICD_IROUTER76_OFFSET
+ str w4, [x2, x0]
+ str w4, [x2, x1]
+ dsb sy
+ isb
+
+ /* x3 = pmu base addr */
+
+ /* Disable sec, Check for eNETC, spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /* x3 = pmu base addr */
+
+ /* Set TPMWAKEMR0 */
+ ldr x0, =TPMWAKEMR0_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* Disable CCI snoop domain */
+ ldr x0, =NXP_CCI_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* Setup retention control */
+ mrs x0, CPUECTLR_EL1
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ orr x0, x0, #CPUECTLR_TIMER_2TICKS
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+
+ bl get_pmu_idle_core_mask
+ mov x3, #NXP_PMU_ADDR
+8:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w0
+ b.ne 8b
+
+ /* x3 = NXP_PMU_ADDR */
+ /* 1 cluster SoC */
+
+ bl get_pmu_idle_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+
+ str w0, [x3, #PMU_CLAINACTSETR_OFFSET]
+
+ bl get_pmu_idle_core_mask
+ /* x3 = NXP_PMU_ADDR */
+ mov x3, #NXP_PMU_ADDR
+1:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w0
+ b.ne 1b
+
+ /* x3 = NXP_PMU_ADDR */
+ bl get_pmu_flush_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+
+ str w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET]
+
+ /* x3 = NXP_PMU_ADDR */
+2:
+ ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET]
+ cmp w1, w0
+ b.ne 2b
+
+ /* x3 = NXP_PMU_ADDR */
+
+ str w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET]
+
+ str w0, [x3, #PMU_CLSINACTSETR_OFFSET]
+
+ /* Force the debug interface to be quiescent */
+ mrs x0, osdlr_el1
+ orr x0, x0, #0x1
+ msr osdlr_el1, x0
+
+ /*
+ * Enable the WakeRequest signal
+ * x3 is cpu mask starting from cpu1 to cpu0
+ */
+ bl get_tot_num_cores
+ sub x0, x0, #1
+ mov x3, #0x1
+ lsl x3, x3, x0
+2:
+ mov x0, x3
+ bl get_gic_rd_base // 0-2
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ orr w1, w1, #GICR_WAKER_SLEEP_BIT
+ str w1, [x0, #GICR_WAKER_OFFSET]
+1:
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ cmp w1, #GICR_WAKER_ASLEEP
+ b.ne 1b
+
+ lsr x3, x3, #1
+ cbnz x3, 2b
+
+ /* Invalidate all TLB entries at all 3 exception levels */
+ tlbi alle1
+ tlbi alle2
+ tlbi alle3
+
+ /* Request lpm20 */
+ mov x3, #NXP_PMU_ADDR
+ ldr x0, =PMU_POWMGTCSR_OFFSET
+ ldr w1, =PMU_POWMGTCSR_VAL
+ str w1, [x3, x0]
+
+ ldr x5, =NXP_EPU_ADDR
+4:
+ wfe
+ ldr w1, [x5, #EPU_EPCTR10_OFFSET]
+ cmp w1, #0
+ b.eq 4b
+
+ /* x3 = NXP_PMU_ADDR */
+
+ bl get_pmu_idle_cluster_mask
+ mov x3, NXP_PMU_ADDR
+
+ /* Re-enable the GPP ACP */
+ str w0, [x3, #PMU_CLAINACTCLRR_OFFSET]
+ str w0, [x3, #PMU_CLSINACTCLRR_OFFSET]
+
+ /* x3 = NXP_PMU_ADDR */
+3:
+ ldr w1, [x3, #PMU_CLAINACTSETR_OFFSET]
+ cbnz w1, 3b
+4:
+ ldr w1, [x3, #PMU_CLSINACTSETR_OFFSET]
+ cbnz w1, 4b
+
+ /*
+ * Enable the WakeRequest signal on cpu 0-1
+ * x3 is cpu mask starting from cpu1
+ */
+ bl get_tot_num_cores
+ sub x0, x0, #1
+ mov x3, #0x1
+ lsl x3, x3, x0
+2:
+ mov x0, x3
+ bl get_gic_rd_base // 0-2
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ bic w1, w1, #GICR_WAKER_SLEEP_BIT
+ str w1, [x0, #GICR_WAKER_OFFSET]
+1:
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ cbnz w1, 1b
+
+ lsr x3, x3, #1
+ cbnz x3, 2b
+
+ /* Enable CCI snoop domain */
+ ldr x0, =NXP_CCI_ADDR
+ str wzr, [x0]
+ dsb sy
+ isb
+
+ ldr x3, =NXP_EPU_ADDR
+
+ /* x3 = epu base addr */
+
+ /* Enable sec, enetc, spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ str wzr, [x2, #DCFG_DEVDISR1_OFFSET]
+ str wzr, [x2, #DCFG_DEVDISR2_OFFSET]
+ str wzr, [x2, #DCFG_DEVDISR4_OFFSET]
+
+ /* Restore flextimer/mmc/usb interrupt router */
+ ldr x3, =NXP_GICD_ADDR
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_IROUTER113_OFFSET
+ str w2, [x3, x1]
+ ldr x1, =GICD_IROUTER112_OFFSET
+ str w0, [x3, x1]
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_IROUTER76_OFFSET
+ str w2, [x3, x1]
+ ldr x1, =GICD_IROUTER60_OFFSET
+ str w0, [x3, x1]
+
+ /* Restore EPU registers */
+ ldr x3, =NXP_EPU_ADDR
+ ldp x0, x2, [sp], #16
+ str w2, [x3, #EPU_EPGCR_OFFSET]
+ str w0, [x3, #EPU_EPCTR10_OFFSET]
+ ldp x2, x1, [sp], #16
+ str w1, [x3, #EPU_EPCCR10_OFFSET]
+ str w2, [x3, #EPU_EPIMCR10_OFFSET]
+
+ dsb sy
+ isb
+ mov x30, x18
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_exit_pwrdn:
+ /* Enable stack alignment checking */
+ mrs x1, SCTLR_EL1
+ orr x1, x1, #0x4
+ msr SCTLR_EL1, x1
+
+ /* Enable debug interface */
+ mrs x1, osdlr_el1
+ bic x1, x1, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x1
+
+ /* Enable i-cache */
+ mrs x1, SCTLR_EL3
+ orr x1, x1, #SCTLR_I_MASK
+ msr SCTLR_EL3, x1
+
+ isb
+ ret
+
+/*
+ * This function setc up the TrustZone Address Space Controller (TZASC)
+ * in: none
+ * out: none
+ * uses x0, x1
+ */
+init_tzpc:
+ /* Set Non Secure access for all devices protected via TZPC */
+ ldr x1, =TZPCDECPROT_0_SET_BASE /* decode Protection-0 Set Reg */
+ mov w0, #0xFF /* set decode region to NS, Bits[7:0] */
+ str w0, [x1]
+
+ ldr x1, =TZPCDECPROT_1_SET_BASE /* decode Protection-1 Set Reg */
+ mov w0, #0xFF /* set decode region to NS, Bits[7:0] */
+ str w0, [x1]
+
+ ldr x1, =TZPCDECPROT_2_SET_BASE /* decode Protection-2 Set Reg */
+ mov w0, #0xFF /* set decode region to NS, Bits[7:0] */
+ str w0, [x1]
+
+ /* entire SRAM as NS */
+ ldr x1, =NXP_OCRAM_TZPC_ADDR /* secure RAM region size Reg */
+ mov w0, #0x00000000 /* 0x00000000 = no secure region */
+ str w0, [x1]
+
+ ret
+
+/*
+ * This function performs any needed initialization on SecMon for
+ * boot services
+ */
+initSecMon:
+ /* Read the register hpcomr */
+ ldr x1, =NXP_SNVS_ADDR
+ ldr w0, [x1, #SECMON_HPCOMR_OFFSET]
+ /* Turn off secure access for the privileged registers */
+ orr w0, w0, #SECMON_HPCOMR_NPSWAEN
+ /* Write back */
+ str w0, [x1, #SECMON_HPCOMR_OFFSET]
+
+ ret
+
+/*
+ * This function checks to see if cores which are to be disabled have been
+ * released from reset - if not, it releases them
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
+ */
+release_disabled:
+ stp x18, x30, [sp, #-16]!
+
+ /*
+ * Get the number of cpus on this device
+ * Calling the below c function.
+ * No need to Callee saved registers x9-x15,
+ * as these registers are not used by the callee
+ * prior to calling the below C-routine.
+ */
+ bl get_tot_num_cores
+ mov x6, x0
+
+ /* Read COREDISABLESR */
+ mov x0, #NXP_DCFG_ADDR
+ ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+
+ mov x0, #NXP_RESET_ADDR
+ ldr w5, [x0, #BRR_OFFSET]
+
+ /* Load the core mask for the first core */
+ mov x7, #1
+
+ /*
+ * x4 = COREDISABLESR
+ * x5 = BRR
+ * x6 = loop count
+ * x7 = core mask bit
+ */
+2:
+ /* Check if the core is to be disabled */
+ tst x4, x7
+ b.eq 1f
+
+ /* See if disabled cores have already been released from reset */
+ tst x5, x7
+ b.ne 1f
+
+ /* If core has not been released, then release it (0-3) */
+ mov x0, x7
+ bl _soc_core_release
+
+ /* Record the core state in the data area (0-3) */
+ mov x0, x7
+ mov x1, #CORE_DISABLED
+ bl _setCoreState
+1:
+ /* Decrement the counter */
+ subs x6, x6, #1
+ b.le 3f
+ /* Shift the core mask to the next core */
+ lsl x7, x7, #1
+ /* Continue */
+ b 2b
+3:
+ ldp x18, x30, [sp], #16
+ ret
+
+/*
+ * Write a register in the DCFG block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_dcfg:
+ ldr x2, =NXP_DCFG_ADDR
+ str w1, [x2, x0]
+ ret
+
+/*
+ * Read a register in the DCFG block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+_read_reg_dcfg:
+ ldr x2, =NXP_DCFG_ADDR
+ ldr w1, [x2, x0]
+ mov w0, w1
+ ret
+
+/*
+ * This function returns an mpidr value for a core, given a core_mask_lsb
+ * in: x0 = core mask lsb
+ * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits
+ * uses x0, x1
+ */
+get_mpidr_value:
+ /* Convert a core mask to an SoC core number */
+ clz w0, w0
+ mov w1, #31
+ sub w0, w1, w0
+
+ /* Get the mpidr core number from the SoC core number */
+ mov w1, wzr
+ tst x0, #1
+ b.eq 1f
+ orr w1, w1, #1
+1:
+ /* Extract the cluster number */
+ lsr w0, w0, #1
+ orr w0, w1, w0, lsl #8
+
+ ret
+
+/*
+ * This function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor rd base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_rd_base:
+ /* Get the 0-based core number */
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ /* x2 = core number / loop counter */
+ ldr x0, =NXP_GICR_ADDR
+ mov x1, #GIC_RD_OFFSET
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+
+/*
+ * This function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor sgi base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_sgi_base:
+ /* Get the 0-based core number */
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ /* x2 = core number / loop counter */
+ ldr x0, =NXP_GICR_SGI_ADDR
+ mov x1, #GIC_SGI_OFFSET
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+
+/*
+ * Write a register in the RESET block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_reset:
+ ldr x2, =NXP_RESET_ADDR
+ str w1, [x2, x0]
+ ret
+
+/*
+ * Read a register in the RESET block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+_read_reg_reset:
+ ldr x1, =NXP_RESET_ADDR
+ ldr w0, [x1, x0]
+ ret
diff --git a/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S b/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S
new file mode 100644
index 0000000..ec67529
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+.globl plat_secondary_cold_boot_setup
+.globl plat_is_my_cpu_primary
+.globl plat_reset_handler
+.globl platform_mem_init
+
+func platform_mem1_init
+ ret
+endfunc platform_mem1_init
+
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+func apply_platform_errata
+ ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+ mov x29, x30
+ bl apply_platform_errata
+
+#if defined(IMAGE_BL31)
+ ldr x0, =POLICY_SMMU_PAGESZ_64K
+ cbz x0, 1f
+ /* Set the SMMU page size in the sACR register */
+ bl _set_smmu_pagesz_64
+#endif
+1:
+ mov x30, x29
+ ret
+endfunc plat_reset_handler
+
+/*
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ */
+func plat_secondary_cold_boot_setup
+ /* ls1028a does not do cold boot for secondary CPU */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+/*
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu.
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, 0x0
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
diff --git a/plat/nxp/soc-ls1028a/include/soc.h b/plat/nxp/soc-ls1028a/include/soc.h
new file mode 100644
index 0000000..b1d044a
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/include/soc.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOC_H
+#define SOC_H
+
+/* Chassis specific defines - common across SoC's of a particular platform */
+#include <dcfg_lsch3.h>
+#include <soc_default_base_addr.h>
+#include <soc_default_helper_macros.h>
+
+/*
+ * SVR Definition of LS1028A
+ * (not include major and minor rev)
+ * These info is listed in Table B-6. DCFG differences
+ * between LS1028A and LS1027A of LS1028ARM(Reference Manual)
+ */
+#define SVR_LS1017AN 0x870B25
+#define SVR_LS1017AE 0x870B24
+#define SVR_LS1018AN 0x870B21
+#define SVR_LS1018AE 0x870B20
+#define SVR_LS1027AN 0x870B05
+#define SVR_LS1027AE 0x870B04
+#define SVR_LS1028AN 0x870B01
+#define SVR_LS1028AE 0x870B00
+
+/* Number of cores in platform */
+#define PLATFORM_CORE_COUNT 2
+#define NUMBER_OF_CLUSTERS 1
+#define CORES_PER_CLUSTER 2
+
+/* Set to 0 if the clusters are not symmetrical */
+#define SYMMETRICAL_CLUSTERS 1
+
+#define NUM_DRAM_REGIONS 3
+
+#define NXP_DRAM0_ADDR 0x80000000
+#define NXP_DRAM0_MAX_SIZE 0x80000000 /* 2GB */
+
+#define NXP_DRAM1_ADDR 0x2080000000
+#define NXP_DRAM1_MAX_SIZE 0x1F80000000 /* 126G */
+
+#define NXP_DRAM2_ADDR 0x6000000000
+#define NXP_DRAM2_MAX_SIZE 0x2000000000 /* 128G */
+
+/* DRAM0 Size defined in platform_def.h */
+#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE
+
+/* CCSR space memory Map */
+#undef NXP_UART_ADDR
+#define NXP_UART_ADDR 0x021C0500
+
+#undef NXP_UART1_ADDR
+#define NXP_UART1_ADDR 0x021C0600
+
+#undef NXP_WDOG1_TZ_ADDR
+#define NXP_WDOG1_TZ_ADDR 0x023C0000
+
+#undef NXP_GICR_ADDR
+#define NXP_GICR_ADDR 0x06040000
+
+#undef NXP_GICR_SGI_ADDR
+#define NXP_GICR_SGI_ADDR 0x06050000
+
+/* EPU register offsets and values */
+#define EPU_EPGCR_OFFSET 0x0
+#define EPU_EPIMCR10_OFFSET 0x128
+#define EPU_EPCTR10_OFFSET 0xa28
+#define EPU_EPCCR10_OFFSET 0x828
+#define EPU_EPCCR10_VAL 0xb2800000
+#define EPU_EPIMCR10_VAL 0xba000000
+#define EPU_EPCTR10_VAL 0x0
+#define EPU_EPGCR_VAL (1 << 31)
+
+/* PORSR1 */
+#define PORSR1_RCW_MASK 0x07800000
+#define PORSR1_RCW_SHIFT 23
+
+#define SDHC1_VAL 0x8
+#define SDHC2_VAL 0x9
+#define I2C1_VAL 0xa
+#define FLEXSPI_NAND2K_VAL 0xc
+#define FLEXSPI_NAND4K_VAL 0xd
+#define FLEXSPI_NOR 0xf
+
+/*
+ * Required LS standard platform porting definitions
+ * for CCI-400
+ */
+#define NXP_CCI_CLUSTER0_SL_IFACE_IX 4
+
+/* Defines required for using XLAT tables from ARM common code */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 40)
+
+/* Clock Divisors */
+#define NXP_PLATFORM_CLK_DIVIDER 1
+#define NXP_UART_CLK_DIVIDER 2
+
+/* dcfg register offsets and values */
+#define DCFG_DEVDISR2_ENETC (1 << 31)
+
+#define MPIDR_AFFINITY0_MASK 0x00FF
+#define MPIDR_AFFINITY1_MASK 0xFF00
+#define CPUECTLR_DISABLE_TWALK_PREFETCH 0x4000000000
+#define CPUECTLR_INS_PREFETCH_MASK 0x1800000000
+#define CPUECTLR_DAT_PREFETCH_MASK 0x0300000000
+#define OSDLR_EL1_DLK_LOCK 0x1
+#define CNTP_CTL_EL0_EN 0x1
+#define CNTP_CTL_EL0_IMASK 0x2
+
+#define SYSTEM_PWR_DOMAINS 1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
+ NUMBER_OF_CLUSTERS + \
+ SYSTEM_PWR_DOMAINS)
+
+/* Power state coordination occurs at the system level */
+#define PLAT_PD_COORD_LVL MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LVL PLAT_PD_COORD_LVL
+
+/* Local power state for power domains in Run state */
+#define LS_LOCAL_STATE_RUN PSCI_LOCAL_STATE_RUN
+
+/* define retention state */
+#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1)
+#define LS_LOCAL_STATE_RET PLAT_MAX_RET_STATE
+
+/* define power-down state */
+#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 1)
+#define LS_LOCAL_STATE_OFF PLAT_MAX_OFF_STATE
+
+/* One cache line needed for bakery locks on ARM platforms */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+#ifndef __ASSEMBLER__
+/* CCI slave interfaces */
+static const int cci_map[] = {
+ NXP_CCI_CLUSTER0_SL_IFACE_IX,
+};
+void soc_init_lowlevel(void);
+void soc_init_percpu(void);
+void _soc_set_start_addr(unsigned long addr);
+void _set_platform_security(void);
+#endif
+
+#endif /* SOC_H */
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c b/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c
new file mode 100644
index 0000000..d82be51
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <string.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+const struct ddr_cfg_regs static_1600 = {
+ .cs[0].config = U(0x80040422),
+ .cs[0].bnds = U(0xFF),
+ .sdram_cfg[0] = U(0xE50C0004),
+ .sdram_cfg[1] = U(0x401100),
+ .timing_cfg[0] = U(0x91550018),
+ .timing_cfg[1] = U(0xBAB40C42),
+ .timing_cfg[2] = U(0x48C111),
+ .timing_cfg[3] = U(0x1111000),
+ .timing_cfg[4] = U(0x2),
+ .timing_cfg[5] = U(0x3401400),
+ .timing_cfg[7] = U(0x23300000),
+ .timing_cfg[8] = U(0x2114600),
+ .sdram_mode[0] = U(0x3010210),
+ .sdram_mode[9] = U(0x4000000),
+ .sdram_mode[8] = U(0x500),
+ .sdram_mode[2] = U(0x10210),
+ .sdram_mode[10] = U(0x400),
+ .sdram_mode[11] = U(0x4000000),
+ .sdram_mode[4] = U(0x10210),
+ .sdram_mode[12] = U(0x400),
+ .sdram_mode[13] = U(0x4000000),
+ .sdram_mode[6] = U(0x10210),
+ .sdram_mode[14] = U(0x400),
+ .sdram_mode[15] = U(0x4000000),
+ .interval = U(0x18600618),
+ .data_init = U(0xdeadbeef),
+ .zq_cntl = U(0x8A090705),
+ .clk_cntl = U(0x2000000),
+ .cdr[0] = U(0x80040000),
+ .cdr[1] = U(0xA181),
+ .wrlvl_cntl[0] = U(0x8675F605),
+ .wrlvl_cntl[1] = U(0x6070700),
+ .wrlvl_cntl[2] = U(0x0000008),
+ .dq_map[0] = U(0x5b65b658),
+ .dq_map[1] = U(0xd96d8000),
+ .dq_map[2] = U(0),
+ .dq_map[3] = U(0x1600000),
+ .debug[28] = U(0x00700046),
+};
+
+unsigned long long board_static_ddr(struct ddr_info *priv)
+{
+ memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600));
+ return ULL(0x100000000);
+}
+
+#else
+
+static const struct rc_timing rcz[] = {
+ {1600, 8, 5},
+ {}
+};
+
+static const struct board_timing ram[] = {
+ {0x1f, rcz, 0x1020200, 0x00000003},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ ret = cal_board_params(priv, ram, ARRAY_SIZE(ram));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->bstopre = U(0x40); /* precharge value */
+ popts->half_strength_drive_en = 1;
+ popts->cpo_sample = U(0x46);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
+ DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */
+
+ popts->addr_hash = 1; /* address hashing */
+ return 0;
+}
+
+/* DDR model number: MT40A1G8SA-075:E */
+struct dimm_params ddr_raw_timing = {
+ .n_ranks = U(1),
+ .rank_density = ULL(4294967296),
+ .capacity = ULL(4294967296),
+ .primary_sdram_width = U(32),
+ .ec_sdram_width = U(4),
+ .rdimm = U(0),
+ .mirrored_dimm = U(0),
+ .n_row_addr = U(16),
+ .n_col_addr = U(10),
+ .bank_group_bits = U(2),
+ .edc_config = U(2),
+ .burst_lengths_bitmask = U(0x0c),
+ .tckmin_x_ps = 750,
+ .tckmax_ps = 1900,
+ .caslat_x = U(0x0001FFE00),
+ .taa_ps = 13500,
+ .trcd_ps = 13500,
+ .trp_ps = 13500,
+ .tras_ps = 32000,
+ .trc_ps = 45500,
+ .twr_ps = 15000,
+ .trfc1_ps = 350000,
+ .trfc2_ps = 260000,
+ .trfc4_ps = 160000,
+ .tfaw_ps = 21000,
+ .trrds_ps = 3000,
+ .trrdl_ps = 4900,
+ .tccdl_ps = 5000,
+ .refresh_rate_ps = U(7800000),
+ .dq_mapping[0] = U(0x16),
+ .dq_mapping[1] = U(0x36),
+ .dq_mapping[2] = U(0x16),
+ .dq_mapping[3] = U(0x36),
+ .dq_mapping[4] = U(0x16),
+ .dq_mapping[5] = U(0x36),
+ .dq_mapping[6] = U(0x16),
+ .dq_mapping[7] = U(0x36),
+ .dq_mapping[8] = U(0x16),
+ .dq_mapping[9] = U(0x0),
+ .dq_mapping[10] = U(0x0),
+ .dq_mapping[11] = U(0x0),
+ .dq_mapping[12] = U(0x0),
+ .dq_mapping[13] = U(0x0),
+ .dq_mapping[14] = U(0x0),
+ .dq_mapping[15] = U(0x0),
+ .dq_mapping[16] = U(0x0),
+ .dq_mapping[17] = U(0x0),
+ .dq_mapping_ors = U(0),
+ .rc = U(0x1f),
+};
+
+int ddr_get_ddr_params(struct dimm_params *pdimm,
+ struct ddr_conf *conf)
+{
+ static const char dimm_model[] = "Fixed DDR on board";
+
+ conf->dimm_in_use[0] = 1;
+ memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
+ memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
+
+ return 1;
+}
+#endif
+
+int64_t init_ddr(void)
+{
+ struct ddr_info info;
+ struct sysinfo sys;
+ int64_t dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ get_clocks(&sys);
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = 1;
+ info.dimm_on_ctlr = 1;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h b/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h
new file mode 100644
index 0000000..63c0219
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+#include <cortex_a72.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+#define NXP_SPD_EEPROM0 0x51
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0xC000)
+
+#ifdef SD_BOOT
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
+ - NXP_SD_BLOCK_BUF_SIZE)
+#else
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#endif
+#define BL2_TEXT_LIMIT (BL2_LIMIT)
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+#define BL31_WDOG_SEC 89
+
+/*
+ * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLAT_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform.c b/plat/nxp/soc-ls1028a/ls1028ardb/platform.c
new file mode 100644
index 0000000..65d508c
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk b/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk
new file mode 100644
index 0000000..c455000
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk
@@ -0,0 +1,33 @@
+#
+# Copyright 2020-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Board-specific build parameters
+BOOT_MODE ?= flexspi_nor
+BOARD := ls1028ardb
+POVDD_ENABLE := no
+WARM_BOOT := no
+
+# DDR build parameters
+NUM_OF_DDRC := 1
+CONFIG_DDR_NODIMM := 1
+DDR_ECC_EN := yes
+
+# On-board flash
+FLASH_TYPE := MT35XU02G
+XSPI_FLASH_SZ := 0x10000000
+
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c \
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := flexspi_nor \
+ sd \
+ emmc
+
+# Add platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Add SoC build info
+include plat/nxp/soc-ls1028a/soc.mk
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h b/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h
new file mode 100644
index 0000000..bbad293
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/policy.h b/plat/nxp/soc-ls1028a/ls1028ardb/policy.h
new file mode 100644
index 0000000..67a8b45
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/*
+ * Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1028a/soc.c b/plat/nxp/soc-ls1028a/soc.c
new file mode 100644
index 0000000..4f67154
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/soc.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <endian.h>
+
+#include <arch.h>
+#include <caam.h>
+#include <cassert.h>
+#include <cci.h>
+#include <common/debug.h>
+#include <dcfg.h>
+#include <i2c.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <ls_interconnect.h>
+#include <mmio.h>
+#if TRUSTED_BOARD_BOOT
+#include <nxp_smmu.h>
+#endif
+#include <nxp_timer.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
+#include <plat_console.h>
+#include <plat_gic.h>
+#include <plat_tzc400.h>
+#include <pmu.h>
+#include <scfg.h>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#include "plat_common.h"
+#include "platform_def.h"
+#include "soc.h"
+
+static dcfg_init_info_t dcfg_init_data = {
+ .g_nxp_dcfg_addr = NXP_DCFG_ADDR,
+ .nxp_sysclk_freq = NXP_SYSCLK_FREQ,
+ .nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
+ .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
+};
+
+static struct soc_type soc_list[] = {
+ SOC_ENTRY(LS1017AN, LS1017AN, 1, 1),
+ SOC_ENTRY(LS1017AE, LS1017AE, 1, 1),
+ SOC_ENTRY(LS1018AN, LS1018AN, 1, 1),
+ SOC_ENTRY(LS1018AE, LS1018AE, 1, 1),
+ SOC_ENTRY(LS1027AN, LS1027AN, 1, 2),
+ SOC_ENTRY(LS1027AE, LS1027AE, 1, 2),
+ SOC_ENTRY(LS1028AN, LS1028AN, 1, 2),
+ SOC_ENTRY(LS1028AE, LS1028AE, 1, 2),
+};
+
+CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
+ assert_invalid_ls1028a_cluster_count);
+
+/*
+ * Function returns the base counter frequency
+ * after reading the first entry at CNTFID0 (0x20 offset).
+ *
+ * Function is used by:
+ * 1. ARM common code for PSCI management.
+ * 2. ARM Generic Timer init.
+ *
+ */
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+ /*
+ * Below register specifies the base frequency of the system counter.
+ * As per NXP Board Manuals:
+ * The system counter always works with SYS_REF_CLK/4 frequency clock.
+ */
+ counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF);
+
+ return counter_base_frequency;
+}
+
+#ifdef IMAGE_BL2
+void soc_preload_setup(void)
+{
+}
+
+void soc_early_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+#ifdef CONFIG_OCRAM_ECC_EN
+ ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
+ dcfg_init(&dcfg_init_data);
+ enable_timer_base_to_cluster(NXP_PMU_ADDR);
+ enable_core_tb(NXP_PMU_ADDR);
+ dram_regions_info_t *dram_regions_info = get_dram_regions_info();
+
+#ifdef POLICY_FUSE_PROVISION
+ gpio_init(&gpio_init_data);
+ sec_init(NXP_CAAM_ADDR);
+#endif
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+ enum boot_device dev = get_boot_dev();
+ /*
+ * Mark the buffer for SD in OCRAM as non secure.
+ * The buffer is assumed to be at end of OCRAM for
+ * the logic below to calculate TZPC programming
+ */
+ if (dev == BOOT_DEVICE_EMMC || dev == BOOT_DEVICE_SDHC2_EMMC) {
+ /*
+ * Calculate the region in OCRAM which is secure
+ * The buffer for SD needs to be marked non-secure
+ * to allow SD to do DMA operations on it
+ */
+ uint32_t secure_region = (NXP_OCRAM_SIZE - NXP_SD_BLOCK_BUF_SIZE);
+ uint32_t mask = secure_region/TZPC_BLOCK_SIZE;
+
+ mmio_write_32(NXP_OCRAM_TZPC_ADDR, mask);
+
+ /* Add the entry for buffer in MMU Table */
+ mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR,
+ NXP_SD_BLOCK_BUF_SIZE, MT_DEVICE | MT_RW | MT_NS);
+ }
+
+#if TRUSTED_BOARD_BOOT
+ uint32_t mode;
+
+ sfp_init(NXP_SFP_ADDR);
+
+ /*
+ * For secure boot disable SMMU.
+ * Later when platform security policy comes in picture,
+ * this might get modified based on the policy
+ */
+ if (check_boot_mode_secure(&mode) == true) {
+ bypass_smmu(NXP_SMMU_ADDR);
+ }
+
+ /*
+ * For Mbedtls currently crypto is not supported via CAAM
+ * enable it when that support is there. In tbbr.mk
+ * the CAAM_INTEG is set as 0.
+ */
+#ifndef MBEDTLS_X509
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled()) {
+ sec_init(NXP_CAAM_ADDR);
+ } else {
+ INFO("SEC is disabled.\n");
+ }
+#endif
+#endif
+
+ /* Set eDDRTQ for DDR performance */
+ scfg_setbits32((void *)(NXP_SCFG_ADDR + 0x210), 0x1f1f1f1f);
+
+ soc_errata();
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ */
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ delay_timer_init(NXP_TIMER_ADDR);
+ i2c_init(NXP_I2C_ADDR);
+ dram_regions_info->total_dram_size = init_ddr();
+}
+
+void soc_bl2_prepare_exit(void)
+{
+#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
+ set_sfp_wr_disable();
+#endif
+}
+
+/*
+ * This function returns the boot device based on RCW_SRC
+ */
+enum boot_device get_boot_dev(void)
+{
+ enum boot_device src = BOOT_DEVICE_NONE;
+ uint32_t porsr1;
+ uint32_t rcw_src;
+
+ porsr1 = read_reg_porsr1();
+
+ rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
+ switch (rcw_src) {
+ case FLEXSPI_NOR:
+ src = BOOT_DEVICE_FLEXSPI_NOR;
+ INFO("RCW BOOT SRC is FLEXSPI NOR\n");
+ break;
+ case FLEXSPI_NAND2K_VAL:
+ case FLEXSPI_NAND4K_VAL:
+ INFO("RCW BOOT SRC is FLEXSPI NAND\n");
+ src = BOOT_DEVICE_FLEXSPI_NAND;
+ break;
+ case SDHC1_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD\n");
+ break;
+ case SDHC2_VAL:
+ src = BOOT_DEVICE_SDHC2_EMMC;
+ INFO("RCW BOOT SRC is EMMC\n");
+ break;
+ default:
+ break;
+ }
+
+ return src;
+}
+
+/*
+ * This function sets up access permissions on memory regions
+ ****************************************************************************/
+void soc_mem_access(void)
+{
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+ struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION];
+ int dram_idx = 0;
+ /* index 0 is reserved for region-0 */
+ int index = 1;
+
+ for (dram_idx = 0; dram_idx < info_dram_regions->num_dram_regions;
+ dram_idx++) {
+ if (info_dram_regions->region[dram_idx].size == 0) {
+ ERROR("DDR init failure, or");
+ ERROR("DRAM regions not populated correctly.\n");
+ break;
+ }
+
+ index = populate_tzc400_reg_list(tzc400_reg_list,
+ dram_idx, index,
+ info_dram_regions->region[dram_idx].addr,
+ info_dram_regions->region[dram_idx].size,
+ NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
+ }
+
+ mem_access_setup(NXP_TZC_ADDR, index, tzc400_reg_list);
+}
+
+#else
+
+static unsigned char _power_domain_tree_desc[NUMBER_OF_CLUSTERS + 2];
+/*
+ * This function dynamically constructs the topology according to
+ * SoC Flavor and returns it.
+ */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+ unsigned int i;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ /*
+ * The highest level is the system level. The next level is constituted
+ * by clusters and then cores in clusters.
+ */
+ _power_domain_tree_desc[0] = 1;
+ _power_domain_tree_desc[1] = num_clusters;
+
+ for (i = 0; i < _power_domain_tree_desc[1]; i++)
+ _power_domain_tree_desc[i + 2] = cores_per_cluster;
+
+ return _power_domain_tree_desc;
+}
+
+/*
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ return num_clusters;
+}
+
+void soc_early_platform_setup2(void)
+{
+ dcfg_init(&dcfg_init_data);
+ /* Initialize system level generic timer for Socs */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+}
+
+void soc_platform_setup(void)
+{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ static uintptr_t target_mask_array[PLATFORM_CORE_COUNT];
+ static interrupt_prop_t ls_interrupt_props[] = {
+ PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S),
+ PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0)
+ };
+
+ plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR,
+ PLATFORM_CORE_COUNT,
+ ls_interrupt_props,
+ ARRAY_SIZE(ls_interrupt_props),
+ target_mask_array,
+ plat_core_pos);
+
+ plat_ls_gic_init();
+ enable_init_timer();
+}
+
+/* This function initializes the soc from the BL31 module */
+void soc_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ /* Low-level init of the soc */
+ soc_init_lowlevel();
+ _init_global_data();
+ soc_init_percpu();
+ _initialize_psci();
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /* Enable Interconnect coherency for the primary CPU's cluster. */
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ /* Set platform security policies */
+ _set_platform_security();
+
+ /* Init SEC Engine which will be used by SiP */
+ if (is_sec_enabled()) {
+ sec_init(NXP_CAAM_ADDR);
+ } else {
+ INFO("SEC is disabled.\n");
+ }
+}
+
+#ifdef NXP_WDOG_RESTART
+static uint64_t wdog_interrupt_handler(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+{
+ uint8_t data = WDOG_RESET_FLAG;
+
+ wr_nv_app_data(WDT_RESET_FLAG_OFFSET,
+ (uint8_t *)&data, sizeof(data));
+
+ mmio_write_32(NXP_RST_ADDR + RSTCNTL_OFFSET, SW_RST_REQ_INIT);
+
+ return 0;
+}
+#endif
+
+void soc_runtime_setup(void)
+{
+#ifdef NXP_WDOG_RESTART
+ request_intr_type_el3(BL31_NS_WDOG_WS1, wdog_interrupt_handler);
+#endif
+}
+
+/* This function returns the total number of cores in the SoC. */
+unsigned int get_tot_num_cores(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ return (num_clusters * cores_per_cluster);
+}
+
+/* This function returns the PMU IDLE Cluster mask. */
+unsigned int get_pmu_idle_cluster_mask(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ return ((1 << num_clusters) - 2);
+}
+
+/* This function returns the PMU Flush Cluster mask. */
+unsigned int get_pmu_flush_cluster_mask(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ return ((1 << num_clusters) - 2);
+}
+
+/* This function returns the PMU idle core mask. */
+unsigned int get_pmu_idle_core_mask(void)
+{
+ return ((1 << get_tot_num_cores()) - 2);
+}
+
+/* Function to return the SoC SYS CLK */
+unsigned int get_sys_clk(void)
+{
+ return NXP_SYSCLK_FREQ;
+}
+#endif
diff --git a/plat/nxp/soc-ls1028a/soc.def b/plat/nxp/soc-ls1028a/soc.def
new file mode 100644
index 0000000..e133982
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/soc.def
@@ -0,0 +1,95 @@
+#
+# Copyright 2018-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# This file contains the basic architecture definitions that drive the build
+#
+# -----------------------------------------------------------------------------
+
+CORE_TYPE := a72
+
+CACHE_LINE := 6
+
+# Set to GIC400 or GIC500
+GIC := GIC500
+
+# Set to CCI400 or CCN504 or CCN508
+INTERCONNECT := CCI400
+
+# Layerscape chassis level - set to 3=LSCH3 or 2=LSCH2
+CHASSIS := 3_2
+
+# TZC used is TZC380 or TZC400
+TZC_ID := TZC400
+
+# CONSOLE is NS16550 or PL011
+CONSOLE := NS16550
+
+# DDR PHY generation to be used
+PLAT_DDR_PHY := PHY_GEN1
+
+PHYS_SYS := 64
+
+# Max Size of CSF header. Required to define BL2 TEXT LIMIT in soc.def
+# Input to CST create_hdr_esbc tool
+CSF_HDR_SZ := 0x3000
+
+# In IMAGE_BL2, compile time flag for handling Cache coherency
+# with CAAM for BL2 running from OCRAM
+SEC_MEM_NON_COHERENT := yes
+
+# OCRAM MAP for BL2
+# Before BL2
+# 0x18000000 - 0x18009fff -> Used by ROM code
+# 0x1800a000 - 0x1800dfff -> CSF header for BL2
+# For FlexSFlexSPI boot
+# 0x1800e000 - 0x18040000 -> Reserved for BL2 binary
+# For SD boot
+# 0x1800e000 - 0x18030000 -> Reserved for BL2 binary
+# 0x18030000 - 0x18040000 -> Reserved for SD buffer
+OCRAM_START_ADDR := 0x18000000
+OCRAM_SIZE := 0x40000
+
+# Area of OCRAM reserved by ROM code
+NXP_ROM_RSVD := 0xa000
+
+# Location of BL2 on OCRAM
+BL2_BASE_ADDR := $(shell echo $$(( $(OCRAM_START_ADDR) + $(NXP_ROM_RSVD) + $(CSF_HDR_SZ) )))
+
+# Covert to HEX to be used by create_pbl.mk
+BL2_BASE := $(shell echo "0x"$$(echo "obase=16; ${BL2_BASE_ADDR}" | bc))
+
+# BL2_HDR_LOC is at (BL2_BASE + NXP_ROM_RSVD)
+# This value BL2_HDR_LOC + CSF_HDR_SZ should not
+# overalp with BL2_BASE
+# Input to CST create_hdr_isbc tool
+BL2_HDR_LOC := 0x1800A000
+
+# SoC ERRATAS to be enabled
+ERRATA_SOC_A008850 := 1
+
+ERRATA_DDR_A009803 := 1
+ERRATA_DDR_A009942 := 1
+ERRATA_DDR_A010165 := 1
+
+# Enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC := 1
+
+# Define Endianness of each module
+NXP_GUR_ENDIANNESS := LE
+NXP_DDR_ENDIANNESS := LE
+NXP_SEC_ENDIANNESS := LE
+NXP_SFP_ENDIANNESS := LE
+NXP_SNVS_ENDIANNESS := LE
+NXP_ESDHC_ENDIANNESS := LE
+NXP_QSPI_ENDIANNESS := LE
+NXP_FSPI_ENDIANNESS := LE
+
+NXP_SFP_VER := 3_4
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN := yes
diff --git a/plat/nxp/soc-ls1028a/soc.mk b/plat/nxp/soc-ls1028a/soc.mk
new file mode 100644
index 0000000..92d8e98
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/soc.mk
@@ -0,0 +1,113 @@
+#
+# Copyright 2020-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# SoC-specific build parameters
+SOC := ls1028a
+PLAT_PATH := plat/nxp
+PLAT_COMMON_PATH := plat/nxp/common
+PLAT_DRIVERS_PATH := drivers/nxp
+PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC}
+BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD}
+
+# Get SoC-specific definitions
+include ${PLAT_SOC_PATH}/soc.def
+include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
+SECURE_BOOT := yes
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM))
+
+$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+# Selecting PSCI & SIP_SVC support
+$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31))
+
+PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\
+ -I${BOARD_PATH}\
+ -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
+ -I${PLAT_SOC_PATH}/include\
+ -I${PLAT_COMMON_PATH}/soc_errata
+
+ifeq (${SECURE_BOOT},yes)
+include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
+endif
+
+ifeq ($(WARM_BOOT),yes)
+include ${PLAT_COMMON_PATH}/warm_reset/warm_reset.mk
+endif
+
+ifeq (${NXP_NV_SW_MAINT_LAST_EXEC_DATA}, yes)
+include ${PLAT_COMMON_PATH}/nv_storage/nv_storage.mk
+endif
+
+ifeq (${PSCI_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/psci/psci.mk
+endif
+
+ifeq (${SIPSVC_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk
+endif
+
+ifeq (${DDR_FIP_IO_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/fip_handler/ddr_fip/ddr_fip_io.mk
+endif
+
+# For fuse-fip & fuse-programming
+ifeq (${FUSE_PROG}, 1)
+include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk
+endif
+
+ifeq (${IMG_LOADR_NEEDED},yes)
+include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk
+endif
+
+# Adding source files for the above selected drivers.
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+# Adding SoC specific files
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
+
+PLAT_INCLUDES += ${NV_STORAGE_INCLUDES}\
+ ${WARM_RST_INCLUDES}
+
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\
+ ${WARM_RST_BL31_SOURCES}\
+ ${PSCI_SOURCES}\
+ ${SIPSVC_SOURCES}\
+ ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S
+
+PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\
+ ${PLAT_SOC_PATH}/aarch64/${SOC}_helpers.S\
+ ${NV_STORAGE_SOURCES}\
+ ${WARM_RST_BL_COMM_SOURCES}\
+ ${PLAT_SOC_PATH}/soc.c
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S \
+ ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S
+endif
+
+BL2_SOURCES += ${DDR_CNTLR_SOURCES}\
+ ${TBBR_SOURCES}\
+ ${FUSE_SOURCES}
+
+# Adding TFA setup files
+include ${PLAT_PATH}/common/setup/common.mk
diff --git a/plat/nxp/soc-lx2160a/erratas_soc.mk b/plat/nxp/soc-lx2160a/erratas_soc.mk
deleted file mode 100644
index 07bed03..0000000
--- a/plat/nxp/soc-lx2160a/erratas_soc.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright 2020 NXP
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-# Platform Errata Build flags.
-# These should be enabled by the platform if the erratum workaround needs to be
-# applied.
-
-# Flag to apply erratum 50426 workaround during reset.
-ERRATA_SOC_A050426 ?= 0
-
-# Process ERRATA_SOC_A050426 flag
-ifeq (${ERRATA_SOC_A050426}, 1)
-INCL_SOC_ERRATA_SOURCES := yes
-$(eval $(call add_define,ERRATA_SOC_A050426))
-endif
-
-ifeq (${INCL_SOC_ERRATA_SOURCES},yes)
-BL2_SOURCES += ${PLAT_SOC_PATH}/erratas_soc.c
-endif
diff --git a/plat/nxp/soc-lx2160a/include/errata.h b/plat/nxp/soc-lx2160a/include/errata.h
deleted file mode 100644
index 937824a..0000000
--- a/plat/nxp/soc-lx2160a/include/errata.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2020 NXP
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef ERRATA_H
-#define ERRATA_H
-
-#ifdef ERRATA_SOC_A050426
-void erratum_a050426(void);
-#endif
-
-#endif /* ERRATA_H */
diff --git a/plat/nxp/soc-lx2160a/include/soc.h b/plat/nxp/soc-lx2160a/include/soc.h
index bd23620..7cc4a03 100644
--- a/plat/nxp/soc-lx2160a/include/soc.h
+++ b/plat/nxp/soc-lx2160a/include/soc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -52,11 +52,10 @@
#define FLEXSPI_NOR 0xf
/* End: Macros used by soc.c: get_boot_dev */
-/* bits */
-/* SVR Definition */
-#define SVR_LX2160A 0x04
-#define SVR_LX2120A 0x14
-#define SVR_LX2080A 0x05
+/* SVR Definition (not include major and minor rev) */
+#define SVR_LX2160A 0x873601
+#define SVR_LX2120A 0x873621
+#define SVR_LX2080A 0x873603
/* Number of cores in platform */
/* Used by common code for array initialization */
diff --git a/plat/nxp/soc-lx2160a/soc.c b/plat/nxp/soc-lx2160a/soc.c
index e0a2fe9..2209fda 100644
--- a/plat/nxp/soc-lx2160a/soc.c
+++ b/plat/nxp/soc-lx2160a/soc.c
@@ -82,28 +82,6 @@
.master_to_rn_id_map = master_to_rn_id_map
};
-/*******************************************************************************
- * This function returns the number of clusters in the SoC
- ******************************************************************************/
-static unsigned int get_num_cluster(void)
-{
- const soc_info_t *soc_info = get_soc_info();
- uint32_t num_clusters = NUMBER_OF_CLUSTERS;
- unsigned int i;
-
- for (i = 0U; i < ARRAY_SIZE(soc_list); i++) {
- if (soc_list[i].personality == soc_info->personality) {
- num_clusters = soc_list[i].num_clusters;
- break;
- }
- }
-
- VERBOSE("NUM of cluster = 0x%x\n", num_clusters);
-
- return num_clusters;
-}
-
-
/******************************************************************************
* Function returns the base counter frequency
* after reading the first entry at CNTFID0 (0x20 offset).
@@ -142,8 +120,10 @@
static void soc_interconnect_config(void)
{
unsigned long long val = 0x0U;
+ uint8_t num_clusters, cores_per_cluster;
- uint32_t num_clusters = get_num_cluster();
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list),
+ &num_clusters, &cores_per_cluster);
if (num_clusters == 6U) {
ccn_init(&plat_six_cluster_ccn_desc);
@@ -271,9 +251,7 @@
MT_DEVICE | MT_RW | MT_NS);
}
-#ifdef ERRATA_SOC_A050426
- erratum_a050426();
-#endif
+ soc_errata();
#if (TRUSTED_BOARD_BOOT) || defined(POLICY_FUSE_PROVISION)
sfp_init(NXP_SFP_ADDR);
@@ -466,7 +444,12 @@
******************************************************************************/
void soc_init(void)
{
- /* low-level init of the soc */
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list),
+ &num_clusters, &cores_per_cluster);
+
+ /* low-level init of the soc */
soc_init_start();
soc_init_percpu();
_init_global_data();
@@ -478,8 +461,6 @@
panic();
}
- uint32_t num_clusters = get_num_cluster();
-
if (num_clusters == 6U) {
ccn_init(&plat_six_cluster_ccn_desc);
} else {
diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
index 8ab1430..75a3af2 100644
--- a/plat/nxp/soc-lx2160a/soc.mk
+++ b/plat/nxp/soc-lx2160a/soc.mk
@@ -99,7 +99,8 @@
PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\
-I${BOARD_PATH}\
-I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
- -I${PLAT_SOC_PATH}/include
+ -I${PLAT_SOC_PATH}/include\
+ -I${PLAT_COMMON_PATH}/soc_errata
ifeq (${SECURE_BOOT},yes)
include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
@@ -138,7 +139,7 @@
include ${PLAT_DRIVERS_PATH}/drivers.mk
# Adding SoC specific files
-include ${PLAT_SOC_PATH}/erratas_soc.mk
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
PLAT_INCLUDES += ${NV_STORAGE_INCLUDES}\
${WARM_RST_INCLUDES}
diff --git a/plat/qti/common/inc/qti_cpu.h b/plat/qti/common/inc/qti_cpu.h
index 3eda02b..3316f7b 100644
--- a/plat/qti/common/inc/qti_cpu.h
+++ b/plat/qti/common/inc/qti_cpu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,4 +13,10 @@
/* KRYO-4xx Silver MIDR */
#define QTI_KRYO4_SILVER_MIDR 0x517F805D
+/* KRYO-6xx Gold MIDR */
+#define QTI_KRYO6_GOLD_MIDR 0x412FD410
+
+/* KRYO-6xx Silver MIDR */
+#define QTI_KRYO6_SILVER_MIDR 0x412FD050
+
#endif /* QTI_CPU_H */
diff --git a/plat/qti/common/src/aarch64/qti_kryo6_gold.S b/plat/qti/common/src/aarch64/qti_kryo6_gold.S
new file mode 100644
index 0000000..db1a304
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_kryo6_gold.S
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+
+#include <plat_macros.S>
+#include <qti_cpu.h>
+
+ .p2align 3
+
+/* -------------------------------------------------
+ * The CPU Ops reset function for Kryo-3 Gold
+ * -------------------------------------------------
+ */
+func qti_kryo6_gold_reset_func
+#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
+ adr x0, wa_cve_2017_5715_bpiall_vbar
+ msr vbar_el3, x0
+ isb
+#endif
+
+ mov x19, x30
+
+ bl qtiseclib_kryo6_gold_reset_asm
+
+ ret x19
+
+endfunc qti_kryo6_gold_reset_func
+
+/* ----------------------------------------------------
+ * The CPU Ops core power down function for Kryo-3 Gold
+ * ----------------------------------------------------
+ */
+func qti_kryo6_gold_core_pwr_dwn
+ ret
+endfunc qti_kryo6_gold_core_pwr_dwn
+
+/* -------------------------------------------------------
+ * The CPU Ops cluster power down function for Kryo-3 Gold
+ * -------------------------------------------------------
+ */
+func qti_kryo6_gold_cluster_pwr_dwn
+ ret
+endfunc qti_kryo6_gold_cluster_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Kryo4 Gold. Must follow AAPCS.
+ */
+func qti_kryo6_gold_errata_report
+ /* TODO : Need to add support. Required only for debug bl31 image.*/
+ ret
+endfunc qti_kryo6_gold_errata_report
+#endif
+
+/* ---------------------------------------------
+ * This function provides kryo4_gold specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ASCII and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.qti_kryo4_gold_regs, "aS"
+qti_kryo6_gold_regs: /* The ASCII list of register names to be reported */
+ .asciz ""
+
+func qti_kryo6_gold_cpu_reg_dump
+ adr x6, qti_kryo6_gold_regs
+ ret
+endfunc qti_kryo6_gold_cpu_reg_dump
+
+declare_cpu_ops qti_kryo6_gold, QTI_KRYO6_GOLD_MIDR, \
+ qti_kryo6_gold_reset_func, \
+ qti_kryo6_gold_core_pwr_dwn, \
+ qti_kryo6_gold_cluster_pwr_dwn
diff --git a/plat/qti/common/src/aarch64/qti_kryo6_silver.S b/plat/qti/common/src/aarch64/qti_kryo6_silver.S
new file mode 100644
index 0000000..2d189f2
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_kryo6_silver.S
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+
+#include <plat_macros.S>
+#include <qti_cpu.h>
+
+ .p2align 3
+
+/* -------------------------------------------------
+ * The CPU Ops reset function for Kryo-3 Silver
+ * -------------------------------------------------
+ */
+func qti_kryo6_silver_reset_func
+ mov x19, x30
+
+ bl qtiseclib_kryo6_silver_reset_asm
+
+ ret x19
+
+endfunc qti_kryo6_silver_reset_func
+
+/* ------------------------------------------------------
+ * The CPU Ops core power down function for Kryo-3 Silver
+ * ------------------------------------------------------
+ */
+func qti_kryo6_silver_core_pwr_dwn
+ ret
+endfunc qti_kryo6_silver_core_pwr_dwn
+
+/* ---------------------------------------------------------
+ * The CPU Ops cluster power down function for Kryo-3 Silver
+ * ---------------------------------------------------------
+ */
+func qti_kryo6_silver_cluster_pwr_dwn
+ ret
+endfunc qti_kryo6_silver_cluster_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Kryo4 Silver. Must follow AAPCS.
+ */
+func qti_kryo6_silver_errata_report
+ /* TODO : Need to add support. Required only for debug bl31 image.*/
+ ret
+endfunc qti_kryo6_silver_errata_report
+#endif
+
+
+/* ---------------------------------------------
+ * This function provides kryo4_silver specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ASCII and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.qti_kryo4_silver_regs, "aS"
+qti_kryo6_silver_regs: /* The ASCII list of register names to be reported */
+ .asciz ""
+
+func qti_kryo6_silver_cpu_reg_dump
+ adr x6, qti_kryo6_silver_regs
+ ret
+endfunc qti_kryo6_silver_cpu_reg_dump
+
+
+declare_cpu_ops qti_kryo6_silver, QTI_KRYO6_SILVER_MIDR, \
+ qti_kryo6_silver_reset_func, \
+ qti_kryo6_silver_core_pwr_dwn, \
+ qti_kryo6_silver_cluster_pwr_dwn
diff --git a/plat/qti/common/src/qti_gic_v3.c b/plat/qti/common/src/qti_gic_v3.c
index a5e0ae7..f00267a 100644
--- a/plat/qti/common/src/qti_gic_v3.c
+++ b/plat/qti/common/src/qti_gic_v3.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -72,6 +72,16 @@
INTR_PROP_DESC(QTISECLIB_INT_ID_MMSS_NOC_ERROR,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
+#ifdef QTISECLIB_INT_ID_LPASS_AGNOC_ERROR
+ INTR_PROP_DESC(QTISECLIB_INT_ID_LPASS_AGNOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_NSP_NOC_ERROR
+ INTR_PROP_DESC(QTISECLIB_INT_ID_NSP_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+#endif
};
const gicv3_driver_data_t qti_gic_data = {
diff --git a/plat/qti/common/src/qti_syscall.c b/plat/qti/common/src/qti_syscall.c
index a7601b6..d8e5be9 100644
--- a/plat/qti/common/src/qti_syscall.c
+++ b/plat/qti/common/src/qti_syscall.c
@@ -21,6 +21,7 @@
#include <qti_plat.h>
#include <qti_secure_io_cfg.h>
#include <qtiseclib_interface.h>
+
/*
* SIP service - SMC function IDs for SiP Service queries
*
@@ -29,7 +30,7 @@
#define QTI_SIP_SVC_UID_ID U(0x0200ff01)
/* 0x8200ff02 is reserved*/
#define QTI_SIP_SVC_VERSION_ID U(0x0200ff03)
-
+#define QTI_SIP_SVC_AVAILABLE_ID U(0x02000601)
/*
* Syscall's to allow Non Secure world accessing peripheral/IO memory
* those are secure/proteced BUT not required to be secure.
@@ -83,6 +84,22 @@
return false;
}
+static bool qti_check_syscall_availability(u_register_t smc_fid)
+{
+ switch (smc_fid) {
+ case QTI_SIP_SVC_CALL_COUNT_ID:
+ case QTI_SIP_SVC_UID_ID:
+ case QTI_SIP_SVC_VERSION_ID:
+ case QTI_SIP_SVC_AVAILABLE_ID:
+ case QTI_SIP_SVC_SECURE_IO_READ_ID:
+ case QTI_SIP_SVC_SECURE_IO_WRITE_ID:
+ case QTI_SIP_SVC_MEM_ASSIGN_ID:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool qti_mem_assign_validate_param(memprot_info_t *mem_info,
u_register_t u_num_mappings,
uint32_t *source_vm_list,
@@ -315,6 +332,18 @@
QTI_SIP_SVC_VERSION_MINOR);
break;
}
+ case QTI_SIP_SVC_AVAILABLE_ID:
+ {
+ if (x1 != 1) {
+ SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
+ }
+ if (qti_check_syscall_availability(x2) == true) {
+ SMC_RET2(handle, QTI_SIP_SUCCESS, 1);
+ } else {
+ SMC_RET2(handle, QTI_SIP_SUCCESS, 0);
+ }
+ break;
+ }
case QTI_SIP_SVC_SECURE_IO_READ_ID:
{
if ((x1 == QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID) &&
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
index 315bd6b..babed1b 100644
--- a/plat/qti/qtiseclib/inc/qtiseclib_interface.h
+++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -50,6 +50,14 @@
void qtiseclib_kryo4_gold_reset_asm(void);
/*
+ * Execute CPU (Kryo46 gold) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo6_gold_reset_asm(void);
+
+/*
* Execute CPU (Kryo4 silver) specific reset handler / system initialization.
* This takes care of executing required CPU errata's.
*
@@ -58,6 +66,14 @@
void qtiseclib_kryo4_silver_reset_asm(void);
/*
+ * Execute CPU (Kryo6 silver) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo6_silver_reset_asm(void);
+
+/*
* C Api's
*/
void qtiseclib_bl31_platform_setup(void);
diff --git a/plat/qti/qtiseclib/inc/sc7280/qtiseclib_defs_plat.h b/plat/qti/qtiseclib/inc/sc7280/qtiseclib_defs_plat.h
new file mode 100644
index 0000000..b3d309f
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/sc7280/qtiseclib_defs_plat.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __QTISECLIB_DEFS_PLAT_H__
+#define __QTISECLIB_DEFS_PLAT_H__
+
+#define QTISECLIB_PLAT_CLUSTER_COUNT 1
+#define QTISECLIB_PLAT_CORE_COUNT 8
+
+#define BL31_BASE 0xC0000000
+#define BL31_SIZE 0x00100000
+
+/*----------------------------------------------------------------------------*/
+/* AOP CMD DB address space for mapping */
+/*----------------------------------------------------------------------------*/
+#define QTI_AOP_CMD_DB_BASE 0x80860000
+#define QTI_AOP_CMD_DB_SIZE 0x00020000
+
+/* Chipset specific secure interrupt number/ID defs. */
+#define QTISECLIB_INT_ID_SEC_WDOG_BARK (0x204)
+#define QTISECLIB_INT_ID_NON_SEC_WDOG_BITE (0x21)
+
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC (0xE6)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC (0xE7)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC (0xE8)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC (0xE9)
+
+#define QTISECLIB_INT_ID_XPU_SEC (0xE3)
+#define QTISECLIB_INT_ID_XPU_NON_SEC (0xE4)
+
+//NOC INterrupt
+#define QTISECLIB_INT_ID_A1_NOC_ERROR (0xC9)
+#define QTISECLIB_INT_ID_A2_NOC_ERROR (0xEA)
+#define QTISECLIB_INT_ID_CONFIG_NOC_ERROR (0xE2)
+#define QTISECLIB_INT_ID_DC_NOC_ERROR (0x122)
+#define QTISECLIB_INT_ID_MEM_NOC_ERROR (0x6C)
+#define QTISECLIB_INT_ID_SYSTEM_NOC_ERROR (0xC8)
+#define QTISECLIB_INT_ID_MMSS_NOC_ERROR (0xBA)
+#define QTISECLIB_INT_ID_LPASS_AGNOC_ERROR (0x143)
+#define QTISECLIB_INT_ID_NSP_NOC_ERROR (0x1CE)
+
+#endif /* __QTISECLIB_DEFS_PLAT_H__ */
diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
index bb552c6..c4cd259 100644
--- a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
+++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
@@ -132,6 +132,10 @@
void *ctx;
ctx = cm_get_context(NON_SECURE);
+ if (ctx) {
+ /* nothing to be done w/o ns context */
+ return;
+ }
qti_ns_ctx->spsr_el3 =
read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3);
diff --git a/plat/qti/sc7280/inc/platform_def.h b/plat/qti/sc7280/inc/platform_def.h
new file mode 100644
index 0000000..660cb33
--- /dev/null
+++ b/plat/qti/sc7280/inc/platform_def.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+/* Enable the dynamic translation tables library. */
+#define PLAT_XLAT_TABLES_DYNAMIC 1
+
+#include <common_def.h>
+
+#include <qti_board_def.h>
+#include <qtiseclib_defs_plat.h>
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/*
+ * MPIDR_PRIMARY_CPU
+ * You just need to have the correct core_affinity_val i.e. [7:0]
+ * and cluster_affinity_val i.e. [15:8]
+ * the other bits will be ignored
+ */
+/*----------------------------------------------------------------------------*/
+#define MPIDR_PRIMARY_CPU 0x0000
+/*----------------------------------------------------------------------------*/
+
+#define QTI_PWR_LVL0 MPIDR_AFFLVL0
+#define QTI_PWR_LVL1 MPIDR_AFFLVL1
+#define QTI_PWR_LVL2 MPIDR_AFFLVL2
+#define QTI_PWR_LVL3 MPIDR_AFFLVL3
+
+/*
+ * Macros for local power states encoded by State-ID field
+ * within the power-state parameter.
+ */
+/* Local power state for power domains in Run state. */
+#define QTI_LOCAL_STATE_RUN 0
+/*
+ * Local power state for clock-gating. Valid only for CPU and not cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_STB 1
+/*
+ * Local power state for retention. Valid for CPU and cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_RET 2
+/*
+ * Local power state for OFF/power down. Valid for CPU, cluster, RSC and PDC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_OFF 3
+/*
+ * Local power state for DEEPOFF/power rail down. Valid for CPU, cluster and RSC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_DEEPOFF 4
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE QTI_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE QTI_LOCAL_STATE_DEEPOFF
+
+/******************************************************************************
+ * Required platform porting definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+/*
+ * Platform specific page table and MMU setup constants.
+ */
+#define MAX_MMAP_REGIONS (PLAT_QTI_MMAP_ENTRIES)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 36)
+
+#define ARM_CACHE_WRITEBACK_SHIFT 6
+
+/*
+ * 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_GRANULE (1 << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*
+ * One cache line needed for bakery locks on ARM platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+/*----------------------------------------------------------------------------*/
+/* PSCI power domain topology definitions */
+/*----------------------------------------------------------------------------*/
+/* One domain each to represent RSC and PDC level */
+#define PLAT_PDC_COUNT 1
+#define PLAT_RSC_COUNT 1
+
+/* There is one top-level FCM cluster */
+#define PLAT_CLUSTER_COUNT 1
+
+/* No. of cores in the FCM cluster */
+#define PLAT_CLUSTER0_CORE_COUNT 8
+
+#define PLATFORM_CORE_COUNT (PLAT_CLUSTER0_CORE_COUNT)
+
+#define PLAT_NUM_PWR_DOMAINS (PLAT_PDC_COUNT +\
+ PLAT_RSC_COUNT +\
+ PLAT_CLUSTER_COUNT +\
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL 3
+
+/*****************************************************************************/
+/* Memory mapped Generic timer interfaces */
+/*****************************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* GIC-600 constants */
+/*----------------------------------------------------------------------------*/
+#define BASE_GICD_BASE 0x17A00000
+#define BASE_GICR_BASE 0x17A60000
+#define BASE_GICC_BASE 0x0
+#define BASE_GICH_BASE 0x0
+#define BASE_GICV_BASE 0x0
+
+#define QTI_GICD_BASE BASE_GICD_BASE
+#define QTI_GICR_BASE BASE_GICR_BASE
+#define QTI_GICC_BASE BASE_GICC_BASE
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* UART related constants. */
+/*----------------------------------------------------------------------------*/
+/* BASE ADDRESS OF DIFFERENT REGISTER SPACES IN HW */
+#define GENI4_CFG 0x0
+#define GENI4_IMAGE_REGS 0x100
+#define GENI4_DATA 0x600
+
+/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */
+#define GENI_STATUS_REG (GENI4_CFG + 0x00000040)
+#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK (0x1)
+#define UART_TX_TRANS_LEN_REG (GENI4_IMAGE_REGS + 0x00000170)
+/* MASTER/TX ENGINE REGISTERS */
+#define GENI_M_CMD0_REG (GENI4_DATA + 0x00000000)
+/* FIFO, STATUS REGISTERS AND MASKS */
+#define GENI_TX_FIFOn_REG (GENI4_DATA + 0x00000100)
+
+#define GENI_M_CMD_TX (0x08000000)
+
+/*----------------------------------------------------------------------------*/
+/* Device address space for mapping. Excluding starting 4K */
+/*----------------------------------------------------------------------------*/
+#define QTI_DEVICE_BASE 0x1000
+#define QTI_DEVICE_SIZE (0x80000000 - QTI_DEVICE_BASE)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at DDR as per memory map. BL31_BASE is calculated using the
+ * current BL31 debug size plus a little space for growth.
+ */
+#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
+
+/*----------------------------------------------------------------------------*/
+/* AOSS registers */
+/*----------------------------------------------------------------------------*/
+#define QTI_PS_HOLD_REG 0x0C264000
+/*----------------------------------------------------------------------------*/
+/* AOP CMD DB address space for mapping */
+/*----------------------------------------------------------------------------*/
+#define QTI_AOP_CMD_DB_BASE 0x80860000
+#define QTI_AOP_CMD_DB_SIZE 0x00020000
+/*----------------------------------------------------------------------------*/
+/* SOC hw version register */
+/*----------------------------------------------------------------------------*/
+#define QTI_SOC_VERSION U(0x7280)
+#define QTI_SOC_VERSION_MASK U(0xFFFF)
+#define QTI_SOC_REVISION_REG 0x1FC8000
+#define QTI_SOC_REVISION_MASK U(0xFFFF)
+/*----------------------------------------------------------------------------*/
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/sc7280/inc/qti_rng_io.h b/plat/qti/sc7280/inc/qti_rng_io.h
new file mode 100644
index 0000000..0f41fd6
--- /dev/null
+++ b/plat/qti/sc7280/inc/qti_rng_io.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_RNG_IO_H
+#define QTI_RNG_IO_H
+
+#define SEC_PRNG_STATUS 0x10D1004
+#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1
+#define SEC_PRNG_DATA_OUT 0x10D1000
+
+
+#endif /* QTI_RNG_IO_H */
+
diff --git a/plat/qti/sc7280/inc/qti_secure_io_cfg.h b/plat/qti/sc7280/inc/qti_secure_io_cfg.h
new file mode 100644
index 0000000..058c5b5
--- /dev/null
+++ b/plat/qti/sc7280/inc/qti_secure_io_cfg.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_SECURE_IO_CFG_H
+#define QTI_SECURE_IO_CFG_H
+
+#include <stdint.h>
+
+/*
+ * List of peripheral/IO memory areas that are protected from
+ * non-secure world but not required to be secure.
+ */
+
+#define APPS_SMMU_TBU_PWR_STATUS 0x15002204
+#define APPS_SMMU_CUSTOM_CFG 0x15002300
+#define APPS_SMMU_STATS_SYNC_INV_TBU_ACK 0x150025DC
+#define APPS_SMMU_SAFE_SEC_CFG 0x15002648
+#define APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR 0x15002670
+
+static const uintptr_t qti_secure_io_allowed_regs[] = {
+ APPS_SMMU_TBU_PWR_STATUS,
+ APPS_SMMU_CUSTOM_CFG,
+ APPS_SMMU_STATS_SYNC_INV_TBU_ACK,
+ APPS_SMMU_SAFE_SEC_CFG,
+ APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
+};
+
+#endif /* QTI_SECURE_IO_CFG_H */
diff --git a/plat/qti/sc7280/platform.mk b/plat/qti/sc7280/platform.mk
new file mode 100644
index 0000000..6e26781
--- /dev/null
+++ b/plat/qti/sc7280/platform.mk
@@ -0,0 +1,119 @@
+#
+# Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Make for SC7280 QTI platform.
+
+QTI_PLAT_PATH := plat/qti
+CHIPSET := ${PLAT}
+
+# Turn On Separate code & data.
+SEPARATE_CODE_AND_RODATA := 1
+USE_COHERENT_MEM := 1
+WARMBOOT_ENABLE_DCACHE_EARLY := 1
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT := 0
+
+# Enable PSCI v1.0 extended state ID format
+PSCI_EXTENDED_STATE_ID := 1
+ARM_RECOM_STATE_ID_ENC := 1
+
+COLD_BOOT_SINGLE_CPU := 1
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+RESET_TO_BL31 := 0
+
+MULTI_CONSOLE_API := 1
+
+QTI_SDI_BUILD := 0
+$(eval $(call assert_boolean,QTI_SDI_BUILD))
+$(eval $(call add_define,QTI_SDI_BUILD))
+
+#disable CTX_INCLUDE_AARCH32_REGS to support sc7280 gold cores
+override CTX_INCLUDE_AARCH32_REGS := 0
+WORKAROUND_CVE_2017_5715 := 0
+DYNAMIC_WORKAROUND_CVE_2018_3639 := 1
+# Enable stack protector.
+ENABLE_STACK_PROTECTOR := strong
+
+
+QTI_EXTERNAL_INCLUDES := -I${QTI_PLAT_PATH}/${CHIPSET}/inc \
+ -I${QTI_PLAT_PATH}/common/inc \
+ -I${QTI_PLAT_PATH}/common/inc/$(ARCH) \
+ -I${QTI_PLAT_PATH}/qtiseclib/inc \
+ -I${QTI_PLAT_PATH}/qtiseclib/inc/${CHIPSET} \
+
+QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo6_silver.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo6_gold.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \
+ $(QTI_PLAT_PATH)/common/src/pm8998.c \
+ $(QTI_PLAT_PATH)/common/src/qti_stack_protector.c \
+ $(QTI_PLAT_PATH)/common/src/qti_common.c \
+ $(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \
+ $(QTI_PLAT_PATH)/common/src/qti_gic_v3.c \
+ $(QTI_PLAT_PATH)/common/src/qti_interrupt_svc.c \
+ $(QTI_PLAT_PATH)/common/src/qti_syscall.c \
+ $(QTI_PLAT_PATH)/common/src/qti_topology.c \
+ $(QTI_PLAT_PATH)/common/src/qti_pm.c \
+ $(QTI_PLAT_PATH)/common/src/qti_rng.c \
+ $(QTI_PLAT_PATH)/common/src/spmi_arb.c \
+ $(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c \
+
+
+PLAT_INCLUDES := -Iinclude/plat/common/ \
+
+PLAT_INCLUDES += ${QTI_EXTERNAL_INCLUDES}
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \
+ plat/common/aarch64/crash_console_helpers.S \
+ common/desc_image_load.c \
+ lib/bl_aux_params/bl_aux_params.c \
+
+include lib/coreboot/coreboot.mk
+
+#PSCI Sources.
+PSCI_SOURCES := plat/common/plat_psci_common.c \
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+#Timer sources
+TIMER_SOURCES := drivers/delay_timer/generic_delay_timer.c \
+ drivers/delay_timer/delay_timer.c \
+
+#GIC sources.
+GIC_SOURCES := plat/common/plat_gicv3.c \
+ ${GICV3_SOURCES} \
+
+BL31_SOURCES += ${QTI_BL31_SOURCES} \
+ ${PSCI_SOURCES} \
+ ${GIC_SOURCES} \
+ ${TIMER_SOURCES} \
+
+LIB_QTI_PATH := ${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET}
+
+
+# Override this on the command line to point to the qtiseclib library which
+# will be available in coreboot.org
+QTISECLIB_PATH ?=
+
+ifeq ($(QTISECLIB_PATH),)
+# if No lib then use stub implementation for qtiseclib interface
+$(warning QTISECLIB_PATH is not provided while building, using stub implementation. \
+ Please refer docs/plat/qti.rst for more details \
+ THIS FIRMWARE WILL NOT BOOT!)
+BL31_SOURCES += plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
+else
+# use library provided by QTISECLIB_PATH
+LDFLAGS += -L $(dir $(QTISECLIB_PATH))
+LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(QTISECLIB_PATH)))
+endif
+
diff --git a/plat/renesas/common/aarch64/plat_helpers.S b/plat/renesas/common/aarch64/plat_helpers.S
index ec21f25..21c3bed 100644
--- a/plat/renesas/common/aarch64/plat_helpers.S
+++ b/plat/renesas/common/aarch64/plat_helpers.S
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -284,7 +284,11 @@
str x3, [sp, #-16]!
str x4, [sp, #-16]!
str x5, [sp, #-16]!
+ str x6, [sp, #-16]!
+ str x7, [sp, #-16]!
bl console_rcar_putc
+ ldr x7, [sp], #16
+ ldr x6, [sp], #16
ldr x5, [sp], #16
ldr x4, [sp], #16
ldr x3, [sp], #16
diff --git a/plat/renesas/common/bl2_cpg_init.c b/plat/renesas/common/bl2_cpg_init.c
index ba8e53b..a545f71 100644
--- a/plat/renesas/common/bl2_cpg_init.c
+++ b/plat/renesas/common/bl2_cpg_init.c
@@ -40,7 +40,6 @@
#endif
#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_D3)
-static void bl2_realtime_cpg_init_d3(void);
static void bl2_system_cpg_init_d3(void);
#endif
@@ -140,7 +139,7 @@
cpg_write(SMSTPCR1, 0xFFFFFFFFU);
cpg_write(SMSTPCR2, 0x040E2FDCU);
cpg_write(SMSTPCR3, 0xFFFFFBDFU);
- cpg_write(SMSTPCR4, 0x80000004U);
+ cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
cpg_write(SMSTPCR5, 0xC3FFFFFFU);
cpg_write(SMSTPCR6, 0xFFFFFFFFU);
cpg_write(SMSTPCR7, 0xFFFFFFFFU);
@@ -176,7 +175,7 @@
cpg_write(SMSTPCR1, 0xFFFFFFFFU);
cpg_write(SMSTPCR2, 0x040E2FDCU);
cpg_write(SMSTPCR3, 0xFFFFFBDFU);
- cpg_write(SMSTPCR4, 0x80000004U);
+ cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
cpg_write(SMSTPCR5, 0xC3FFFFFFU);
cpg_write(SMSTPCR6, 0xFFFFFFFFU);
cpg_write(SMSTPCR7, 0xFFFFFFFFU);
@@ -212,7 +211,7 @@
cpg_write(SMSTPCR1, 0xFFFFFFFFU);
cpg_write(SMSTPCR2, 0x040E2FDCU);
cpg_write(SMSTPCR3, 0xFFFFFBDFU);
- cpg_write(SMSTPCR4, 0x80000004U);
+ cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
cpg_write(SMSTPCR5, 0xC3FFFFFFU);
cpg_write(SMSTPCR6, 0xFFFFFFFFU);
cpg_write(SMSTPCR7, 0xFFFFFFFFU);
@@ -246,7 +245,7 @@
cpg_write(SMSTPCR1, 0xFFFFFFFFU);
cpg_write(SMSTPCR2, 0x340E2FDCU);
cpg_write(SMSTPCR3, 0xFFFFFBDFU);
- cpg_write(SMSTPCR4, 0x80000004U);
+ cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
cpg_write(SMSTPCR5, 0xC3FFFFFFU);
cpg_write(SMSTPCR6, 0xFFFFFFFFU);
cpg_write(SMSTPCR7, 0xFFFFFFFFU);
@@ -280,7 +279,7 @@
cpg_write(SMSTPCR1, 0xFFFFFFFFU);
cpg_write(SMSTPCR2, 0x000E2FDCU);
cpg_write(SMSTPCR3, 0xFFFFFBDFU);
- cpg_write(SMSTPCR4, 0x80000004U);
+ cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
cpg_write(SMSTPCR5, 0xC3FFFFFFU);
cpg_write(SMSTPCR6, 0xFFFFFFFFU);
cpg_write(SMSTPCR7, 0xFFFFFFFFU);
@@ -292,23 +291,6 @@
#endif
#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_D3)
-static void bl2_realtime_cpg_init_d3(void)
-{
- /* Realtime Module Stop Control Registers */
- cpg_write(RMSTPCR0, 0x00010000U);
- cpg_write(RMSTPCR1, 0xFFFFFFFFU);
- cpg_write(RMSTPCR2, 0x00060FDCU);
- cpg_write(RMSTPCR3, 0xFFFFFFDFU);
- cpg_write(RMSTPCR4, 0x80000184U);
- cpg_write(RMSTPCR5, 0x83FFFFFFU);
- cpg_write(RMSTPCR6, 0xFFFFFFFFU);
- cpg_write(RMSTPCR7, 0xFFFFFFFFU);
- cpg_write(RMSTPCR8, 0x00F1FFF7U);
- cpg_write(RMSTPCR9, 0xF3F5E016U);
- cpg_write(RMSTPCR10, 0xFFFEFFE0U);
- cpg_write(RMSTPCR11, 0x000000B7U);
-}
-
static void bl2_system_cpg_init_d3(void)
{
/* System Module Stop Control Registers */
@@ -316,7 +298,7 @@
cpg_write(SMSTPCR1, 0xFFFFFFFFU);
cpg_write(SMSTPCR2, 0x00060FDCU);
cpg_write(SMSTPCR3, 0xFFFFFBDFU);
- cpg_write(SMSTPCR4, 0x00000084U);
+ cpg_write(SMSTPCR4, 0x00000080U | (mmio_read_32(SMSTPCR4) & 0x4));
cpg_write(SMSTPCR5, 0x83FFFFFFU);
cpg_write(SMSTPCR6, 0xFFFFFFFFU);
cpg_write(SMSTPCR7, 0xFFFFFFFFU);
@@ -356,7 +338,7 @@
bl2_realtime_cpg_init_e3();
break;
case PRR_PRODUCT_D3:
- bl2_realtime_cpg_init_d3();
+ /* no need */
break;
default:
panic();
@@ -373,7 +355,7 @@
#elif RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2E
bl2_realtime_cpg_init_e3();
#elif RCAR_LSI == RCAR_D3
- bl2_realtime_cpg_init_d3();
+ /* no need */
#else
#error "Don't have CPG initialize routine(unknown)."
#endif
diff --git a/plat/renesas/common/bl2_secure_setting.c b/plat/renesas/common/bl2_secure_setting.c
index 095d1f6..2f8b001 100644
--- a/plat/renesas/common/bl2_secure_setting.c
+++ b/plat/renesas/common/bl2_secure_setting.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -49,10 +49,10 @@
/*
* Bit13: SCEG PKA (secure APB) slave ports
* 0: registers accessed from secure resource only
- * 1: Reserved[R-Car E3]
+ * 1: Reserved[R-Car E3/D3]
* Bit12: SCEG PKA (public APB) slave ports
* 0: registers accessed from secure resource only
- * 1: Reserved[R-Car E3]
+ * 1: Reserved[R-Car E3/D3]
* Bit10: SCEG Secure Core slave ports
* 0: registers accessed from secure resource only
*/
@@ -152,14 +152,14 @@
* Security group 1 attribute setting for slave ports 6
* Bit13: SCEG PKA (secure APB) slave ports
* SecurityGroup3
- * Reserved[R-Car E3]
+ * Reserved[R-Car E3/D3]
* Bit12: SCEG PKA (public APB) slave ports
* SecurityGroup3
- * Reserved[R-Car E3]
+ * Reserved[R-Car E3/D3]
* Bit10: SCEG Secure Core slave ports
* SecurityGroup3
*/
-#if RCAR_LSI == RCAR_E3
+#if RCAR_LSI == RCAR_E3 || RCAR_LSI == RCAR_D3
{ SEC_GRP0COND6, 0x00000400U },
{ SEC_GRP1COND6, 0x00000400U },
#else /* RCAR_LSI == RCAR_E3 */
diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk
index fafce98..0d88d65 100644
--- a/plat/renesas/common/common.mk
+++ b/plat/renesas/common/common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved.
+# Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -65,10 +65,12 @@
ERRATA_A53_835769 := 1
ERRATA_A53_843419 := 1
ERRATA_A53_855873 := 1
+ERRATA_A53_1530924 := 1
# Enable workarounds for selected Cortex-A57 erratas.
ERRATA_A57_859972 := 1
ERRATA_A57_813419 := 1
+ERRATA_A57_1319537 := 1
PLAT_INCLUDES := -Iplat/renesas/common/include/registers \
-Iplat/renesas/common/include \
@@ -77,9 +79,8 @@
PLAT_BL_COMMON_SOURCES := drivers/renesas/common/iic_dvfs/iic_dvfs.c \
plat/renesas/common/rcar_common.c
-RCAR_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
+include drivers/arm/gic/v2/gicv2.mk
+RCAR_GIC_SOURCES := ${GICV2_SOURCES} \
plat/common/plat_gicv2.c
BL2_SOURCES += ${RCAR_GIC_SOURCES} \
diff --git a/plat/renesas/common/include/platform_def.h b/plat/renesas/common/include/platform_def.h
index 72c7688..1213a3c 100644
--- a/plat/renesas/common/include/platform_def.h
+++ b/plat/renesas/common/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -144,7 +144,7 @@
******************************************************************************/
#ifndef SPD_NONE
#define BL32_BASE U(0x44100000)
-#define BL32_LIMIT (BL32_BASE + U(0x100000))
+#define BL32_LIMIT (BL32_BASE + U(0x200000))
#endif
/*******************************************************************************
diff --git a/plat/renesas/common/include/rcar_def.h b/plat/renesas/common/include/rcar_def.h
index 93a65f1..2cd26ed 100644
--- a/plat/renesas/common/include/rcar_def.h
+++ b/plat/renesas/common/include/rcar_def.h
@@ -148,9 +148,13 @@
#define RCAR_PWRER5 U(0xE61801D4) /* shutoff/resume error */
#define RCAR_SYSCISR U(0xE6180004) /* Interrupt status */
#define RCAR_SYSCISCR U(0xE6180008) /* Interrupt stat clear */
+#define RCAR_SYSCEXTMASK U(0xE61802F8) /* External Request Mask */
+ /* H3/H3-N, M3 v3.0, M3-N, E3 */
/* Product register */
#define RCAR_PRR U(0xFFF00044)
#define RCAR_M3_CUT_VER11 U(0x00000010) /* M3 Ver.1.1/Ver.1.2 */
+#define RCAR_D3_CUT_VER10 U(0x00000000) /* D3 Ver.1.0 */
+#define RCAR_D3_CUT_VER11 U(0x00000010) /* D3 Ver.1.1 */
#define RCAR_MAJOR_MASK U(0x000000F0)
#define RCAR_MINOR_MASK U(0x0000000F)
#define PRR_PRODUCT_SHIFT U(8)
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 41b2d11..e07b96f 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -263,9 +263,6 @@
if (product == PRR_PRODUCT_H3 && PRR_PRODUCT_20 > cut)
goto tlb;
- if (product == PRR_PRODUCT_D3)
- goto tlb;
-
/* Disable MFIS write protection */
mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1);
@@ -708,6 +705,7 @@
[4] = 0x600000000ULL,
[6] = 0x700000000ULL,
};
+ uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK;
switch (product) {
case PRR_PRODUCT_H3:
@@ -733,15 +731,21 @@
break;
case PRR_PRODUCT_M3:
+ if (cut < PRR_PRODUCT_30) {
#if (RCAR_GEN3_ULCB == 1)
- /* 2GB(1GBx2 2ch split) */
- dram_config[1] = 0x40000000ULL;
- dram_config[5] = 0x40000000ULL;
+ /* 2GB(1GBx2 2ch split) */
+ dram_config[1] = 0x40000000ULL;
+ dram_config[5] = 0x40000000ULL;
#else
- /* 4GB(2GBx2 2ch split) */
- dram_config[1] = 0x80000000ULL;
- dram_config[5] = 0x80000000ULL;
+ /* 4GB(2GBx2 2ch split) */
+ dram_config[1] = 0x80000000ULL;
+ dram_config[5] = 0x80000000ULL;
#endif
+ } else {
+ /* 8GB(2GBx4 2ch split) */
+ dram_config[1] = 0x100000000ULL;
+ dram_config[5] = 0x100000000ULL;
+ }
break;
case PRR_PRODUCT_M3N:
@@ -897,6 +901,14 @@
str,
(reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET);
}
+ } else if (product == PRR_PRODUCT_D3) {
+ if (RCAR_D3_CUT_VER10 == (reg & PRR_CUT_MASK)) {
+ NOTICE("BL2: PRR is R-Car %s Ver.1.0\n", str);
+ } else if (RCAR_D3_CUT_VER11 == (reg & PRR_CUT_MASK)) {
+ NOTICE("BL2: PRR is R-Car %s Ver.1.1\n", str);
+ } else {
+ NOTICE("BL2: PRR is R-Car %s Ver.X.X\n", str);
+ }
} else {
major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT;
major = major + RCAR_MAJOR_OFFSET;
@@ -904,7 +916,7 @@
NOTICE("BL2: PRR is R-Car %s Ver.%d.%d\n", str, major, minor);
}
- if (product == PRR_PRODUCT_E3) {
+ if (PRR_PRODUCT_E3 == product || PRR_PRODUCT_D3 == product) {
reg = mmio_read_32(RCAR_MODEMR);
sscg = reg & RCAR_SSCG_MASK;
str = sscg == RCAR_SSCG_ENABLE ? sscg_on : sscg_off;
@@ -968,10 +980,6 @@
str = boot_emmc25x1;
break;
case MODEMR_BOOT_DEV_EMMC_50X8:
-#if RCAR_LSI == RCAR_D3
- ERROR("BL2: Failed to Initialize. eMMC is not supported.\n");
- panic();
-#endif
str = boot_emmc50x8;
break;
default:
diff --git a/plat/socionext/synquacer/sq_psci.c b/plat/socionext/synquacer/sq_psci.c
index 0c97fcf..4168df9 100644
--- a/plat/socionext/synquacer/sq_psci.c
+++ b/plat/socionext/synquacer/sq_psci.c
@@ -97,6 +97,14 @@
void sq_pwr_domain_off(const psci_power_state_t *target_state)
{
#if SQ_USE_SCMI_DRIVER
+ /* Prevent interrupts from spuriously waking up this cpu */
+ sq_gic_cpuif_disable();
+
+ /* Cluster is to be turned off, so disable coherency */
+ if (SQ_CLUSTER_PWR_STATE(target_state) == SQ_LOCAL_STATE_OFF) {
+ plat_sq_interconnect_exit_coherency();
+ }
+
sq_scmi_off(target_state);
#else
sq_power_down_common(target_state);
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index e603267..7e76083 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -7,13 +7,12 @@
#include <assert.h>
#include <string.h>
-#include <platform_def.h>
-
#include <arch_helpers.h>
#include <common/debug.h>
+#include <common/desc_image_load.h>
#include <drivers/io/io_block.h>
#include <drivers/io/io_driver.h>
-#include <drivers/io/io_dummy.h>
+#include <drivers/io/io_fip.h>
#include <drivers/io/io_mtd.h>
#include <drivers/io/io_storage.h>
#include <drivers/mmc.h>
@@ -22,34 +21,30 @@
#include <drivers/spi_nand.h>
#include <drivers/spi_nor.h>
#include <drivers/st/io_mmc.h>
-#include <drivers/st/io_stm32image.h>
#include <drivers/st/stm32_fmc2_nand.h>
#include <drivers/st/stm32_qspi.h>
#include <drivers/st/stm32_sdmmc2.h>
+#include <lib/fconf/fconf.h>
#include <lib/mmio.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <platform_def.h>
+#include <stm32mp_fconf_getter.h>
/* IO devices */
-#ifndef AARCH32_SP_OPTEE
-static const io_dev_connector_t *dummy_dev_con;
-static uintptr_t dummy_dev_handle;
-static uintptr_t dummy_dev_spec;
-#endif
+uintptr_t fip_dev_handle;
+uintptr_t storage_dev_handle;
-static uintptr_t image_dev_handle;
-static uintptr_t storage_dev_handle;
+static const io_dev_connector_t *fip_dev_con;
#if STM32MP_SDMMC || STM32MP_EMMC
static struct mmc_device_info mmc_info;
-static io_block_spec_t gpt_block_spec = {
- .offset = 0,
- .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */
-};
static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
-static const io_block_dev_spec_t mmc_block_dev_spec = {
+static io_block_dev_spec_t mmc_block_dev_spec = {
/* It's used as temp buffer in block driver */
.buffer = {
.offset = (size_t)&block_buffer,
@@ -62,30 +57,6 @@
.block_size = MMC_BLOCK_SIZE,
};
-#if STM32MP_EMMC_BOOT
-static io_block_spec_t emmc_boot_ssbl_block_spec = {
- .offset = PLAT_EMMC_BOOT_SSBL_OFFSET,
- .length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */
-};
-
-static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = {
- /* It's used as temp buffer in block driver */
- .buffer = {
- .offset = (size_t)&block_buffer,
- .length = MMC_BLOCK_SIZE,
- },
- .ops = {
- .read = mmc_boot_part_read_blocks,
- .write = NULL,
- },
- .block_size = MMC_BLOCK_SIZE,
-};
-#endif
-
-static struct io_mmc_dev_spec mmc_device_spec = {
- .use_boot_part = false,
-};
-
static const io_dev_connector_t *mmc_dev_con;
#endif /* STM32MP_SDMMC || STM32MP_EMMC */
@@ -103,6 +74,7 @@
.ops = {
.init = nand_raw_init,
.read = nand_read,
+ .seek = nand_seek_bb
},
};
@@ -114,6 +86,7 @@
.ops = {
.init = spi_nand_init,
.read = nand_read,
+ .seek = nand_seek_bb
},
};
#endif
@@ -122,176 +95,21 @@
static const io_dev_connector_t *spi_dev_con;
#endif
-#ifdef AARCH32_SP_OPTEE
-static const struct stm32image_part_info optee_header_partition_spec = {
- .name = OPTEE_HEADER_IMAGE_NAME,
- .binary_type = OPTEE_HEADER_BINARY_TYPE,
+io_block_spec_t image_block_spec = {
+ .offset = 0U,
+ .length = 0U,
};
-static const struct stm32image_part_info optee_core_partition_spec = {
- .name = OPTEE_CORE_IMAGE_NAME,
- .binary_type = OPTEE_CORE_BINARY_TYPE,
-};
-
-static const struct stm32image_part_info optee_paged_partition_spec = {
- .name = OPTEE_PAGED_IMAGE_NAME,
- .binary_type = OPTEE_PAGED_BINARY_TYPE,
-};
-#else
-static const io_block_spec_t bl32_block_spec = {
- .offset = BL32_BASE,
- .length = STM32MP_BL32_SIZE
-};
-#endif
-
-static const struct stm32image_part_info bl33_partition_spec = {
- .name = BL33_IMAGE_NAME,
- .binary_type = BL33_BINARY_TYPE,
-};
-
-enum {
- IMG_IDX_BL33,
-#ifdef AARCH32_SP_OPTEE
- IMG_IDX_OPTEE_HEADER,
- IMG_IDX_OPTEE_CORE,
- IMG_IDX_OPTEE_PAGED,
-#endif
- IMG_IDX_NUM
-};
-
-static struct stm32image_device_info stm32image_dev_info_spec __unused = {
- .lba_size = MMC_BLOCK_SIZE,
- .part_info[IMG_IDX_BL33] = {
- .name = BL33_IMAGE_NAME,
- .binary_type = BL33_BINARY_TYPE,
- },
-#ifdef AARCH32_SP_OPTEE
- .part_info[IMG_IDX_OPTEE_HEADER] = {
- .name = OPTEE_HEADER_IMAGE_NAME,
- .binary_type = OPTEE_HEADER_BINARY_TYPE,
- },
- .part_info[IMG_IDX_OPTEE_CORE] = {
- .name = OPTEE_CORE_IMAGE_NAME,
- .binary_type = OPTEE_CORE_BINARY_TYPE,
- },
- .part_info[IMG_IDX_OPTEE_PAGED] = {
- .name = OPTEE_PAGED_IMAGE_NAME,
- .binary_type = OPTEE_PAGED_BINARY_TYPE,
- },
-#endif
-};
-
-static io_block_spec_t stm32image_block_spec = {
- .offset = 0,
- .length = 0,
-};
-
-static const io_dev_connector_t *stm32image_dev_con __unused;
-
-#ifndef AARCH32_SP_OPTEE
-static int open_dummy(const uintptr_t spec);
-#endif
-static int open_image(const uintptr_t spec);
-static int open_storage(const uintptr_t spec);
-
-struct plat_io_policy {
- uintptr_t *dev_handle;
- uintptr_t image_spec;
- int (*check)(const uintptr_t spec);
-};
-
-static const struct plat_io_policy policies[] = {
-#ifdef AARCH32_SP_OPTEE
- [BL32_IMAGE_ID] = {
- .dev_handle = &image_dev_handle,
- .image_spec = (uintptr_t)&optee_header_partition_spec,
- .check = open_image
- },
- [BL32_EXTRA1_IMAGE_ID] = {
- .dev_handle = &image_dev_handle,
- .image_spec = (uintptr_t)&optee_core_partition_spec,
- .check = open_image
- },
- [BL32_EXTRA2_IMAGE_ID] = {
- .dev_handle = &image_dev_handle,
- .image_spec = (uintptr_t)&optee_paged_partition_spec,
- .check = open_image
- },
-#else
- [BL32_IMAGE_ID] = {
- .dev_handle = &dummy_dev_handle,
- .image_spec = (uintptr_t)&bl32_block_spec,
- .check = open_dummy
- },
-#endif
- [BL33_IMAGE_ID] = {
- .dev_handle = &image_dev_handle,
- .image_spec = (uintptr_t)&bl33_partition_spec,
- .check = open_image
- },
-#if STM32MP_SDMMC || STM32MP_EMMC
- [GPT_IMAGE_ID] = {
- .dev_handle = &storage_dev_handle,
- .image_spec = (uintptr_t)&gpt_block_spec,
- .check = open_storage
- },
-#endif
- [STM32_IMAGE_ID] = {
- .dev_handle = &storage_dev_handle,
- .image_spec = (uintptr_t)&stm32image_block_spec,
- .check = open_storage
- }
-};
-
-#ifndef AARCH32_SP_OPTEE
-static int open_dummy(const uintptr_t spec)
+int open_fip(const uintptr_t spec)
{
- return io_dev_init(dummy_dev_handle, 0);
-}
-#endif
-
-static int open_image(const uintptr_t spec)
-{
- return io_dev_init(image_dev_handle, 0);
+ return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
}
-static int open_storage(const uintptr_t spec)
+int open_storage(const uintptr_t spec)
{
return io_dev_init(storage_dev_handle, 0);
}
-#if STM32MP_EMMC_BOOT
-static uint32_t get_boot_part_ssbl_header(void)
-{
- uint32_t magic = 0;
- int io_result;
- size_t bytes_read;
-
- io_result = register_io_dev_block(&mmc_dev_con);
- if (io_result != 0) {
- panic();
- }
-
- io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_boot_part_spec,
- &storage_dev_handle);
- assert(io_result == 0);
-
- io_result = io_open(storage_dev_handle, (uintptr_t) &emmc_boot_ssbl_block_spec,
- &image_dev_handle);
- assert(io_result == 0);
-
- io_result = io_read(image_dev_handle, (uintptr_t) &magic, sizeof(magic),
- &bytes_read);
- assert(io_result == 0);
- assert(bytes_read == sizeof(magic));
-
- io_result = io_dev_close(storage_dev_handle);
- assert(io_result == 0);
-
- return magic;
-}
-#endif
-
static void print_boot_device(boot_api_context_t *boot_context)
{
switch (boot_context->boot_interface_selected) {
@@ -311,7 +129,8 @@
INFO("Using SPI NAND\n");
break;
default:
- ERROR("Boot interface not found\n");
+ ERROR("Boot interface %u not found\n",
+ boot_context->boot_interface_selected);
panic();
break;
}
@@ -321,29 +140,12 @@
}
}
-static void stm32image_io_setup(void)
-{
- int io_result __unused;
-
- io_result = register_io_dev_stm32image(&stm32image_dev_con);
- assert(io_result == 0);
-
- io_result = io_dev_open(stm32image_dev_con,
- (uintptr_t)&stm32image_dev_info_spec,
- &image_dev_handle);
- assert(io_result == 0);
-}
-
#if STM32MP_SDMMC || STM32MP_EMMC
static void boot_mmc(enum mmc_device_type mmc_dev_type,
uint16_t boot_interface_instance)
{
int io_result __unused;
- uint8_t idx;
- struct stm32image_part_info *part;
struct stm32_sdmmc2_params params;
- const partition_entry_t *entry __unused;
- uint32_t magic __unused;
zeromem(¶ms, sizeof(struct stm32_sdmmc2_params));
@@ -375,26 +177,6 @@
panic();
}
- stm32image_dev_info_spec.device_size =
- stm32_sdmmc2_mmc_get_device_size();
-
-#if STM32MP_EMMC_BOOT
- magic = get_boot_part_ssbl_header();
-
- if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) {
- VERBOSE("%s, header found, jump to emmc load\n", __func__);
- idx = IMG_IDX_BL33;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET;
- part->bkp_offset = 0U;
- mmc_device_spec.use_boot_part = true;
-
- goto emmc_boot;
- } else {
- WARN("%s: Can't find STM32 header on a boot partition\n", __func__);
- }
-#endif
-
/* Open MMC as a block device to read GPT table */
io_result = register_io_dev_block(&mmc_dev_con);
if (io_result != 0) {
@@ -404,37 +186,6 @@
io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
&storage_dev_handle);
assert(io_result == 0);
-
- partition_init(GPT_IMAGE_ID);
-
- io_result = io_dev_close(storage_dev_handle);
- assert(io_result == 0);
-
- for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
- part = &stm32image_dev_info_spec.part_info[idx];
- entry = get_partition_entry(part->name);
- if (entry == NULL) {
- ERROR("Partition %s not found\n", part->name);
- panic();
- }
-
- part->part_offset = entry->start;
- part->bkp_offset = 0U;
- }
-
-#if STM32MP_EMMC_BOOT
-emmc_boot:
-#endif
- /*
- * Re-open MMC with io_mmc, for better perfs compared to
- * io_block.
- */
- io_result = register_io_dev_mmc(&mmc_dev_con);
- assert(io_result == 0);
-
- io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_device_spec,
- &storage_dev_handle);
- assert(io_result == 0);
}
#endif /* STM32MP_SDMMC || STM32MP_EMMC */
@@ -442,8 +193,6 @@
static void boot_spi_nor(boot_api_context_t *boot_context)
{
int io_result __unused;
- uint8_t idx;
- struct stm32image_part_info *part;
io_result = stm32_qspi_init();
assert(io_result == 0);
@@ -456,30 +205,6 @@
(uintptr_t)&spi_nor_dev_spec,
&storage_dev_handle);
assert(io_result == 0);
-
- stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size;
-
- idx = IMG_IDX_BL33;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NOR_BL33_OFFSET;
- part->bkp_offset = 0U;
-
-#ifdef AARCH32_SP_OPTEE
- idx = IMG_IDX_OPTEE_HEADER;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NOR_TEEH_OFFSET;
- part->bkp_offset = 0U;
-
- idx = IMG_IDX_OPTEE_PAGED;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NOR_TEED_OFFSET;
- part->bkp_offset = 0U;
-
- idx = IMG_IDX_OPTEE_CORE;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NOR_TEEX_OFFSET;
- part->bkp_offset = 0U;
-#endif
}
#endif /* STM32MP_SPI_NOR */
@@ -487,8 +212,6 @@
static void boot_fmc2_nand(boot_api_context_t *boot_context)
{
int io_result __unused;
- uint8_t idx;
- struct stm32image_part_info *part;
io_result = stm32_fmc2_init();
assert(io_result == 0);
@@ -501,30 +224,6 @@
io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
&storage_dev_handle);
assert(io_result == 0);
-
- stm32image_dev_info_spec.device_size = nand_dev_spec.device_size;
-
- idx = IMG_IDX_BL33;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NAND_BL33_OFFSET;
- part->bkp_offset = nand_dev_spec.erase_size;
-
-#ifdef AARCH32_SP_OPTEE
- idx = IMG_IDX_OPTEE_HEADER;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NAND_TEEH_OFFSET;
- part->bkp_offset = nand_dev_spec.erase_size;
-
- idx = IMG_IDX_OPTEE_PAGED;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NAND_TEED_OFFSET;
- part->bkp_offset = nand_dev_spec.erase_size;
-
- idx = IMG_IDX_OPTEE_CORE;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NAND_TEEX_OFFSET;
- part->bkp_offset = nand_dev_spec.erase_size;
-#endif
}
#endif /* STM32MP_RAW_NAND */
@@ -532,8 +231,6 @@
static void boot_spi_nand(boot_api_context_t *boot_context)
{
int io_result __unused;
- uint8_t idx;
- struct stm32image_part_info *part;
io_result = stm32_qspi_init();
assert(io_result == 0);
@@ -546,31 +243,6 @@
(uintptr_t)&spi_nand_dev_spec,
&storage_dev_handle);
assert(io_result == 0);
-
- stm32image_dev_info_spec.device_size =
- spi_nand_dev_spec.device_size;
-
- idx = IMG_IDX_BL33;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NAND_BL33_OFFSET;
- part->bkp_offset = spi_nand_dev_spec.erase_size;
-
-#ifdef AARCH32_SP_OPTEE
- idx = IMG_IDX_OPTEE_HEADER;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NAND_TEEH_OFFSET;
- part->bkp_offset = spi_nand_dev_spec.erase_size;
-
- idx = IMG_IDX_OPTEE_PAGED;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NAND_TEED_OFFSET;
- part->bkp_offset = spi_nand_dev_spec.erase_size;
-
- idx = IMG_IDX_OPTEE_CORE;
- part = &stm32image_dev_info_spec.part_info[idx];
- part->part_offset = STM32MP_NAND_TEEX_OFFSET;
- part->bkp_offset = spi_nand_dev_spec.erase_size;
-#endif
}
#endif /* STM32MP_SPI_NAND */
@@ -584,53 +256,45 @@
if ((boot_context->boot_partition_used_toboot == 1U) ||
(boot_context->boot_partition_used_toboot == 2U)) {
- INFO("Boot used partition fsbl%d\n",
+ INFO("Boot used partition fsbl%u\n",
boot_context->boot_partition_used_toboot);
}
-#ifndef AARCH32_SP_OPTEE
- io_result = register_io_dev_dummy(&dummy_dev_con);
+ io_result = register_io_dev_fip(&fip_dev_con);
assert(io_result == 0);
- io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
- &dummy_dev_handle);
- assert(io_result == 0);
-#endif
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+ &fip_dev_handle);
switch (boot_context->boot_interface_selected) {
#if STM32MP_SDMMC
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
dmbsy();
boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
- stm32image_io_setup();
break;
#endif
#if STM32MP_EMMC
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
dmbsy();
boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
- stm32image_io_setup();
break;
#endif
#if STM32MP_SPI_NOR
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
dmbsy();
boot_spi_nor(boot_context);
- stm32image_io_setup();
break;
#endif
#if STM32MP_RAW_NAND
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
dmbsy();
boot_fmc2_nand(boot_context);
- stm32image_io_setup();
break;
#endif
#if STM32MP_SPI_NAND
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
dmbsy();
boot_spi_nand(boot_context);
- stm32image_io_setup();
break;
#endif
@@ -642,6 +306,65 @@
}
}
+int bl2_plat_handle_pre_image_load(unsigned int image_id)
+{
+ static bool gpt_init_done __unused;
+ uint16_t boot_itf = stm32mp_get_boot_itf_selected();
+
+ switch (boot_itf) {
+#if STM32MP_SDMMC || STM32MP_EMMC
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+ if (!gpt_init_done) {
+ const partition_entry_t *entry;
+
+ partition_init(GPT_IMAGE_ID);
+ entry = get_partition_entry(FIP_IMAGE_NAME);
+ if (entry == NULL) {
+ ERROR("Could NOT find the %s partition!\n",
+ FIP_IMAGE_NAME);
+ return -ENOENT;
+ }
+
+ image_block_spec.offset = entry->start;
+ image_block_spec.length = entry->length;
+
+ gpt_init_done = true;
+ } else {
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+ mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base;
+ mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size;
+ }
+
+ break;
+#endif
+
+#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
+#if STM32MP_RAW_NAND
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+#endif
+#if STM32MP_SPI_NAND
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
+#endif
+ image_block_spec.offset = STM32MP_NAND_FIP_OFFSET;
+ break;
+#endif
+
+#if STM32MP_SPI_NOR
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+ image_block_spec.offset = STM32MP_NOR_FIP_OFFSET;
+ break;
+#endif
+
+ default:
+ ERROR("FIP Not found\n");
+ panic();
+ }
+
+ return 0;
+}
+
/*
* Return an IO device handle and specification which can be used to access
* an image. Use this to enforce platform load policy.
@@ -652,9 +375,7 @@
int rc;
const struct plat_io_policy *policy;
- assert(image_id < ARRAY_SIZE(policies));
-
- policy = &policies[image_id];
+ policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id);
rc = policy->check(policy->image_spec);
if (rc == 0) {
*image_spec = policy->image_spec;
diff --git a/plat/st/common/bl2_stm32_io_storage.c b/plat/st/common/bl2_stm32_io_storage.c
new file mode 100644
index 0000000..2d68a50
--- /dev/null
+++ b/plat/st/common/bl2_stm32_io_storage.c
@@ -0,0 +1,665 @@
+/*
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/io/io_block.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_dummy.h>
+#include <drivers/io/io_mtd.h>
+#include <drivers/io/io_storage.h>
+#include <drivers/mmc.h>
+#include <drivers/partition/partition.h>
+#include <drivers/raw_nand.h>
+#include <drivers/spi_nand.h>
+#include <drivers/spi_nor.h>
+#include <drivers/st/io_mmc.h>
+#include <drivers/st/io_stm32image.h>
+#include <drivers/st/stm32_fmc2_nand.h>
+#include <drivers/st/stm32_qspi.h>
+#include <drivers/st/stm32_sdmmc2.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/* IO devices */
+#ifndef AARCH32_SP_OPTEE
+static const io_dev_connector_t *dummy_dev_con;
+static uintptr_t dummy_dev_handle;
+static uintptr_t dummy_dev_spec;
+#endif
+
+static uintptr_t image_dev_handle;
+static uintptr_t storage_dev_handle;
+
+#if STM32MP_SDMMC || STM32MP_EMMC
+static struct mmc_device_info mmc_info;
+static io_block_spec_t gpt_block_spec = {
+ .offset = 0U,
+ .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */
+};
+
+static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
+
+static const io_block_dev_spec_t mmc_block_dev_spec = {
+ /* It's used as temp buffer in block driver */
+ .buffer = {
+ .offset = (size_t)&block_buffer,
+ .length = MMC_BLOCK_SIZE,
+ },
+ .ops = {
+ .read = mmc_read_blocks,
+ .write = NULL,
+ },
+ .block_size = MMC_BLOCK_SIZE,
+};
+
+#if STM32MP_EMMC_BOOT
+static io_block_spec_t emmc_boot_ssbl_block_spec = {
+ .offset = PLAT_EMMC_BOOT_SSBL_OFFSET,
+ .length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */
+};
+
+static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = {
+ /* It's used as temp buffer in block driver */
+ .buffer = {
+ .offset = (size_t)&block_buffer,
+ .length = MMC_BLOCK_SIZE,
+ },
+ .ops = {
+ .read = mmc_boot_part_read_blocks,
+ .write = NULL,
+ },
+ .block_size = MMC_BLOCK_SIZE,
+};
+#endif
+
+static struct io_mmc_dev_spec mmc_device_spec = {
+ .use_boot_part = false,
+};
+
+static const io_dev_connector_t *mmc_dev_con;
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
+#if STM32MP_SPI_NOR
+static io_mtd_dev_spec_t spi_nor_dev_spec = {
+ .ops = {
+ .init = spi_nor_init,
+ .read = spi_nor_read,
+ },
+};
+#endif
+
+#if STM32MP_RAW_NAND
+static io_mtd_dev_spec_t nand_dev_spec = {
+ .ops = {
+ .init = nand_raw_init,
+ .read = nand_read,
+ },
+};
+
+static const io_dev_connector_t *nand_dev_con;
+#endif
+
+#if STM32MP_SPI_NAND
+static io_mtd_dev_spec_t spi_nand_dev_spec = {
+ .ops = {
+ .init = spi_nand_init,
+ .read = nand_read,
+ },
+};
+#endif
+
+#if STM32MP_SPI_NAND || STM32MP_SPI_NOR
+static const io_dev_connector_t *spi_dev_con;
+#endif
+
+#ifdef AARCH32_SP_OPTEE
+static const struct stm32image_part_info optee_header_partition_spec = {
+ .name = OPTEE_HEADER_IMAGE_NAME,
+ .binary_type = OPTEE_HEADER_BINARY_TYPE,
+};
+
+static const struct stm32image_part_info optee_core_partition_spec = {
+ .name = OPTEE_CORE_IMAGE_NAME,
+ .binary_type = OPTEE_CORE_BINARY_TYPE,
+};
+
+static const struct stm32image_part_info optee_paged_partition_spec = {
+ .name = OPTEE_PAGED_IMAGE_NAME,
+ .binary_type = OPTEE_PAGED_BINARY_TYPE,
+};
+#else
+static const io_block_spec_t bl32_block_spec = {
+ .offset = BL32_BASE,
+ .length = STM32MP_BL32_SIZE
+};
+#endif
+
+static const struct stm32image_part_info bl33_partition_spec = {
+ .name = BL33_IMAGE_NAME,
+ .binary_type = BL33_BINARY_TYPE,
+};
+
+enum {
+ IMG_IDX_BL33,
+#ifdef AARCH32_SP_OPTEE
+ IMG_IDX_OPTEE_HEADER,
+ IMG_IDX_OPTEE_CORE,
+ IMG_IDX_OPTEE_PAGED,
+#endif
+ IMG_IDX_NUM
+};
+
+static struct stm32image_device_info stm32image_dev_info_spec __unused = {
+ .lba_size = MMC_BLOCK_SIZE,
+ .part_info[IMG_IDX_BL33] = {
+ .name = BL33_IMAGE_NAME,
+ .binary_type = BL33_BINARY_TYPE,
+ },
+#ifdef AARCH32_SP_OPTEE
+ .part_info[IMG_IDX_OPTEE_HEADER] = {
+ .name = OPTEE_HEADER_IMAGE_NAME,
+ .binary_type = OPTEE_HEADER_BINARY_TYPE,
+ },
+ .part_info[IMG_IDX_OPTEE_CORE] = {
+ .name = OPTEE_CORE_IMAGE_NAME,
+ .binary_type = OPTEE_CORE_BINARY_TYPE,
+ },
+ .part_info[IMG_IDX_OPTEE_PAGED] = {
+ .name = OPTEE_PAGED_IMAGE_NAME,
+ .binary_type = OPTEE_PAGED_BINARY_TYPE,
+ },
+#endif
+};
+
+static io_block_spec_t stm32image_block_spec = {
+ .offset = 0U,
+ .length = 0U,
+};
+
+static const io_dev_connector_t *stm32image_dev_con __unused;
+
+#ifndef AARCH32_SP_OPTEE
+static int open_dummy(const uintptr_t spec);
+#endif
+static int open_image(const uintptr_t spec);
+static int open_storage(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+#ifdef AARCH32_SP_OPTEE
+ [BL32_IMAGE_ID] = {
+ .dev_handle = &image_dev_handle,
+ .image_spec = (uintptr_t)&optee_header_partition_spec,
+ .check = open_image
+ },
+ [BL32_EXTRA1_IMAGE_ID] = {
+ .dev_handle = &image_dev_handle,
+ .image_spec = (uintptr_t)&optee_core_partition_spec,
+ .check = open_image
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ .dev_handle = &image_dev_handle,
+ .image_spec = (uintptr_t)&optee_paged_partition_spec,
+ .check = open_image
+ },
+#else
+ [BL32_IMAGE_ID] = {
+ .dev_handle = &dummy_dev_handle,
+ .image_spec = (uintptr_t)&bl32_block_spec,
+ .check = open_dummy
+ },
+#endif
+ [BL33_IMAGE_ID] = {
+ .dev_handle = &image_dev_handle,
+ .image_spec = (uintptr_t)&bl33_partition_spec,
+ .check = open_image
+ },
+#if STM32MP_SDMMC || STM32MP_EMMC
+ [GPT_IMAGE_ID] = {
+ .dev_handle = &storage_dev_handle,
+ .image_spec = (uintptr_t)&gpt_block_spec,
+ .check = open_storage
+ },
+#endif
+ [STM32_IMAGE_ID] = {
+ .dev_handle = &storage_dev_handle,
+ .image_spec = (uintptr_t)&stm32image_block_spec,
+ .check = open_storage
+ }
+};
+
+#ifndef AARCH32_SP_OPTEE
+static int open_dummy(const uintptr_t spec)
+{
+ return io_dev_init(dummy_dev_handle, 0);
+}
+#endif
+
+static int open_image(const uintptr_t spec)
+{
+ return io_dev_init(image_dev_handle, 0);
+}
+
+static int open_storage(const uintptr_t spec)
+{
+ return io_dev_init(storage_dev_handle, 0);
+}
+
+#if STM32MP_EMMC_BOOT
+static uint32_t get_boot_part_ssbl_header(void)
+{
+ uint32_t magic = 0U;
+ int io_result;
+ size_t bytes_read;
+
+ io_result = register_io_dev_block(&mmc_dev_con);
+ if (io_result != 0) {
+ panic();
+ }
+
+ io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_boot_part_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ io_result = io_open(storage_dev_handle, (uintptr_t)&emmc_boot_ssbl_block_spec,
+ &image_dev_handle);
+ assert(io_result == 0);
+
+ io_result = io_read(image_dev_handle, (uintptr_t)&magic, sizeof(magic),
+ &bytes_read);
+ assert(io_result == 0);
+ assert(bytes_read == sizeof(magic));
+
+ io_result = io_dev_close(storage_dev_handle);
+ assert(io_result == 0);
+
+ return magic;
+}
+#endif
+
+static void print_boot_device(boot_api_context_t *boot_context)
+{
+ switch (boot_context->boot_interface_selected) {
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+ INFO("Using SDMMC\n");
+ break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+ INFO("Using EMMC\n");
+ break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+ INFO("Using QSPI NOR\n");
+ break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+ INFO("Using FMC NAND\n");
+ break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
+ INFO("Using SPI NAND\n");
+ break;
+ default:
+ ERROR("Boot interface not found\n");
+ panic();
+ break;
+ }
+
+ if (boot_context->boot_interface_instance != 0U) {
+ INFO(" Instance %d\n", boot_context->boot_interface_instance);
+ }
+}
+
+static void stm32image_io_setup(void)
+{
+ int io_result __unused;
+
+ io_result = register_io_dev_stm32image(&stm32image_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(stm32image_dev_con,
+ (uintptr_t)&stm32image_dev_info_spec,
+ &image_dev_handle);
+ assert(io_result == 0);
+}
+
+#if STM32MP_SDMMC || STM32MP_EMMC
+static void boot_mmc(enum mmc_device_type mmc_dev_type,
+ uint16_t boot_interface_instance)
+{
+ int io_result __unused;
+ uint8_t idx;
+ struct stm32image_part_info *part;
+ struct stm32_sdmmc2_params params;
+ const partition_entry_t *entry __unused;
+ uint32_t magic __unused;
+
+ zeromem(¶ms, sizeof(struct stm32_sdmmc2_params));
+
+ mmc_info.mmc_dev_type = mmc_dev_type;
+
+ switch (boot_interface_instance) {
+ case 1:
+ params.reg_base = STM32MP_SDMMC1_BASE;
+ break;
+ case 2:
+ params.reg_base = STM32MP_SDMMC2_BASE;
+ break;
+ case 3:
+ params.reg_base = STM32MP_SDMMC3_BASE;
+ break;
+ default:
+ WARN("SDMMC instance not found, using default\n");
+ if (mmc_dev_type == MMC_IS_SD) {
+ params.reg_base = STM32MP_SDMMC1_BASE;
+ } else {
+ params.reg_base = STM32MP_SDMMC2_BASE;
+ }
+ break;
+ }
+
+ params.device_info = &mmc_info;
+ if (stm32_sdmmc2_mmc_init(¶ms) != 0) {
+ ERROR("SDMMC%u init failed\n", boot_interface_instance);
+ panic();
+ }
+
+ stm32image_dev_info_spec.device_size =
+ stm32_sdmmc2_mmc_get_device_size();
+
+#if STM32MP_EMMC_BOOT
+ magic = get_boot_part_ssbl_header();
+
+ if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) {
+ VERBOSE("%s, header found, jump to emmc load\n", __func__);
+ idx = IMG_IDX_BL33;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET;
+ part->bkp_offset = 0U;
+ mmc_device_spec.use_boot_part = true;
+
+ goto emmc_boot;
+ } else {
+ WARN("%s: Can't find STM32 header on a boot partition\n", __func__);
+ }
+#endif
+
+ /* Open MMC as a block device to read GPT table */
+ io_result = register_io_dev_block(&mmc_dev_con);
+ if (io_result != 0) {
+ panic();
+ }
+
+ io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ partition_init(GPT_IMAGE_ID);
+
+ io_result = io_dev_close(storage_dev_handle);
+ assert(io_result == 0);
+
+ for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
+ part = &stm32image_dev_info_spec.part_info[idx];
+ entry = get_partition_entry(part->name);
+ if (entry == NULL) {
+ ERROR("Partition %s not found\n", part->name);
+ panic();
+ }
+
+ part->part_offset = entry->start;
+ part->bkp_offset = 0U;
+ }
+
+#if STM32MP_EMMC_BOOT
+emmc_boot:
+#endif
+ /*
+ * Re-open MMC with io_mmc, for better perfs compared to
+ * io_block.
+ */
+ io_result = register_io_dev_mmc(&mmc_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_device_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+}
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
+#if STM32MP_SPI_NOR
+static void boot_spi_nor(boot_api_context_t *boot_context)
+{
+ int io_result __unused;
+ uint8_t idx;
+ struct stm32image_part_info *part;
+
+ io_result = stm32_qspi_init();
+ assert(io_result == 0);
+
+ io_result = register_io_dev_mtd(&spi_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to device */
+ io_result = io_dev_open(spi_dev_con,
+ (uintptr_t)&spi_nor_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size;
+
+ idx = IMG_IDX_BL33;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NOR_BL33_OFFSET;
+ part->bkp_offset = 0U;
+
+#ifdef AARCH32_SP_OPTEE
+ idx = IMG_IDX_OPTEE_HEADER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NOR_TEEH_OFFSET;
+ part->bkp_offset = 0U;
+
+ idx = IMG_IDX_OPTEE_PAGED;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NOR_TEED_OFFSET;
+ part->bkp_offset = 0U;
+
+ idx = IMG_IDX_OPTEE_CORE;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NOR_TEEX_OFFSET;
+ part->bkp_offset = 0U;
+#endif
+}
+#endif /* STM32MP_SPI_NOR */
+
+#if STM32MP_RAW_NAND
+static void boot_fmc2_nand(boot_api_context_t *boot_context)
+{
+ int io_result __unused;
+ uint8_t idx;
+ struct stm32image_part_info *part;
+
+ io_result = stm32_fmc2_init();
+ assert(io_result == 0);
+
+ /* Register the IO device on this platform */
+ io_result = register_io_dev_mtd(&nand_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to device */
+ io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ stm32image_dev_info_spec.device_size = nand_dev_spec.device_size;
+
+ idx = IMG_IDX_BL33;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_BL33_OFFSET;
+ part->bkp_offset = nand_dev_spec.erase_size;
+
+#ifdef AARCH32_SP_OPTEE
+ idx = IMG_IDX_OPTEE_HEADER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEEH_OFFSET;
+ part->bkp_offset = nand_dev_spec.erase_size;
+
+ idx = IMG_IDX_OPTEE_PAGED;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEED_OFFSET;
+ part->bkp_offset = nand_dev_spec.erase_size;
+
+ idx = IMG_IDX_OPTEE_CORE;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEEX_OFFSET;
+ part->bkp_offset = nand_dev_spec.erase_size;
+#endif
+}
+#endif /* STM32MP_RAW_NAND */
+
+#if STM32MP_SPI_NAND
+static void boot_spi_nand(boot_api_context_t *boot_context)
+{
+ int io_result __unused;
+ uint8_t idx;
+ struct stm32image_part_info *part;
+
+ io_result = stm32_qspi_init();
+ assert(io_result == 0);
+
+ io_result = register_io_dev_mtd(&spi_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to device */
+ io_result = io_dev_open(spi_dev_con,
+ (uintptr_t)&spi_nand_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ stm32image_dev_info_spec.device_size =
+ spi_nand_dev_spec.device_size;
+
+ idx = IMG_IDX_BL33;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_BL33_OFFSET;
+ part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+#ifdef AARCH32_SP_OPTEE
+ idx = IMG_IDX_OPTEE_HEADER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEEH_OFFSET;
+ part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+ idx = IMG_IDX_OPTEE_PAGED;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEED_OFFSET;
+ part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+ idx = IMG_IDX_OPTEE_CORE;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEEX_OFFSET;
+ part->bkp_offset = spi_nand_dev_spec.erase_size;
+#endif
+}
+#endif /* STM32MP_SPI_NAND */
+
+void stm32mp_io_setup(void)
+{
+ int io_result __unused;
+ boot_api_context_t *boot_context =
+ (boot_api_context_t *)stm32mp_get_boot_ctx_address();
+
+ print_boot_device(boot_context);
+
+ if ((boot_context->boot_partition_used_toboot == 1U) ||
+ (boot_context->boot_partition_used_toboot == 2U)) {
+ INFO("Boot used partition fsbl%u\n",
+ boot_context->boot_partition_used_toboot);
+ }
+
+#ifndef AARCH32_SP_OPTEE
+ io_result = register_io_dev_dummy(&dummy_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
+ &dummy_dev_handle);
+ assert(io_result == 0);
+#endif
+
+ switch (boot_context->boot_interface_selected) {
+#if STM32MP_SDMMC
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+ dmbsy();
+ boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
+ stm32image_io_setup();
+ break;
+#endif
+#if STM32MP_EMMC
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+ dmbsy();
+ boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
+ stm32image_io_setup();
+ break;
+#endif
+#if STM32MP_SPI_NOR
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+ dmbsy();
+ boot_spi_nor(boot_context);
+ stm32image_io_setup();
+ break;
+#endif
+#if STM32MP_RAW_NAND
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+ dmbsy();
+ boot_fmc2_nand(boot_context);
+ stm32image_io_setup();
+ break;
+#endif
+#if STM32MP_SPI_NAND
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
+ dmbsy();
+ boot_spi_nand(boot_context);
+ stm32image_io_setup();
+ break;
+#endif
+
+ default:
+ ERROR("Boot interface %d not supported\n",
+ boot_context->boot_interface_selected);
+ panic();
+ break;
+ }
+}
+
+/*
+ * Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy.
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int rc;
+ const struct plat_io_policy *policy;
+
+ assert(image_id < ARRAY_SIZE(policies));
+
+ policy = &policies[image_id];
+ rc = policy->check(policy->image_spec);
+ if (rc == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ }
+
+ return rc;
+}
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index edced71..8a5fe48 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -95,6 +95,7 @@
/* Initialise the IO layer and register platform IO devices */
void stm32mp_io_setup(void);
+#if STM32MP_USE_STM32IMAGE
/*
* Check that the STM32 header of a .stm32 binary image is valid
* @param header: pointer to the stm32 image header
@@ -102,6 +103,7 @@
* @return: 0 on success, negative value in case of error
*/
int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer);
+#endif /* STM32MP_USE_STM32IMAGE */
/* Functions to map DDR in MMU with non-cacheable attribute, and unmap it */
int stm32mp_map_ddr_non_cacheable(void);
diff --git a/plat/st/common/include/stm32mp_fconf_getter.h b/plat/st/common/include/stm32mp_fconf_getter.h
new file mode 100644
index 0000000..3a8bb11
--- /dev/null
+++ b/plat/st/common/include/stm32mp_fconf_getter.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_FCONF_GETTER
+#define STM32MP_FCONF_GETTER
+
+#include <assert.h>
+
+#include <lib/fconf/fconf.h>
+
+/* IO policies */
+#define stm32mp__io_policies_getter(id) __extension__ ({ \
+ assert((id) < MAX_NUMBER_IDS); \
+ &policies[id]; \
+})
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+extern struct plat_io_policy policies[];
+int fconf_populate_stm32mp_io_policies(uintptr_t config);
+
+#endif /* STM32MP_FCONF_GETTER */
diff --git a/plat/st/common/include/stm32mp_io_storage.h b/plat/st/common/include/stm32mp_io_storage.h
new file mode 100644
index 0000000..989c890
--- /dev/null
+++ b/plat/st/common/include/stm32mp_io_storage.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef STM32MP_IO_STORAGE_H
+#define STM32MP_IO_STORAGE_H
+
+#include <stdint.h>
+
+#include <drivers/io/io_storage.h>
+
+/* IO devices handle */
+extern uintptr_t storage_dev_handle;
+extern uintptr_t fip_dev_handle;
+
+extern io_block_spec_t image_block_spec;
+
+/* Function declarations */
+int open_fip(const uintptr_t spec);
+int open_storage(const uintptr_t spec);
+
+#endif /* STM32MP_IO_STORAGE_H */
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index 5e5958b..17ac145 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -76,6 +76,7 @@
return (read_sctlr() & c_m_bits) == c_m_bits;
}
+#if STM32MP_USE_STM32IMAGE
int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer)
{
uint32_t i;
@@ -109,6 +110,7 @@
return 0;
}
+#endif /* STM32MP_USE_STM32IMAGE */
int stm32mp_map_ddr_non_cacheable(void)
{
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
new file mode 100644
index 0000000..aa8cd54
--- /dev/null
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/io/io_storage.h>
+#include <drivers/mmc.h>
+#include <lib/fconf/fconf.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <platform_def.h>
+#include <stm32mp_fconf_getter.h>
+#include <stm32mp_io_storage.h>
+
+#if STM32MP_SDMMC || STM32MP_EMMC
+static io_block_spec_t gpt_block_spec = {
+ .offset = 0U,
+ .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */
+};
+#endif
+
+/* By default, STM32 platforms load images from the FIP */
+struct plat_io_policy policies[MAX_NUMBER_IDS] = {
+ [FIP_IMAGE_ID] = {
+ &storage_dev_handle,
+ (uintptr_t)&image_block_spec,
+ open_storage
+ },
+#if STM32MP_SDMMC || STM32MP_EMMC
+ [GPT_IMAGE_ID] = {
+ &storage_dev_handle,
+ (uintptr_t)&gpt_block_spec,
+ open_storage
+ },
+#endif
+};
+
+#define FCONF_ST_IO_UUID_NUMBER U(8)
+
+static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER];
+static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids);
+
+struct policies_load_info {
+ unsigned int image_id;
+ const char *name;
+};
+
+/* image id to property name table */
+static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = {
+ {FW_CONFIG_ID, "fw_cfg_uuid"},
+ {BL32_IMAGE_ID, "bl32_uuid"},
+ {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
+ {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"},
+ {BL33_IMAGE_ID, "bl33_uuid"},
+ {HW_CONFIG_ID, "hw_cfg_uuid"},
+ {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
+ {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
+};
+
+int fconf_populate_stm32mp_io_policies(uintptr_t config)
+{
+ int node;
+ unsigned int i;
+
+ /* As libfdt uses void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Assert the node offset point to "st,io-fip-handle" compatible property */
+ const char *compatible_str = "st,io-fip-handle";
+
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ /* Locate the uuid cells and read the value for all the load info uuid */
+ for (i = 0U; i < FCONF_ST_IO_UUID_NUMBER; i++) {
+ union uuid_helper_t uuid_helper;
+ io_uuid_spec_t *uuid_ptr;
+ int err;
+
+ uuid_ptr = pool_alloc(&fconf_stm32mp_uuids_pool);
+ err = fdtw_read_uuid(dtb, node, load_info[i].name, 16,
+ (uint8_t *)&uuid_helper);
+ if (err < 0) {
+ WARN("FCONF: Read cell failed for %s\n", load_info[i].name);
+ return err;
+ }
+
+ VERBOSE("FCONF: stm32mp-io_policies.%s cell found with value = "
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+ load_info[i].name,
+ uuid_helper.uuid_struct.time_low[0], uuid_helper.uuid_struct.time_low[1],
+ uuid_helper.uuid_struct.time_low[2], uuid_helper.uuid_struct.time_low[3],
+ uuid_helper.uuid_struct.time_mid[0], uuid_helper.uuid_struct.time_mid[1],
+ uuid_helper.uuid_struct.time_hi_and_version[0],
+ uuid_helper.uuid_struct.time_hi_and_version[1],
+ uuid_helper.uuid_struct.clock_seq_hi_and_reserved,
+ uuid_helper.uuid_struct.clock_seq_low,
+ uuid_helper.uuid_struct.node[0], uuid_helper.uuid_struct.node[1],
+ uuid_helper.uuid_struct.node[2], uuid_helper.uuid_struct.node[3],
+ uuid_helper.uuid_struct.node[4], uuid_helper.uuid_struct.node[5]);
+
+ uuid_ptr->uuid = uuid_helper.uuid_struct;
+ policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr;
+ policies[load_info[i].image_id].dev_handle = &fip_dev_handle;
+ policies[load_info[i].image_id].check = open_fip;
+ }
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(TB_FW, stm32mp_io, fconf_populate_stm32mp_io_policies);
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index b4c42fc..e87c529 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -5,6 +5,7 @@
*/
#include <assert.h>
+#include <errno.h>
#include <string.h>
#include <platform_def.h>
@@ -15,6 +16,7 @@
#include <common/desc_image_load.h>
#include <drivers/delay_timer.h>
#include <drivers/generic_delay_timer.h>
+#include <drivers/mmc.h>
#include <drivers/st/bsec.h>
#include <drivers/st/stm32_console.h>
#include <drivers/st/stm32_iwdg.h>
@@ -23,6 +25,8 @@
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_pwr.h>
#include <drivers/st/stm32mp1_ram.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/mmio.h>
#include <lib/optee_utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
@@ -151,11 +155,13 @@
panic();
}
+#if STM32MP_USE_STM32IMAGE
#ifdef AARCH32_SP_OPTEE
INFO("BL2 runs OP-TEE setup\n");
#else
INFO("BL2 runs SP_MIN setup\n");
#endif
+#endif /* STM32MP_USE_STM32IMAGE */
}
void bl2_el3_plat_arch_setup(void)
@@ -173,11 +179,19 @@
BL_CODE_END - BL_CODE_BASE,
MT_CODE | MT_SECURE);
+#if STM32MP_USE_STM32IMAGE
#ifdef AARCH32_SP_OPTEE
mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE,
STM32MP_OPTEE_SIZE,
MT_MEMORY | MT_RW | MT_SECURE);
+#else
+ /* Prevent corruption of preloaded BL32 */
+ mmap_add_region(BL32_BASE, BL32_BASE,
+ BL32_LIMIT - BL32_BASE,
+ MT_RO_DATA | MT_SECURE);
#endif
+#endif /* STM32MP_USE_STM32IMAGE */
+
/* Prevent corruption of preloaded Device Tree */
mmap_add_region(DTB_BASE, DTB_BASE,
DTB_LIMIT - DTB_BASE,
@@ -316,10 +330,13 @@
print_reset_reason();
+#if !STM32MP_USE_STM32IMAGE
+ fconf_populate("TB_FW", STM32MP_DTB_BASE);
+#endif /* !STM32MP_USE_STM32IMAGE */
+
stm32mp_io_setup();
}
-#if defined(AARCH32_SP_OPTEE)
/*******************************************************************************
* This function can be used by the platforms to update/use image
* information for given `image_id`.
@@ -329,44 +346,119 @@
int err = 0;
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
bl_mem_params_node_t *bl32_mem_params;
- bl_mem_params_node_t *pager_mem_params;
- bl_mem_params_node_t *paged_mem_params;
+ bl_mem_params_node_t *pager_mem_params __unused;
+ bl_mem_params_node_t *paged_mem_params __unused;
+#if !STM32MP_USE_STM32IMAGE
+ const struct dyn_cfg_dtb_info_t *config_info;
+ bl_mem_params_node_t *tos_fw_mem_params;
+ unsigned int i;
+ unsigned long long ddr_top __unused;
+ const unsigned int image_ids[] = {
+ BL32_IMAGE_ID,
+ BL33_IMAGE_ID,
+ HW_CONFIG_ID,
+ TOS_FW_CONFIG_ID,
+ };
+#endif /* !STM32MP_USE_STM32IMAGE */
assert(bl_mem_params != NULL);
switch (image_id) {
- case BL32_IMAGE_ID:
- bl_mem_params->ep_info.pc =
- bl_mem_params->image_info.image_base;
+#if !STM32MP_USE_STM32IMAGE
+ case FW_CONFIG_ID:
+ /* Set global DTB info for fixed fw_config information */
+ set_config_info(STM32MP_FW_CONFIG_BASE, STM32MP_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID);
+ fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
- pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
- assert(pager_mem_params != NULL);
- pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE;
- pager_mem_params->image_info.image_max_size =
- STM32MP_OPTEE_SIZE;
+ /* Iterate through all the fw config IDs */
+ for (i = 0U; i < ARRAY_SIZE(image_ids); i++) {
+ bl_mem_params = get_bl_mem_params_node(image_ids[i]);
+ assert(bl_mem_params != NULL);
- paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
- assert(paged_mem_params != NULL);
- paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
- stm32mp_get_ddr_ns_size();
- paged_mem_params->image_info.image_max_size =
- STM32MP_DDR_S_SIZE;
+ config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_ids[i]);
+ if (config_info == NULL) {
+ continue;
+ }
- err = parse_optee_header(&bl_mem_params->ep_info,
- &pager_mem_params->image_info,
- &paged_mem_params->image_info);
- if (err) {
- ERROR("OPTEE header parse error.\n");
- panic();
+ bl_mem_params->image_info.image_base = config_info->config_addr;
+ bl_mem_params->image_info.image_max_size = config_info->config_max_size;
+
+ bl_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+
+ switch (image_ids[i]) {
+ case BL32_IMAGE_ID:
+ bl_mem_params->ep_info.pc = config_info->config_addr;
+
+ /* In case of OPTEE, initialize address space with tos_fw addr */
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ pager_mem_params->image_info.image_base = config_info->config_addr;
+ pager_mem_params->image_info.image_max_size =
+ config_info->config_max_size;
+
+ /* Init base and size for pager if exist */
+ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+ paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
+ (dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
+ STM32MP_DDR_SHMEM_SIZE);
+ paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE;
+ break;
+
+ case BL33_IMAGE_ID:
+ bl_mem_params->ep_info.pc = config_info->config_addr;
+ break;
+
+ case HW_CONFIG_ID:
+ case TOS_FW_CONFIG_ID:
+ break;
+
+ default:
+ return -EINVAL;
+ }
}
+ break;
+#endif /* !STM32MP_USE_STM32IMAGE */
- /* Set optee boot info from parsed header data */
- bl_mem_params->ep_info.pc =
- pager_mem_params->image_info.image_base;
- bl_mem_params->ep_info.args.arg0 =
- paged_mem_params->image_info.image_base;
- bl_mem_params->ep_info.args.arg1 = 0; /* Unused */
- bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */
+ case BL32_IMAGE_ID:
+ if (optee_header_is_valid(bl_mem_params->image_info.image_base)) {
+ /* BL32 is OP-TEE header */
+ bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+ assert((pager_mem_params != NULL) && (paged_mem_params != NULL));
+
+#if STM32MP_USE_STM32IMAGE && defined(AARCH32_SP_OPTEE)
+ /* Set OP-TEE extra image load areas at run-time */
+ pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE;
+ pager_mem_params->image_info.image_max_size = STM32MP_OPTEE_SIZE;
+
+ paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
+ dt_get_ddr_size() -
+ STM32MP_DDR_S_SIZE -
+ STM32MP_DDR_SHMEM_SIZE;
+ paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE;
+#endif /* STM32MP_USE_STM32IMAGE && defined(AARCH32_SP_OPTEE) */
+
+ err = parse_optee_header(&bl_mem_params->ep_info,
+ &pager_mem_params->image_info,
+ &paged_mem_params->image_info);
+ if (err) {
+ ERROR("OPTEE header parse error.\n");
+ panic();
+ }
+
+ /* Set optee boot info from parsed header data */
+ bl_mem_params->ep_info.args.arg0 = paged_mem_params->image_info.image_base;
+ bl_mem_params->ep_info.args.arg1 = 0; /* Unused */
+ bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */
+ } else {
+#if !STM32MP_USE_STM32IMAGE
+ bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
+ tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
+ bl_mem_params->image_info.image_max_size +=
+ tos_fw_mem_params->image_info.image_max_size;
+#endif /* !STM32MP_USE_STM32IMAGE */
+ bl_mem_params->ep_info.args.arg0 = 0;
+ }
break;
case BL33_IMAGE_ID:
@@ -380,6 +472,19 @@
break;
}
+#if STM32MP_SDMMC || STM32MP_EMMC
+ /*
+ * Invalidate remaining data read from MMC but not flushed by load_image_flush().
+ * We take the worst case which is 2 MMC blocks.
+ */
+ if ((image_id != FW_CONFIG_ID) &&
+ ((bl_mem_params->image_info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U)) {
+ inv_dcache_range(bl_mem_params->image_info.image_base +
+ bl_mem_params->image_info.image_size,
+ 2U * MMC_BLOCK_SIZE);
+ }
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
return err;
}
@@ -387,4 +492,3 @@
{
stm32mp1_security_setup();
}
-#endif
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 2d7d369..8a065bf 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -25,6 +25,7 @@
#define PLATFORM_STACK_SIZE 0xC00
#endif
+#if STM32MP_USE_STM32IMAGE
#ifdef AARCH32_SP_OPTEE
#define OPTEE_HEADER_IMAGE_NAME "teeh"
#define OPTEE_CORE_IMAGE_NAME "teex"
@@ -37,6 +38,9 @@
/* SSBL = second stage boot loader */
#define BL33_IMAGE_NAME "ssbl"
#define BL33_BINARY_TYPE U(0x0)
+#else /* STM32MP_USE_STM32IMAGE */
+#define FIP_IMAGE_NAME "fip"
+#endif /* STM32MP_USE_STM32IMAGE */
#define STM32MP_PRIMARY_CPU U(0x0)
#define STM32MP_SECONDARY_CPU U(0x1)
@@ -67,7 +71,7 @@
/*******************************************************************************
* BL32 specific defines.
******************************************************************************/
-#ifndef AARCH32_SP_OPTEE
+#if STM32MP_USE_STM32IMAGE || defined(IMAGE_BL32)
#if ENABLE_PIE
#define BL32_BASE 0
#define BL32_LIMIT STM32MP_BL32_SIZE
@@ -76,7 +80,7 @@
#define BL32_LIMIT (STM32MP_BL32_BASE + \
STM32MP_BL32_SIZE)
#endif
-#endif
+#endif /* STM32MP_USE_STM32IMAGE || defined(IMAGE_BL32) */
/*******************************************************************************
* BL33 specific defines.
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index b6cb91e..729d233 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,7 +21,9 @@
void stm32mp1_syscfg_enable_io_compensation(void);
void stm32mp1_syscfg_disable_io_compensation(void);
+#if STM32MP_USE_STM32IMAGE
uint32_t stm32mp_get_ddr_ns_size(void);
+#endif /* STM32MP_USE_STM32IMAGE */
void stm32mp1_init_scmi_server(void);
#endif /* STM32MP1_PRIVATE_H */
diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
index 984c6ba..7963c4a 100644
--- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
@@ -4,12 +4,12 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <platform_def.h>
-
#include <common/bl_common.h>
#include <common/desc_image_load.h>
#include <plat/common/platform.h>
+#include <platform_def.h>
+
/*******************************************************************************
* Following descriptor provides BL image/ep information that gets used
* by BL2 to load the images and also subset of this information is
@@ -19,6 +19,22 @@
* the next executable image id.
******************************************************************************/
static bl_mem_params_node_t bl2_mem_params_descs[] = {
+ /* Fill FW_CONFIG related information if it exists */
+ {
+ .image_id = FW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP),
+
+ .image_info.image_base = STM32MP_FW_CONFIG_BASE,
+ .image_info.image_max_size = STM32MP_FW_CONFIG_MAX_SIZE,
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+
/* Fill BL32 related information */
{
.image_id = BL32_IMAGE_ID,
@@ -27,28 +43,17 @@
VERSION_2, entry_point_info_t,
SECURE | EXECUTABLE | EP_FIRST_EXE),
-#if !defined(AARCH32_SP_OPTEE)
- .ep_info.pc = STM32MP_BL32_BASE,
-#endif
.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
SPSR_E_LITTLE,
DISABLE_ALL_EXCEPTIONS),
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
VERSION_2, image_info_t,
- IMAGE_ATTRIB_PLAT_SETUP),
-#if defined(AARCH32_SP_OPTEE)
- /* optee header is loaded in SYSRAM above BL2 */
- .image_info.image_base = STM32MP_OPTEE_BASE,
- .image_info.image_max_size = STM32MP_OPTEE_SIZE,
-#else
- .image_info.image_base = STM32MP_BL32_BASE,
- .image_info.image_max_size = STM32MP_BL32_SIZE,
-#endif
+ IMAGE_ATTRIB_SKIP_LOADING),
+
.next_handoff_image_id = BL33_IMAGE_ID,
},
-#if defined(AARCH32_SP_OPTEE)
/* Fill BL32 external 1 image related information */
{
.image_id = BL32_EXTRA1_IMAGE_ID,
@@ -77,7 +82,32 @@
.next_handoff_image_id = INVALID_IMAGE_ID,
},
-#endif /* AARCH32_SP_OPTEE */
+
+ /* Fill HW_CONFIG related information if it exists */
+ {
+ .image_id = HW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+
+ /* Fill TOS_FW_CONFIG related information if it exists */
+ {
+ .image_id = TOS_FW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
/* Fill BL33 related information */
{
@@ -87,17 +117,13 @@
VERSION_2, entry_point_info_t,
NON_SECURE | EXECUTABLE),
- .ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET,
.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
SPSR_E_LITTLE,
DISABLE_ALL_EXCEPTIONS),
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
-
- .image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET,
- .image_info.image_max_size = STM32MP_DDR_MAX_SIZE -
- (PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE),
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
.next_handoff_image_id = INVALID_IMAGE_ID,
}
diff --git a/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c
new file mode 100644
index 0000000..4fce55a
--- /dev/null
+++ b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Following descriptor provides BL image/ep information that gets used
+ * by BL2 to load the images and also subset of this information is
+ * passed to next BL image. The image loading sequence is managed by
+ * populating the images in required loading order. The image execution
+ * sequence is managed by populating the `next_handoff_image_id` with
+ * the next executable image id.
+ ******************************************************************************/
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+ /* Fill BL32 related information */
+ {
+ .image_id = BL32_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+
+ /* Updated at runtime if OP-TEE is loaded */
+ .ep_info.pc = STM32MP_BL32_BASE,
+
+ .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+ SPSR_E_LITTLE,
+ DISABLE_ALL_EXCEPTIONS),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP),
+
+ /* Updated at runtime if OP-TEE is loaded */
+ .image_info.image_base = STM32MP_BL32_BASE,
+ .image_info.image_max_size = STM32MP_BL32_SIZE,
+
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+
+#if defined(AARCH32_SP_OPTEE)
+ /* Fill BL32 external 1 image related information */
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+ /* Fill BL32 external 2 image related information */
+ {
+ .image_id = BL32_EXTRA2_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+#endif /* AARCH32_SP_OPTEE */
+
+ /* Fill BL33 related information */
+ {
+ .image_id = BL33_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | EXECUTABLE),
+
+ .ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET,
+ .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+ SPSR_E_LITTLE,
+ DISABLE_ALL_EXCEPTIONS),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0U),
+
+ .image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET,
+ .image_info.image_max_size = STM32MP_DDR_MAX_SIZE -
+ (PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index 6d7af74..36a3a1c 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,12 +23,14 @@
******************************************************************************/
bl_load_info_t *plat_get_bl_image_load_info(void)
{
+#if STM32MP_USE_STM32IMAGE
bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID);
uint32_t ddr_ns_size = stm32mp_get_ddr_ns_size();
/* Max size is non-secure DDR end address minus image_base */
bl33->image_info.image_max_size = STM32MP_DDR_BASE + ddr_ns_size -
bl33->image_info.image_base;
+#endif /* STM32MP_USE_STM32IMAGE */
return get_bl_load_info_from_mem_params_desc();
}
@@ -38,5 +40,9 @@
******************************************************************************/
bl_params_t *plat_get_next_bl_params(void)
{
- return get_next_bl_params_from_mem_params_desc();
+ bl_params_t *bl_params = get_next_bl_params_from_mem_params_desc();
+
+ populate_next_bl_params_config(bl_params);
+
+ return bl_params;
}
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 1693135..1c2c9f0 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -9,7 +9,14 @@
BL2_AT_EL3 := 1
USE_COHERENT_MEM := 0
+# Allow TF-A to concatenate BL2 & BL32 binaries in a single file,
+# share DTB file between BL2 and BL32
+# If it is set to 0, then FIP is used
+STM32MP_USE_STM32IMAGE ?= 0
+
+ifneq ($(STM32MP_USE_STM32IMAGE),1)
ENABLE_PIE := 1
+endif
STM32_TF_VERSION ?= 0
@@ -29,8 +36,10 @@
STM32_BL33_PARTS_NUM := 1
ifeq ($(AARCH32_SP),optee)
STM32_RUNTIME_PARTS_NUM := 3
-else
+else ifeq ($(STM32MP_USE_STM32IMAGE),1)
STM32_RUNTIME_PARTS_NUM := 0
+else
+STM32_RUNTIME_PARTS_NUM := 1
endif
PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + \
$(STM32_BL33_PARTS_NUM) + \
@@ -46,7 +55,22 @@
# Device tree
DTB_FILE_NAME ?= stm32mp157c-ev1.dtb
+ifeq ($(STM32MP_USE_STM32IMAGE),1)
+ifeq ($(AARCH32_SP),optee)
+BL2_DTSI := stm32mp15-bl2.dtsi
+FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
+else
FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME)))
+endif
+else
+BL2_DTSI := stm32mp15-bl2.dtsi
+FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
+ifeq ($(AARCH32_SP),sp_min)
+BL32_DTSI := stm32mp15-bl32.dtsi
+FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME)))
+endif
+endif
+DTC_CPPFLAGS += ${INCLUDES}
DTC_FLAGS += -Wno-unit_address_vs_reg
# Macros and rules to build TF binary
@@ -66,6 +90,33 @@
STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT}
STM32IMAGE_SRC := ${STM32IMAGEPATH}/stm32image.c
+ifneq (${STM32MP_USE_STM32IMAGE},1)
+FIP_DEPS += dtbs
+STM32MP_HW_CONFIG := ${BL33_CFG}
+STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
+STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+ifneq (${AARCH32_SP},none)
+FDT_SOURCES += $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
+endif
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_HW_CONFIG},--hw-config))
+ifeq ($(AARCH32_SP),sp_min)
+STM32MP_TOS_FW_CONFIG := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dtb,$(DTB_FILE_NAME)))
+$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_TOS_FW_CONFIG},--tos-fw-config))
+else
+# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
+# in the FIP if the platform requires.
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
+endif
+endif
+
# Enable flags for C files
$(eval $(call assert_booleans,\
$(sort \
@@ -76,6 +127,7 @@
STM32MP_SPI_NOR \
STM32MP_EMMC_BOOT \
PLAT_XLAT_TABLES_DYNAMIC \
+ STM32MP_USE_STM32IMAGE \
)))
$(eval $(call assert_numerics,\
@@ -95,6 +147,7 @@
PLAT_XLAT_TABLES_DYNAMIC \
STM32_TF_A_COPIES \
PLAT_PARTITION_MAX_ENTRIES \
+ STM32MP_USE_STM32IMAGE \
)))
# Include paths and source files
@@ -104,6 +157,7 @@
include lib/libfdt/libfdt.mk
PLAT_BL_COMMON_SOURCES := common/fdt_wrappers.c \
+ common/uuid.c \
plat/st/common/stm32mp_common.c \
plat/st/stm32mp1/stm32mp1_private.c
@@ -135,17 +189,29 @@
plat/st/stm32mp1/stm32mp1_context.c \
plat/st/stm32mp1/stm32mp1_dbgmcu.c \
plat/st/stm32mp1/stm32mp1_helper.S \
- plat/st/stm32mp1/stm32mp1_security.c \
plat/st/stm32mp1/stm32mp1_syscfg.c
+ifneq (${STM32MP_USE_STM32IMAGE},1)
+BL2_SOURCES += drivers/io/io_fip.c \
+ lib/fconf/fconf.c \
+ lib/fconf/fconf_dyn_cfg_getter.c \
+ plat/st/common/bl2_io_storage.c \
+ plat/st/common/stm32mp_fconf_io.c \
+ plat/st/stm32mp1/plat_bl2_mem_params_desc.c \
+ plat/st/stm32mp1/stm32mp1_fconf_firewall.c
+else
+BL2_SOURCES += drivers/io/io_dummy.c \
+ drivers/st/io/io_stm32image.c \
+ plat/st/common/bl2_stm32_io_storage.c \
+ plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c \
+ plat/st/stm32mp1/stm32mp1_security.c
+endif
+
BL2_SOURCES += drivers/io/io_block.c \
- drivers/io/io_dummy.c \
drivers/io/io_mtd.c \
drivers/io/io_storage.c \
drivers/st/crypto/stm32_hash.c \
- drivers/st/io/io_stm32image.c \
plat/st/common/stm32mp_auth.c \
- plat/st/common/bl2_io_storage.c \
plat/st/stm32mp1/bl2_plat_setup.c
ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
@@ -187,12 +253,9 @@
drivers/st/ddr/stm32mp1_ram.c
BL2_SOURCES += common/desc_image_load.c \
- plat/st/stm32mp1/plat_bl2_mem_params_desc.c \
plat/st/stm32mp1/plat_image_load.c
-ifeq ($(AARCH32_SP),optee)
BL2_SOURCES += lib/optee/optee_utils.c
-endif
# Compilation rules
.PHONY: check_dtc_version stm32image clean_stm32image check_boot_device
@@ -230,12 +293,35 @@
false; \
fi
-
+ifeq ($(STM32MP_USE_STM32IMAGE)-$(AARCH32_SP),1-sp_min)
${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%.dtb plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP}
@echo " AS stm32mp1.S"
${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
-DDTB_BIN_PATH=\"$<\" \
+ -c $(word 2,$^) -o $@
+else
+# Create DTB file for BL2
+${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
+ @echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+ @echo '#include "${BL2_DTSI}"' >> $@
+
+${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts
+
+ifeq ($(AARCH32_SP),sp_min)
+# Create DTB file for BL32
+${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | ${BUILD_PLAT} fdt_dirs
+ @echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+ @echo '#include "${BL32_DTSI}"' >> $@
+
+${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts
+endif
+
+${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb plat/st/stm32mp1/stm32mp1.S bl2
+ @echo " AS stm32mp1.S"
+ ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
+ -DDTB_BIN_PATH=\"$<\" \
-c plat/st/stm32mp1/stm32mp1.S -o $@
+endif
$(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,2))
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 334f914a..1495e02 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -45,6 +45,7 @@
{
switch (id & INT_ID_MASK) {
case STM32MP1_IRQ_TZC400:
+ tzc400_init(STM32MP1_TZC_BASE);
(void)tzc400_it_handler();
panic();
break;
@@ -117,6 +118,11 @@
struct dt_node_info dt_uart_info;
int result;
bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
+#if STM32MP_USE_STM32IMAGE
+ uintptr_t dt_addr = STM32MP_DTB_BASE;
+#else
+ uintptr_t dt_addr = arg1;
+#endif
/* Imprecise aborts can be masked in NonSecure */
write_scr(read_scr() | SCR_AW_BIT);
@@ -140,13 +146,23 @@
while (bl_params != NULL) {
if (bl_params->image_id == BL33_IMAGE_ID) {
bl33_image_ep_info = *bl_params->ep_info;
+ /*
+ * Check if hw_configuration is given to BL32 and
+ * share it to BL33.
+ */
+ if (arg2 != 0U) {
+ bl33_image_ep_info.args.arg0 = 0U;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = arg2;
+ }
+
break;
}
bl_params = bl_params->next_params_info;
}
- if (dt_open_and_check(STM32MP_DTB_BASE) < 0) {
+ if (dt_open_and_check(dt_addr) < 0) {
panic();
}
@@ -185,9 +201,6 @@
******************************************************************************/
void sp_min_platform_setup(void)
{
- /* Initialize tzc400 after DDR initialization */
- stm32mp1_security_setup();
-
generic_delay_timer_init();
stm32mp1_gic_init();
diff --git a/plat/st/stm32mp1/stm32mp1.S b/plat/st/stm32mp1/stm32mp1.S
index 7255fe5..85caa0a 100644
--- a/plat/st/stm32mp1/stm32mp1.S
+++ b/plat/st/stm32mp1/stm32mp1.S
@@ -1,13 +1,15 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#if STM32MP_USE_STM32IMAGE
#ifdef BL32_BIN_PATH
.section .bl32_image
.incbin BL32_BIN_PATH
#endif
+#endif /* STM32MP_USE_STM32IMAGE */
.section .bl2_image
.incbin BL2_BIN_PATH
diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S
index b347bad..945de99 100644
--- a/plat/st/stm32mp1/stm32mp1.ld.S
+++ b/plat/st/stm32mp1/stm32mp1.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -43,7 +43,11 @@
* The strongest and only alignment contraint is MMU 4K page.
* Indeed as images below will be removed, 4K pages will be re-used.
*/
+#if STM32MP_USE_STM32IMAGE
. = ( STM32MP_DTB_BASE - STM32MP_BINARY_BASE );
+#else
+ . = ( STM32MP_BL2_DTB_BASE - STM32MP_BINARY_BASE );
+#endif /* STM32MP_USE_STM32IMAGE */
__DTB_IMAGE_START__ = .;
*(.dtb_image*)
__DTB_IMAGE_END__ = .;
@@ -58,7 +62,7 @@
*(.bl2_image*)
__BL2_IMAGE_END__ = .;
-#ifndef AARCH32_SP_OPTEE
+#if STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE)
/*
* bl32 will be settled by bl2.
* The strongest and only alignment constraint is 8 words to simplify
@@ -68,7 +72,7 @@
__BL32_IMAGE_START__ = .;
*(.bl32_image*)
__BL32_IMAGE_END__ = .;
-#endif
+#endif /* STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE) */
__DATA_END__ = .;
} >RAM
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 155d63d..469c2d9 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -28,6 +28,12 @@
#include <stm32mp1_shared_resources.h>
#endif
+#if !STM32MP_USE_STM32IMAGE
+#include "stm32mp1_fip_def.h"
+#else /* STM32MP_USE_STM32IMAGE */
+#include "stm32mp1_stm32image_def.h"
+#endif /* STM32MP_USE_STM32IMAGE */
+
/*******************************************************************************
* CHIP ID
******************************************************************************/
@@ -81,13 +87,6 @@
/* DDR configuration */
#define STM32MP_DDR_BASE U(0xC0000000)
#define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */
-#ifdef AARCH32_SP_OPTEE
-#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
-#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
-#else
-#define STM32MP_DDR_S_SIZE U(0)
-#define STM32MP_DDR_SHMEM_SIZE U(0)
-#endif
/* DDR power initializations */
#ifndef __ASSEMBLER__
@@ -111,26 +110,6 @@
(STM32MP_PARAM_LOAD_SIZE + \
STM32MP_HEADER_SIZE))
-#ifdef AARCH32_SP_OPTEE
-#define STM32MP_BL32_SIZE U(0)
-
-#define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE
-
-#define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \
- STM32MP_OPTEE_BASE)
-#else
-#define STM32MP_BL32_SIZE U(0x00012000) /* 72 KB for BL32 */
-#endif
-
-#define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \
- STM32MP_SEC_SYSRAM_SIZE - \
- STM32MP_BL32_SIZE)
-
-#define STM32MP_BL2_SIZE U(0x0001A000) /* 100 KB for BL2 */
-
-#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \
- STM32MP_BL2_SIZE)
-
/* BL2 and BL32/sp_min require 4 tables */
#define MAX_XLAT_TABLES U(4) /* 16 KB for mapping */
@@ -141,39 +120,14 @@
#if defined(IMAGE_BL2)
#define MAX_MMAP_REGIONS 11
#endif
-#if defined(IMAGE_BL32)
- #define MAX_MMAP_REGIONS 6
-#endif
-
-/* DTB initialization value */
-#define STM32MP_DTB_SIZE U(0x00005000) /* 20 KB for DTB */
-
-#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \
- STM32MP_DTB_SIZE)
#define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000))
+#define STM32MP_BL33_MAX_SIZE U(0x400000)
/* Define maximum page size for NAND devices */
#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000)
/*******************************************************************************
- * STM32MP1 RAW partition offset for MTD devices
- ******************************************************************************/
-#define STM32MP_NOR_BL33_OFFSET U(0x00080000)
-#ifdef AARCH32_SP_OPTEE
-#define STM32MP_NOR_TEEH_OFFSET U(0x00280000)
-#define STM32MP_NOR_TEED_OFFSET U(0x002C0000)
-#define STM32MP_NOR_TEEX_OFFSET U(0x00300000)
-#endif
-
-#define STM32MP_NAND_BL33_OFFSET U(0x00200000)
-#ifdef AARCH32_SP_OPTEE
-#define STM32MP_NAND_TEEH_OFFSET U(0x00600000)
-#define STM32MP_NAND_TEED_OFFSET U(0x00680000)
-#define STM32MP_NAND_TEEX_OFFSET U(0x00700000)
-#endif
-
-/*******************************************************************************
* STM32MP1 device/io map related constants (used for MMU)
******************************************************************************/
#define STM32MP1_DEVICE1_BASE U(0x40000000)
@@ -251,6 +205,8 @@
#define DEBUG_UART_TX_CLKSRC RCC_UART24CKSELR_HSI
#define DEBUG_UART_TX_EN_REG RCC_MP_APB1ENSETR
#define DEBUG_UART_TX_EN RCC_MP_APB1ENSETR_UART4EN
+#define DEBUG_UART_RST_REG RCC_APB1RSTSETR
+#define DEBUG_UART_RST_BIT RCC_APB1RSTSETR_UART4RST
/*******************************************************************************
* STM32MP1 ETZPC
@@ -355,18 +311,6 @@
******************************************************************************/
#define STM32MP1_TZC_BASE U(0x5C006000)
-#define STM32MP1_TZC_A7_ID U(0)
-#define STM32MP1_TZC_M4_ID U(1)
-#define STM32MP1_TZC_LCD_ID U(3)
-#define STM32MP1_TZC_GPU_ID U(4)
-#define STM32MP1_TZC_MDMA_ID U(5)
-#define STM32MP1_TZC_DMA_ID U(6)
-#define STM32MP1_TZC_USB_HOST_ID U(7)
-#define STM32MP1_TZC_USB_OTG_ID U(8)
-#define STM32MP1_TZC_SDMMC_ID U(9)
-#define STM32MP1_TZC_ETH_ID U(10)
-#define STM32MP1_TZC_DAP_ID U(15)
-
#define STM32MP1_FILTER_BIT_ALL (TZC_400_REGION_ATTR_FILTER_BIT(0) | \
TZC_400_REGION_ATTR_FILTER_BIT(1))
diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
new file mode 100644
index 0000000..caf9ff1
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/arm/tzc400.h>
+#include <drivers/st/stm32mp1_clk.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <lib/fconf/fconf.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <platform_def.h>
+#include <stm32mp_fconf_getter.h>
+
+#define STM32MP_REGION_PARAMS 4
+#define STM32MP_MAX_REGIONS 8
+#define FORCE_SEC_REGION BIT(31)
+
+static uint32_t nb_regions;
+
+struct dt_id_attr {
+ fdt32_t id_attr[STM32MP_MAX_REGIONS];
+};
+
+void stm32mp1_arch_security_setup(void)
+{
+ stm32mp_clk_enable(TZC1);
+ stm32mp_clk_enable(TZC2);
+
+ tzc400_init(STM32MP1_TZC_BASE);
+ tzc400_disable_filters();
+
+ /*
+ * Region 0 set to cover all DRAM at 0xC000_0000
+ * Only secure access is granted in read/write.
+ */
+ tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
+
+ tzc400_set_action(TZC_ACTION_ERR);
+ tzc400_enable_filters();
+}
+
+void stm32mp1_security_setup(void)
+{
+ uint8_t i;
+
+ assert(nb_regions > 0U);
+
+ tzc400_init(STM32MP1_TZC_BASE);
+ tzc400_disable_filters();
+
+ /*
+ * Region 0 set to cover all DRAM at 0xC000_0000
+ * No access is allowed.
+ */
+ tzc400_configure_region0(TZC_REGION_S_NONE, 0);
+
+ for (i = 1U; i <= nb_regions; i++) {
+ tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
+ }
+
+ tzc400_set_action(TZC_ACTION_INT);
+ tzc400_enable_filters();
+}
+
+static int fconf_populate_stm32mp1_firewall(uintptr_t config)
+{
+ int node, len;
+ unsigned int i;
+ const struct dt_id_attr *conf_list;
+ const void *dtb = (const void *)config;
+
+ /* Assert the node offset point to "st,mem-firewall" compatible property */
+ const char *compatible_str = "st,mem-firewall";
+
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
+ if (conf_list == NULL) {
+ WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
+ return -1;
+ }
+
+ /* Locate the memory cells and read all values */
+ for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
+ uint32_t base;
+ uint32_t size;
+ uint32_t sec_attr;
+ uint32_t nsaid;
+
+ base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
+ size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
+ sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
+ nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
+
+ VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
+ base, size, sec_attr, nsaid);
+
+ nb_regions++;
+
+ /* Configure region but keep disabled for secure access for BL2 load */
+ tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
+ (unsigned long long)base + size - 1ULL, sec_attr, nsaid);
+ }
+
+ /* Force flush as the value will be used cache off */
+ flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
new file mode 100644
index 0000000..d8561dc
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_FIP_DEF_H
+#define STM32MP1_FIP_DEF_H
+
+#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
+#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
+
+#define STM32MP_BL2_SIZE U(0x0001B000) /* 108 KB for BL2 */
+#define STM32MP_BL2_DTB_SIZE U(0x00006000) /* 24 KB for DTB */
+#define STM32MP_BL32_SIZE U(0x00019000) /* 100 KB for BL32 */
+#define STM32MP_BL32_DTB_SIZE U(0x00005000) /* 20 KB for DTB */
+#define STM32MP_FW_CONFIG_MAX_SIZE PAGE_SIZE /* 4 KB for FCONF DTB */
+#define STM32MP_HW_CONFIG_MAX_SIZE U(0x40000) /* 256 KB for HW config DTB */
+
+#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \
+ STM32MP_SEC_SYSRAM_SIZE - \
+ STM32MP_BL2_SIZE)
+
+#define STM32MP_BL2_DTB_BASE (STM32MP_BL2_BASE - \
+ STM32MP_BL2_DTB_SIZE)
+
+#define STM32MP_BL32_DTB_BASE STM32MP_SYSRAM_BASE
+
+#define STM32MP_BL32_BASE (STM32MP_BL32_DTB_BASE + \
+ STM32MP_BL32_DTB_SIZE)
+
+
+#if defined(IMAGE_BL2)
+#define STM32MP_DTB_SIZE STM32MP_BL2_DTB_SIZE
+#define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE
+#endif
+#if defined(IMAGE_BL32)
+#define STM32MP_DTB_SIZE STM32MP_BL32_DTB_SIZE
+#define STM32MP_DTB_BASE STM32MP_BL32_DTB_BASE
+#endif
+
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE
+
+#define STM32MP_OPTEE_SIZE (STM32MP_BL2_DTB_BASE - \
+ STM32MP_OPTEE_BASE)
+#endif
+
+#define STM32MP_FW_CONFIG_BASE (STM32MP_SYSRAM_BASE + \
+ STM32MP_SYSRAM_SIZE - \
+ PAGE_SIZE)
+#define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \
+ STM32MP_BL33_MAX_SIZE)
+
+/*
+ * MAX_MMAP_REGIONS is usually:
+ * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup
+ */
+#if defined(IMAGE_BL32)
+#define MAX_MMAP_REGIONS 10
+#endif
+
+/*******************************************************************************
+ * STM32MP1 RAW partition offset for MTD devices
+ ******************************************************************************/
+#define STM32MP_NOR_FIP_OFFSET U(0x00080000)
+#define STM32MP_NAND_FIP_OFFSET U(0x00200000)
+
+#endif /* STM32MP1_FIP_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index 84e9e8d..cac9752 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -148,6 +148,19 @@
* ---------------------------------------------
*/
func plat_crash_console_init
+ /* Reset UART peripheral */
+ ldr r1, =(RCC_BASE + DEBUG_UART_RST_REG)
+ ldr r2, =DEBUG_UART_RST_BIT
+ str r2, [r1]
+1:
+ ldr r0, [r1]
+ ands r2, r0, r2
+ beq 1b
+ str r2, [r1, #4] /* RSTCLR register */
+2:
+ ldr r0, [r1]
+ ands r2, r0, r2
+ bne 2b
/* Enable GPIOs for UART TX */
ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
ldr r2, [r1]
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index 1af0075..e4065c1 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -452,6 +452,7 @@
}
#endif
+#if STM32MP_USE_STM32IMAGE
/* Get the non-secure DDR size */
uint32_t stm32mp_get_ddr_ns_size(void)
{
@@ -472,3 +473,4 @@
return ddr_ns_size;
}
+#endif /* STM32MP_USE_STM32IMAGE */
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
index 2ee5f4a..19ef4f0 100644
--- a/plat/st/stm32mp1/stm32mp1_security.c
+++ b/plat/st/stm32mp1/stm32mp1_security.c
@@ -12,21 +12,9 @@
#include <drivers/arm/tzc400.h>
#include <drivers/st/stm32mp1_clk.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/soc/stm32mp15-tzc400.h>
#include <lib/mmio.h>
-#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID)
-
static unsigned int region_nb;
static void init_tzc400_begin(unsigned int region0_attr)
diff --git a/plat/st/stm32mp1/stm32mp1_stm32image_def.h b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
new file mode 100644
index 0000000..8efa342
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_STM32IMAGE_DEF_H
+#define STM32MP1_STM32IMAGE_DEF_H
+
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
+#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
+#else
+#define STM32MP_DDR_S_SIZE U(0)
+#define STM32MP_DDR_SHMEM_SIZE U(0)
+#endif
+
+#define STM32MP_BL2_SIZE U(0x0001C000) /* 112 KB for BL2 */
+#define STM32MP_DTB_SIZE U(0x00006000) /* 24 KB for DTB */
+
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_BL32_BASE STM32MP_SEC_SYSRAM_BASE
+
+#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \
+ STM32MP_SEC_SYSRAM_SIZE - \
+ STM32MP_BL2_SIZE)
+
+/* OP-TEE loads from SYSRAM base to BL2 DTB start address */
+#define STM32MP_OPTEE_BASE STM32MP_BL32_BASE
+#define STM32MP_OPTEE_SIZE (STM32MP_SEC_SYSRAM_SIZE - \
+ STM32MP_BL2_SIZE - STM32MP_DTB_SIZE)
+#define STM32MP_BL32_SIZE STM32MP_OPTEE_SIZE
+#else /* AARCH32_SP_OPTEE */
+#define STM32MP_BL32_SIZE U(0x00019000) /* 96 KB for BL32 */
+
+#define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \
+ STM32MP_SEC_SYSRAM_SIZE - \
+ STM32MP_BL32_SIZE)
+
+#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \
+ STM32MP_BL2_SIZE)
+#endif /* AARCH32_SP_OPTEE */
+
+/* DTB initialization value */
+#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \
+ STM32MP_DTB_SIZE)
+
+/*
+ * MAX_MMAP_REGIONS is usually:
+ * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup
+ */
+#if defined(IMAGE_BL32)
+#define MAX_MMAP_REGIONS 6
+#endif
+
+/*******************************************************************************
+ * STM32MP1 RAW partition offset for MTD devices
+ ******************************************************************************/
+#define STM32MP_NOR_BL33_OFFSET U(0x00080000)
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_NOR_TEEH_OFFSET U(0x00280000)
+#define STM32MP_NOR_TEED_OFFSET U(0x002C0000)
+#define STM32MP_NOR_TEEX_OFFSET U(0x00300000)
+#endif
+
+#define STM32MP_NAND_BL33_OFFSET U(0x00200000)
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_NAND_TEEH_OFFSET U(0x00600000)
+#define STM32MP_NAND_TEED_OFFSET U(0x00680000)
+#define STM32MP_NAND_TEEX_OFFSET U(0x00700000)
+#endif
+
+#endif /* STM32MP1_STM32IMAGE_DEF_H */
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index dda127f..6de5feb 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -65,14 +65,6 @@
}
/*******************************************************************************
- * SPM Core entry point information get helper.
- ******************************************************************************/
-entry_point_info_t *spmd_spmc_ep_info_get(void)
-{
- return spmc_ep_info;
-}
-
-/*******************************************************************************
* SPM Core ID getter.
******************************************************************************/
uint16_t spmd_spmc_id_get(void)
@@ -156,18 +148,11 @@
{
spmd_spm_core_context_t *ctx = spmd_get_context();
uint64_t rc;
- unsigned int linear_id = plat_my_core_pos();
- unsigned int core_id;
VERBOSE("SPM Core init start.\n");
- ctx->state = SPMC_STATE_ON_PENDING;
- /* Set the SPMC context state on other CPUs to OFF */
- for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) {
- if (core_id != linear_id) {
- spm_core_context[core_id].state = SPMC_STATE_OFF;
- }
- }
+ /* Primary boot core enters the SPMC for initialization. */
+ ctx->state = SPMC_STATE_ON_PENDING;
rc = spmd_spm_core_sync_entry(ctx);
if (rc != 0ULL) {
@@ -187,7 +172,8 @@
******************************************************************************/
static int spmd_spmc_init(void *pm_addr)
{
- spmd_spm_core_context_t *spm_ctx = spmd_get_context();
+ cpu_context_t *cpu_ctx;
+ unsigned int core_id;
uint32_t ep_attr;
int rc;
@@ -280,13 +266,21 @@
DISABLE_ALL_EXCEPTIONS);
}
- /* Initialise SPM Core context with this entry point information */
- cm_setup_context(&spm_ctx->cpu_ctx, spmc_ep_info);
+ /* Set an initial SPMC context state for all cores. */
+ for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) {
+ spm_core_context[core_id].state = SPMC_STATE_OFF;
- /* Reuse PSCI affinity states to mark this SPMC context as off */
- spm_ctx->state = AFF_STATE_OFF;
+ /* Setup an initial cpu context for the SPMC. */
+ cpu_ctx = &spm_core_context[core_id].cpu_ctx;
+ cm_setup_context(cpu_ctx, spmc_ep_info);
- INFO("SPM Core setup done.\n");
+ /*
+ * Pass the core linear ID to the SPMC through x4.
+ * (TF-A implementation defined behavior helping
+ * a legacy TOS migration to adopt FF-A).
+ */
+ write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4, core_id);
+ }
/* Register power management hooks with PSCI */
psci_register_spd_pm_hook(&spmd_pm);
@@ -294,6 +288,8 @@
/* Register init function for deferred init. */
bl31_register_bl32_init(&spmd_init);
+ INFO("SPM Core setup done.\n");
+
return 0;
}
@@ -620,9 +616,19 @@
case FFA_RXTX_MAP_SMC64:
case FFA_RXTX_UNMAP:
case FFA_PARTITION_INFO_GET:
+#if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED
+ case FFA_NOTIFICATION_BITMAP_CREATE:
+ case FFA_NOTIFICATION_BITMAP_DESTROY:
+ case FFA_NOTIFICATION_BIND:
+ case FFA_NOTIFICATION_UNBIND:
+ case FFA_NOTIFICATION_SET:
+ case FFA_NOTIFICATION_GET:
+ case FFA_NOTIFICATION_INFO_GET:
+ case FFA_NOTIFICATION_INFO_GET_SMC64:
+#endif
/*
- * Should not be allowed to forward FFA_PARTITION_INFO_GET
- * from Secure world to Normal world
+ * Above calls should not be forwarded from Secure world to
+ * Normal world.
*
* Fall through to forward the call to the other world
*/
diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c
index 074609c..ac962ea 100644
--- a/services/std_svc/spmd/spmd_pm.c
+++ b/services/std_svc/spmd/spmd_pm.c
@@ -75,14 +75,14 @@
******************************************************************************/
static void spmd_cpu_on_finish_handler(u_register_t unused)
{
- entry_point_info_t *spmc_ep_info = spmd_spmc_ep_info_get();
spmd_spm_core_context_t *ctx = spmd_get_context();
unsigned int linear_id = plat_my_core_pos();
+ el3_state_t *el3_state;
+ uintptr_t entry_point;
uint64_t rc;
assert(ctx != NULL);
assert(ctx->state != SPMC_STATE_ON);
- assert(spmc_ep_info != NULL);
spin_lock(&g_spmd_pm.lock);
@@ -92,14 +92,20 @@
* primary core address for booting secondary cores.
*/
if (g_spmd_pm.secondary_ep_locked == true) {
- spmc_ep_info->pc = g_spmd_pm.secondary_ep;
+ /*
+ * The CPU context has already been initialized at boot time
+ * (in spmd_spmc_init by a call to cm_setup_context). Adjust
+ * below the target core entry point based on the address
+ * passed to by FFA_SECONDARY_EP_REGISTER.
+ */
+ entry_point = g_spmd_pm.secondary_ep;
+ el3_state = get_el3state_ctx(&ctx->cpu_ctx);
+ write_ctx_reg(el3_state, CTX_ELR_EL3, entry_point);
}
spin_unlock(&g_spmd_pm.lock);
- cm_setup_context(&ctx->cpu_ctx, spmc_ep_info);
-
- /* Mark CPU as initiating ON operation */
+ /* Mark CPU as initiating ON operation. */
ctx->state = SPMC_STATE_ON_PENDING;
rc = spmd_spm_core_sync_entry(ctx);
diff --git a/tools/renesas/rcar_layout_create/sa6.c b/tools/renesas/rcar_layout_create/sa6.c
index fa828b9..8fafdad 100644
--- a/tools/renesas/rcar_layout_create/sa6.c
+++ b/tools/renesas/rcar_layout_create/sa6.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -96,7 +96,7 @@
#define RCAR_BL32DST_ADDRESS (0x44100000U)
#define RCAR_BL32DST_ADDRESSH (0x00000000U)
/* Destination size for BL32 */
-#define RCAR_BL32DST_SIZE (0x00040000U)
+#define RCAR_BL32DST_SIZE (0x00080000U)
/* Destination address for BL33 */
#define RCAR_BL33DST_ADDRESS (0x50000000U)
#define RCAR_BL33DST_ADDRESSH (0x00000000U)
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index a37e702..f983ff3 100755
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -1,5 +1,5 @@
#!/usr/bin/python3
-# Copyright (c) 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
@@ -110,24 +110,36 @@
Extract uuid from partition manifest
"""
pm_file = open(dts)
- uuid_key = "uuid"
-
for line in pm_file:
- if uuid_key in line:
- uuid_hex = re.findall(r'\<(.+?)\>', line)[0];
+ if "uuid" in line:
+ # re.findall returns a list of string tuples.
+ # uuid_hex is the first item in this list representing the four
+ # uuid hex integers from the manifest uuid field. The heading
+ # '0x' of the hexadecimal representation is stripped out.
+ # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
+ # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da')
+ uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0];
- # PM has uuid in format 0xABC... 0x... 0x... 0x...
- # Get rid of '0x' and spaces and convert to string of hex digits
- uuid_hex = uuid_hex.replace('0x','').replace(' ','')
- # make UUID from a string of hex digits
- uuid_std = uuid.UUID(uuid_hex)
- # convert UUID to a string of hex digits in standard form
- uuid_std = str(uuid_std)
+ # uuid_hex is a list of four hex string values
+ if len(uuid_hex) != 4:
+ print("ERROR: malformed UUID")
+ exit(-1)
+
+ # The uuid field in SP manifest is the little endian representation
+ # mapped to arguments as described in SMCCC section 5.3.
+ # Convert each unsigned integer value to a big endian representation
+ # required by fiptool.
+ y=list(map(bytearray.fromhex, uuid_hex))
+ z=(int.from_bytes(y[0], byteorder='little', signed=False),
+ int.from_bytes(y[1], byteorder='little', signed=False),
+ int.from_bytes(y[2], byteorder='little', signed=False),
+ int.from_bytes(y[3], byteorder='little', signed=False))
+ uuid_std = uuid.UUID(f'{z[0]:04x}{z[1]:04x}{z[2]:04x}{z[3]:04x}')
"""
Append FIP_ARGS
"""
- out_file.write("FIP_ARGS += --blob uuid=" + uuid_std + ",file=" + dst + "\n")
+ out_file.write("FIP_ARGS += --blob uuid=" + str(uuid_std) + ",file=" + dst + "\n")
"""
Append CRT_ARGS