Merge changes from topic "advk-serror" into integration
* changes:
fix(plat/marvell/a3k): disable HANDLE_EA_EL3_FIRST by default
fix(plat/marvell/a3k): update information about PCIe abort hack
diff --git a/Makefile b/Makefile
index b4bebf1..8411355 100644
--- a/Makefile
+++ b/Makefile
@@ -525,6 +525,10 @@
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
else
# All other SPDs in spd directory
SPD_DIR := spd
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index bc277a7..bde6d97 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -281,6 +281,19 @@
- ``ERRATA_A78_1821534``: This applies errata 1821534 workaround to Cortex-A78
CPU. This needs to be enabled for revisions r0p0 and r1p0.
+- ``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.
+
+For Cortex-A78 AE, the following errata build flags are defined :
+
+- ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to Cortex-A78
+ AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This erratum is
+ still open.
+
+- ``ERRATA_A78_AE_1951502`` : This applies errata 1951502 workaround to Cortex-A78
+ AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This erratum is
+ still open.
+
For Neoverse N1, the following errata build flags are defined :
- ``ERRATA_N1_1073348``: This applies errata 1073348 workaround to Neoverse-N1
@@ -323,6 +336,11 @@
CPU. This needs to be enabled for revisions r3p0, r3p1, r4p0, and r4p1, for
revisions r0p0, r1p0, and r2p0 there is no workaround.
+For Neoverse N2, the following errata build flags are defined :
+
+- ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open.
+
For Neoverse V1, the following errata build flags are defined :
- ``ERRATA_V1_1774420``: This applies errata 1774420 workaround to Neoverse-V1
@@ -353,6 +371,38 @@
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
+ Cortex-A710 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
+ r2p0 of the CPU. It is still open.
+
+- ``ERRATA_A710_2081180``: This applies errata 2081180 workaround to
+ 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.
+
+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.
+
DSU Errata Workarounds
----------------------
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 901a72a..bac8847 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -790,6 +790,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/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index d4fa98d..74251bd 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -100,6 +100,9 @@
- ``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.
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 b10fb3a..b125144 100644
--- a/docs/plat/marvell/armada/build.rst
+++ b/docs/plat/marvell/armada/build.rst
@@ -62,6 +62,7 @@
- a80x0_mcbin - MacchiatoBin
- a80x0_puzzle - IEI Puzzle-M801
- t9130 - CN913x
+ - t9130_cex7_eval - CN913x CEx7 Evaluation Board
- DEBUG
@@ -136,6 +137,19 @@
The parameter is optional, its default value is ``plat/marvell/armada/a8k/common/ble``
which uses TF-A in-tree BLE implementation.
+- MSS_SUPPORT
+
+ When ``MSS_SUPPORT=1``, then TF-A includes support for Management SubSystem (MSS).
+ When enabled it is required to specify path to the MSS firmware image via ``SCP_BL2``
+ option.
+
+ This option is by default enabled.
+
+- SCP_BL2
+
+ Specify path to the MSS fimware image binary which will run on Cortex-M3 coprocessor.
+ It is available in Marvell binaries-marvell git repository. Required when ``MSS_SUPPORT=1``.
+
Armada37x0 specific build options:
@@ -428,10 +442,15 @@
https://gitlab.nic.cz/turris/mox-boot-builder.git
-Armada70x0 and Armada80x0 Builds require installation of an additional component
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Armada70x0, Armada80x0 and CN913x Builds require installation of additional components
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(1) DDR initialization library sources (mv_ddr) available at the following repository
(use the "master" branch):
https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
+
+(2) MSS Management SubSystem Firmware available at the following repository
+ (use the "binaries-marvell-armada-SDK10.0.1.0" branch):
+
+ https://github.com/MarvellEmbeddedProcessors/binaries-marvell.git
diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index 02ff38b..391c7c8 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -19,7 +19,7 @@
multi-processing (HMP) solution designed to optimize performance and
efficiency.
-T186 has Dual NVIDIA Denver 2 ARM® CPU cores, plus Quad ARM Cortex®-A57 cores,
+T186 has Dual NVIDIA Denver2 ARM® CPU cores, plus Quad ARM Cortex®-A57 cores,
in a coherent multiprocessor configuration. The Denver 2 and Cortex-A57 cores
support ARMv8, executing both 64-bit Aarch64 code, and 32-bit Aarch32 code
including legacy ARMv7 applications. The Denver 2 processors each have 128 KB
@@ -29,20 +29,6 @@
high speed coherency fabric connects these two processor complexes and allows
heterogeneous multi-processing with all six cores if required.
-- .. rubric:: T210
- :name: t210
-
-T210 has Quad Arm® Cortex®-A57 cores in a switched configuration with a
-companion set of quad Arm Cortex-A53 cores. The Cortex-A57 and A53 cores
-support Armv8-A, executing both 64-bit Aarch64 code, and 32-bit Aarch32 code
-including legacy Armv7-A applications. The Cortex-A57 processors each have
-48 KB Instruction and 32 KB Data Level 1 caches; and have a 2 MB shared
-Level 2 unified cache. The Cortex-A53 processors each have 32 KB Instruction
-and 32 KB Data Level 1 caches; and have a 512 KB shared Level 2 unified cache.
-
-- .. rubric:: T132
- :name: t132
-
Denver is NVIDIA's own custom-designed, 64-bit, dual-core CPU which is
fully Armv8-A architecture compatible. Each of the two Denver cores
implements a 7-way superscalar microarchitecture (up to 7 concurrent
@@ -68,6 +54,17 @@
to extensive power-gating and dynamic voltage and clock scaling based on
workloads.
+- .. rubric:: T210
+ :name: t210
+
+T210 has Quad Arm® Cortex®-A57 cores in a switched configuration with a
+companion set of quad Arm Cortex-A53 cores. The Cortex-A57 and A53 cores
+support Armv8-A, executing both 64-bit Aarch64 code, and 32-bit Aarch32 code
+including legacy Armv7-A applications. The Cortex-A57 processors each have
+48 KB Instruction and 32 KB Data Level 1 caches; and have a 2 MB shared
+Level 2 unified cache. The Cortex-A53 processors each have 32 KB Instruction
+and 32 KB Data Level 1 caches; and have a 512 KB shared Level 2 unified cache.
+
Directory structure
-------------------
@@ -89,7 +86,6 @@
These are the supported Trusted OS' by Tegra platforms.
-- Tegra132: TLK
- Tegra210: TLK and Trusty
- Tegra186: Trusty
- Tegra194: Trusty
@@ -110,7 +106,7 @@
.. code:: shell
CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- make PLAT=tegra \
- TARGET_SOC=<target-soc e.g. t194|t186|t210|t132> SPD=<dispatcher e.g. trusty|tlkd>
+ TARGET_SOC=<target-soc e.g. t194|t186|t210> SPD=<dispatcher e.g. trusty|tlkd>
bl31
Platforms wanting to use different TZDRAM\_BASE, can add ``TZDRAM_BASE=<value>``
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..3d98354
--- /dev/null
+++ b/docs/plat/nxp/nxp-layerscape.rst
@@ -0,0 +1,232 @@
+NXP SoCs - Overview
+=====================
+.. section-numbering::
+ :suffix: .
+
+The QorIQ family of ARM based SoCs that are supported on TF-A are:
+
+1. LX2160ARDB:
+ Platform Name:
+
+ a. lx2160ardb (Board details can be fetched from the link: `lx2160ardb`_)
+
+
+Table of supported boot-modes by each platform & platform that needs FIP-DDR:
+-----------------------------------------------------------------------------
+
++---+-----------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
+| | BOOT_MODE-->| sd | qspi | nor | nand | emmc | flexspi_nor | flexspi_nand | fip_ddr needed |
+| | | | | | | | | | |
+| | PLAT | | | | | | | | |
++===+=================+=======+========+=======+=======+=======+=============+==============+=================+
+| 1.| lx2160ardb | yes | | | | yes | yes | | yes |
++---+-----------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
+
+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 ---------------/
++
+
+
+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.
+
+
+.. _lx2160ardb: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-communication-process/layerscape-lx2160a-multicore-communications-processor:LX2160A
+.. _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/resources/diagrams/plantuml/spm_dfd.puml b/docs/resources/diagrams/plantuml/spm_dfd.puml
new file mode 100644
index 0000000..ad4996e
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/spm_dfd.puml
@@ -0,0 +1,82 @@
+/'
+ ' Copyright (c) 2021, Arm Limited. All rights reserved.
+ '
+ ' SPDX-License-Identifier: BSD-3-Clause
+ '/
+
+/'
+TF-A SPMC Data Flow Diagram
+'/
+
+@startuml
+digraph tfa_dfd {
+
+ # Allow arrows to end on cluster boundaries
+ compound=true
+
+ # Default settings for edges and nodes
+ edge [minlen=2 color="#8c1b07"]
+ node [fillcolor="#ffb866" style=filled shape=box fixedsize=true width=1.6 height=0.7]
+
+ # Nodes outside of the trust boundary
+ nsec [label="NS Client"]
+ ddr [label="External memory (DDR)"]
+
+ # Trust boundary cluster
+ subgraph cluster_trusted {
+ graph [style=dashed color="#f22430"]
+
+ # HW IPs cluster
+ subgraph cluster_ip {
+ label ="Hardware IPs";
+ graph [style=filled color="#000000" fillcolor="#ffd29e"]
+
+ rank="same"
+ gic [label="GIC" width=1.2 height=0.5]
+ smmu [label="SMMU" width=1.2 height=0.5]
+ uart [label="UART" width=1.2 height=0.5]
+ pe [label="PE" width=1.2 height=0.5]
+ }
+
+ # TF-A cluster
+ subgraph cluster_tfa {
+ label ="EL3 monitor";
+ graph [style=filled color="#000000" fillcolor="#faf9cd"]
+
+ bl31 [label="BL31" fillcolor="#ddffb3"];
+ spmd [label="SPMD" fillcolor="#ddffb3" height=1]
+ }
+
+ # SPMC cluster
+ subgraph cluster_spmc {
+ label ="SPMC";
+ graph [style=filled color="#000000" fillcolor="#faf9cd"]
+
+ spmc [label="SPMC" fillcolor="#ddffb3" height=1]
+ }
+ bl2 [label="BL2" width=1.2 height=0.5]
+ }
+
+ # Secure Partitions cluster
+ subgraph cluster_sp {
+ label ="Secure Partitions";
+ graph [style=filled color="#000000" fillcolor="#faf9cd"]
+
+ sp1 [label="SP1" fillcolor="#ddffb3" height=1]
+ sp2 [label="SP2" fillcolor="#ddffb3" height=1]
+ spn [label="SP..." fillcolor="#ddffb3" height=1]
+ }
+
+ # Interactions between nodes
+ sp1 -> spmc [dir="both" label="DF1"]
+ spmc -> spmd [dir="both" label="DF2"]
+ spmd -> nsec [dir="both" label="DF3"]
+ sp1 -> sp2 [dir="both" label="DF4"]
+ spmc -> smmu [lhead=cluster_spmc label="DF5"]
+ bl2 -> spmc [lhead=cluster_spmc label="DF6"]
+ bl2 -> spn [lhead=cluster_spmc label="DF6"]
+ sp1 -> ddr [dir="both" label="DF7"]
+ spmc -> ddr [dir="both" label="DF7"]
+}
+
+@enduml
diff --git a/docs/resources/diagrams/spm-threat-model-trust-boundaries.png b/docs/resources/diagrams/spm-threat-model-trust-boundaries.png
new file mode 100644
index 0000000..58898c5
--- /dev/null
+++ b/docs/resources/diagrams/spm-threat-model-trust-boundaries.png
Binary files differ
diff --git a/docs/threat_model/index.rst b/docs/threat_model/index.rst
index e8f09b9..b5ede69 100644
--- a/docs/threat_model/index.rst
+++ b/docs/threat_model/index.rst
@@ -1,5 +1,12 @@
Threat Model
-=============
+============
+
+Threat modeling is an important part of Secure Development Lifecycle (SDL)
+that helps us identify potential threats and mitigations affecting a system.
+
+In the next sections, we first give a description of the target of evaluation
+using a data flow diagram. Then we provide a list of threats we have identified
+based on the data flow diagram and potential threat mitigations.
.. toctree::
:maxdepth: 1
@@ -7,6 +14,7 @@
:numbered:
threat_model
+ threat_model_spm
--------------
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 9cee104..9f26487 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -1,13 +1,10 @@
-*****************
-Introduction
-*****************
-Threat modeling is an important part of Secure Development Lifecycle (SDL)
-that helps us identify potential threats and mitigations affecting a system.
+Generic threat model
+********************
-This document provides a generic threat model for TF-A firmware. In the
-next sections, we first give a description of the target of evaluation
-using a data flow diagram. Then we provide a list of threats we have
-identified based on the data flow diagram and potential threat mitigations.
+************************
+Introduction
+************************
+This document provides a generic threat model for TF-A firmware.
************************
Target of Evaluation
@@ -781,4 +778,4 @@
.. _Trusted Board Boot (TBB): https://trustedfirmware-a.readthedocs.io/en/latest/design/trusted-board-boot.html
.. _TF-A error handling policy: https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#error-handling-and-robustness
.. _Secure Development Guidelines: https://trustedfirmware-a.readthedocs.io/en/latest/process/security-hardening.html#secure-development-guidelines
-.. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
\ No newline at end of file
+.. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
diff --git a/docs/threat_model/threat_model_spm.rst b/docs/threat_model/threat_model_spm.rst
new file mode 100644
index 0000000..96d33a2
--- /dev/null
+++ b/docs/threat_model/threat_model_spm.rst
@@ -0,0 +1,617 @@
+SPMC threat model
+*****************
+
+************************
+Introduction
+************************
+This document provides a threat model for the TF-A `Secure Partition Manager`_
+(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.
+
+In brief, the broad FF-A specification and S-EL2 firmware implementation
+provide:
+
+- Isolation of mutually mistrusting SW components, or endpoints in the FF-A
+ terminology.
+- Distinct sandboxes in the secure world called secure partitions. This permits
+ isolation of services from multiple vendors.
+- A standard protocol for communication and memory sharing between FF-A
+ endpoints.
+- Mutual isolation of the normal world and the secure world (e.g. a Trusted OS
+ is prevented to map an arbitrary NS physical memory region such as the kernel
+ or the Hypervisor).
+
+************************
+Target of Evaluation
+************************
+In this threat model, the target of evaluation is the S-EL2 firmware or the
+``Secure Partition Manager Core`` component (SPMC).
+The monitor and SPMD at EL3 are covered by the `Generic TF-A threat model`_.
+
+The scope for this threat model is:
+
+- The TF-A implementation for the S-EL2 SPMC based on the Hafnium hypervisor
+ running in the secure world of TrustZone (at S-EL2 exception level).
+ The threat model is not related to the normal world Hypervisor or VMs.
+ The S-EL1 SPMC solution is not covered.
+- The implementation complies with the FF-A v1.0 specification.
+- Secure partitions are statically provisioned at boot time.
+- Focus on the run-time part of the life-cycle (no specific emphasis on boot
+ time, factory firmware provisioning, firmware udpate etc.)
+- Not covering advanced or invasive physical attacks such as decapsulation,
+ FIB etc.
+- Assumes secure boot or in particular TF-A trusted boot (TBBR or dual CoT) is
+ enabled. An attacker cannot boot arbitrary images that are not approved by the
+ SiP or platform providers.
+
+Data Flow Diagram
+======================
+Figure 1 shows a high-level data flow diagram for the SPM split into an SPMD
+component at EL3 and an SPMC component at S-EL2. The SPMD mostly acts as a
+relayer/pass-through between the normal world and the secure world. It is
+assumed to expose small attack surface.
+
+A description of each diagram element is given in Table 1. In the diagram, the
+red broken lines indicate trust boundaries.
+
+Components outside of the broken lines are considered untrusted.
+
+.. uml:: ../resources/diagrams/plantuml/spm_dfd.puml
+ :caption: Figure 1: SPMC Data Flow Diagram
+
+.. table:: Table 1: SPMC Data Flow Diagram Description
+
+ +---------------------+--------------------------------------------------------+
+ | Diagram Element | Description |
+ +=====================+========================================================+
+ | ``DF1`` | SP to SPMC communication. FF-A function invocation or |
+ | | implementation-defined Hypervisor call. |
+ +---------------------+--------------------------------------------------------+
+ | ``DF2`` | SPMC to SPMD FF-A call. |
+ +---------------------+--------------------------------------------------------+
+ | ``DF3`` | SPMD to NS forwarding. |
+ +---------------------+--------------------------------------------------------+
+ | ``DF4`` | SP to SP FF-A direct message request/response. |
+ | | Note as a matter of simplifying the diagram |
+ | | the SP to SP communication happens through the SPMC |
+ | | (SP1 performs a direct message request to the |
+ | | SPMC targeting SP2 as destination. And similarly for |
+ | | the direct message response from SP2 to SP1). |
+ +---------------------+--------------------------------------------------------+
+ | ``DF5`` | HW control. |
+ +---------------------+--------------------------------------------------------+
+ | ``DF6`` | Bootloader image loading. |
+ +---------------------+--------------------------------------------------------+
+ | ``DF7`` | External memory access. |
+ +---------------------+--------------------------------------------------------+
+
+*********************
+Threat Analysis
+*********************
+
+This threat model follows a similar methodology to the `Generic TF-A threat model`_.
+The following sections define:
+
+- Trust boundaries
+- Assets
+- Theat agents
+- Threat types
+
+Trust boundaries
+============================
+
+- Normal world is untrusted.
+- Secure world and normal world are separate trust boundaries.
+- EL3 monitor, SPMD and SPMC are trusted.
+- Bootloaders (in particular BL1/BL2 if using TF-A) and run-time BL31 are
+ implicitely trusted by the usage of secure boot.
+- EL3 monitor, SPMD, SPMC do not trust SPs.
+
+.. figure:: ../resources/diagrams/spm-threat-model-trust-boundaries.png
+
+ Figure 2: Trust boundaries
+
+Assets
+============================
+
+The following assets are identified:
+
+- SPMC state.
+- SP state.
+- Information exchange between endpoints (partition messages).
+- SPMC secrets (e.g. pointer authentication key when enabled)
+- SP secrets (e.g. application keys).
+- Scheduling cycles.
+- Shared memory.
+
+Threat Agents
+============================
+
+The following threat agents are identified:
+
+- NS-Endpoint identifies a non-secure endpoint: normal world client at NS-EL2
+ (Hypervisor) or NS-EL1 (VM or OS kernel).
+- S-Endpoint identifies a secure endpoint typically a secure partition.
+- Hardware attacks (non-invasive) requiring a physical access to the device,
+ such as bus probing or DRAM stress.
+
+Threat types
+============================
+
+The following threat categories as exposed in the `Generic TF-A threat model`_
+are re-used:
+
+- Spoofing
+- Tampering
+- Repudiation
+- Information disclosure
+- Denial of service
+- Elevation of privileges
+
+Similarly this threat model re-uses the same threat risk ratings. The risk
+analysis is evaluated based on the environment being ``Server`` or ``Mobile``.
+
+Threat Assessment
+============================
+
+The following threats are identified by applying STRIDE analysis on each diagram
+element of the data flow diagram.
+
++------------------------+----------------------------------------------------+
+| ID | 01 |
++========================+====================================================+
+| ``Threat`` | **An endpoint impersonates the sender or receiver |
+| | FF-A ID in a direct request/response invocation.** |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF1, DF2, DF3, DF4 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMD, SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SP state |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Spoofing |
++------------------------+------------------+-----------------+---------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------++----------------+---------------+
+| ``Impact`` | Critical(5) | Critical(5) | |
++------------------------+------------------++----------------+---------------+
+| ``Likelihood`` | Critical(5) | Critical(5) | |
++------------------------+------------------++----------------+---------------+
+| ``Total Risk Rating`` | Critical(25) | Critical(25) | |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations`` | The TF-A SPMC does not mitigate this threat. |
+| | The guidance below is left for a system integrator |
+| | to implemented as necessary. |
+| | The SPMC must enforce checks in the direct message |
+| | request/response interfaces such an endpoint cannot|
+| | spoof the origin and destination worlds (e.g. a NWd|
+| | originated message directed to the SWd cannot use a|
+| | SWd ID as the sender ID). |
+| | Additionally a software component residing in the |
+| | SPMC can be added for the purpose of direct |
+| | request/response filtering. |
+| | It can be configured with the list of known IDs |
+| | and about which interaction can occur between one |
+| | and another endpoint (e.g. which NWd endpoint ID |
+| | sends a direct request to which SWd endpoint ID). |
+| | This component checks the sender/receiver fields |
+| | for a legitimate communication between endpoints. |
+| | A similar component can exist in the OS kernel |
+| | driver, or Hypervisor although it remains untrusted|
+| | by the SPMD/SPMC. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 02 |
++========================+====================================================+
+| ``Threat`` | **Tampering with memory shared between an endpoint |
+| | and the SPMC.** |
+| | A malicious endpoint may attempt tampering with its|
+| | RX/TX buffer contents while the SPMC is processing |
+| | it (TOCTOU). |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF1, DF3, DF4, DF7 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | Shared memory, Information exchange |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Tampering |
++------------------------+------------------+-----------------+---------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+-----------------+---------------+
+| ``Impact`` | High (4) | High (4) | |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood`` | High (4) | High (4) | |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating`` | High (16) | High (16) | |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations`` | In context of FF-A v1.0 this is the case of sharing|
+| | the RX/TX buffer pair and usage in the |
+| | PARTITION_INFO_GET or mem sharing primitives. |
+| | The SPMC must copy the contents of the TX buffer |
+| | to an internal temporary buffer before processing |
+| | its contents. The SPMC must implement hardened |
+| | input validation on data transmitted through the TX|
+| | buffer by an untrusted endpoint. |
+| | The TF-A SPMC mitigates this threat by enforcing |
+| | checks on data transmitted through RX/TX buffers. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 03 |
++========================+====================================================+
+| ``Threat`` | **An endpoint may tamper with its own state or the |
+| | state of another endpoint.** |
+| | A malicious endpoint may attempt violating: |
+| | - its own or another SP state by using an unusual |
+| | combination (or out-of-order) FF-A function |
+| | invocations. |
+| | This can also be an endpoint emitting |
+| | FF-A function invocations to another endpoint while|
+| | the latter in not in a state to receive it (e.g. a |
+| | SP sends a direct request to the normal world early|
+| | while the normal world is not booted yet). |
+| | - the SPMC state itself by employing unexpected |
+| | transitions in FF-A memory sharing, direct requests|
+| | and responses, or handling of interrupts. |
+| | This can be led by random stimuli injection or |
+| | fuzzing. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF1, DF2, DF3, DF4 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMD, SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SP state, SPMC state |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Tampering |
++------------------------+------------------+-----------------+---------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+-----------------+---------------+
+| ``Impact`` | High (4) | High (4) | |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood`` | Medium (3) | Medium (3) | |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating`` | High (12) | High (12) | |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations`` | The SPMC may be vulnerable to invalid state |
+| | transitions for itself or while handling an SP |
+| | state. The FF-A v1.1 specification provides a |
+| | guidance on those state transitions (run-time |
+| | model). The TF-A SPMC will be hardened in future |
+| | releases to follow this guidance. |
+| | Additionally The TF-A SPMC mitigates the threat by |
+| | runs of the Arm `FF-A ACS`_ compliance test suite. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 04 |
++========================+====================================================+
+| ``Threat`` | *An attacker may attempt injecting errors by the |
+| | use of external DRAM stress techniques.** |
+| | A malicious agent may attempt toggling an SP |
+| | Stage-2 MMU descriptor bit within the page tables |
+| | that the SPMC manages. This can happen in Rowhammer|
+| | types of attack. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF7 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SP or SPMC state |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | Hardware attack |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Tampering |
++------------------------+------------------+---------------+-----------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+---------------+-----------------+
+| ``Impact`` | High (4) | High (4) | |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood`` | Low (2) | Medium (3) | |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating`` | Medium (8) | High (12) | |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations`` | The TF-A SPMC does not provide mitigations to this |
+| | type of attack. It can be addressed by the use of |
+| | dedicated HW circuity or hardening at the chipset |
+| | or platform level left to the integrator. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 05 |
++========================+====================================================+
+| ``Threat`` | **Protection of the SPMC from a DMA capable device |
+| | upstream to an SMMU.** |
+| | A device may attempt to tamper with the internal |
+| | SPMC code/data sections. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF5 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SPMC or SP state |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Tampering, Elevation of privileges |
++------------------------+------------------+---------------+-----------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+---------------+-----------------+
+| ``Impact`` | High (4) | High (4) | |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood`` | Medium (3) | Medium (3) | |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating`` | High (12) | High (12) | |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations`` | A platform may prefer assigning boot time, |
+| | statically alocated memory regions through the SMMU|
+| | configuration and page tables. The FF-A v1.1 |
+| | specification provisions this capability through |
+| | static DMA isolation. |
+| | The TF-A SPMC does not mitigate this threat. |
+| | It will adopt the static DMA isolation approach in |
+| | a future release. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 06 |
++========================+====================================================+
+| ``Threat`` | **Replay fragments of past communication between |
+| | endpoints.** |
+| | A malicious endpoint may replay a message exchange |
+| | that occured between two legitimate endpoint as |
+| | a matter of triggering a malfunction or extracting |
+| | secrets from the receiving endpoint. In particular |
+| | the memory sharing operation with fragmented |
+| | messages between an endpoint and the SPMC may be |
+| | replayed by a malicious agent as a matter of |
+| | getting access or gaining permissions to a memory |
+| | region which does not belong to this agent. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF2, DF3 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | Information exchange |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Repdudiation |
++------------------------+------------------+---------------+-----------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+---------------+-----------------+
+| ``Impact`` | Medium (3) | Medium (3) | |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood`` | High (4) | High (4) | |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating`` | High (12) | High (12) | |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations`` | The TF-A SPMC does not mitigate this threat. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 07 |
++========================+====================================================+
+| ``Threat`` | **A malicious endpoint may attempt to extract data |
+| | or state information by the use of invalid or |
+| | incorrect input arguments.** |
+| | Lack of input parameter validation or side effects |
+| | of maliciously forged input parameters might affect|
+| | the SPMC. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF1, DF2, DF3, DF4 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMD, SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SP secrets, SPMC secrets, SP state, SPMC state |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Information discolure |
++------------------------+------------------+---------------+-----------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+---------------+-----------------+
+| ``Impact`` | High (4) | High (4) | |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood`` | Medium (3) | Medium (3) | |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating`` | High (12) | High (12) | |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations`` | Secure Partitions must follow security standards |
+| | and best practises as a way to mitigate the risk |
+| | of common vulnerabilities to be exploited. |
+| | The use of software (canaries) or hardware |
+| | hardening techniques (XN, WXN, BTI, pointer |
+| | authentication, MTE) helps detecting and stopping |
+| | an exploitation early. |
+| | The TF-A SPMC mitigates this threat by implementing|
+| | stack protector, pointer authentication, BTI, XN, |
+| | WXN, security hardening techniques. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 08 |
++========================+====================================================+
+| ``Threat`` | **A malicious endpoint may forge a direct message |
+| | request such that it reveals the internal state of |
+| | another endpoint through the direct message |
+| | response.** |
+| | The secure partition or SPMC replies to a partition|
+| | message by a direct message response with |
+| | information which may reveal its internal state |
+| | (.e.g. partition message response outside of |
+| | allowed bounds). |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF1, DF2, DF3, DF4 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SPMC or SP state |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Information discolure |
++------------------------+------------------+---------------+-----------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+---------------+-----------------+
+| ``Impact`` | Medium (3) | Medium (3) | |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood`` | Low (2) | Low (2) | |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating`` | Medium (6) | Medium (6) | |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations`` | For the specific case of direct requests targetting|
+| | the SPMC, the latter is hardened to prevent |
+| | its internal state or the state of an SP to be |
+| | revealed through a direct message response. |
+| | Further FF-A v1.1 guidance about run time models |
+| | and partition states will be implemented in future |
+| | TF-A SPMC releases. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 09 |
++========================+====================================================+
+| ``Threat`` | **Probing the FF-A communication between |
+| | endpoints.** |
+| | SPMC and SPs are typically loaded to external |
+| | memory (protected by a TrustZone memory |
+| | controller). A malicious agent may use non invasive|
+| | methods to probe the external memory bus and |
+| | extract the traffic between an SP and the SPMC or |
+| | among SPs when shared buffers are held in external |
+| | memory. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF7 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SP/SPMC state, SP/SPMC secrets |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | Hardware attack |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Information disclosure |
++------------------------+------------------+-----------------+---------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+-----------------+---------------+
+| ``Impact`` | Medium (3) | Medium (3) | |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood`` | Low (2) | Medium (3) | |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating`` | Medium (6) | Medium (9) | |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations`` | It is expected the platform or chipset provides |
+| | guarantees in protecting the DRAM contents. |
+| | The TF-A SPMC does not mitigate this class of |
+| | attack and this is left to the integrator. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 10 |
++========================+====================================================+
+| ``Threat`` | **A malicious agent may attempt revealing the SPMC |
+| | state or secrets by the use of software-based cache|
+| | side-channel attack techniques.** |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF7 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SP or SPMC state |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Information disclosure |
++------------------------+------------------+-----------------+---------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+-----------------+---------------+
+| ``Impact`` | Medium (3) | Medium (3) | |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood`` | Low (2) | Low (2) | |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating`` | Medium (6) | Medium (6) | |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations`` | From an integration perspective it is assumed |
+| | platforms consuming the SPMC component at S-EL2 |
+| | (hence implementing the Armv8.4 FEAT_SEL2 |
+| | architecture extension) implement mitigations to |
+| | Spectre, Meltdown or other cache timing |
+| | side-channel type of attacks. |
+| | The TF-A SPMC implements one mitigation (barrier |
+| | preventing speculation past exeception returns). |
+| | The SPMC may be hardened further with SW |
+| | mitigations (e.g. speculation barriers) for the |
+| | cases not covered in HW. Usage of hardened |
+| | compilers and appropriate options, code inspection |
+| | are recommended ways to mitigate Spectre types of |
+| | attacks. For non-hardened cores, the usage of |
+| | techniques such a kernel page table isolation can |
+| | help mitigating Meltdown type of attacks. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID | 11 |
++========================+====================================================+
+| ``Threat`` | **A malicious endpoint may attempt flooding the |
+| | SPMC with requests targetting a service within an |
+| | endpoint such that it denies another endpoint to |
+| | access this service.** |
+| | Similarly, the malicious endpoint may target a |
+| | a service within an endpoint such that the latter |
+| | is unable to request services from another |
+| | endpoint. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements`` | DF1, DF2, DF3, DF4 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A | SPMC |
+| Components`` | |
++------------------------+----------------------------------------------------+
+| ``Assets`` | SPMC state |
++------------------------+----------------------------------------------------+
+| ``Threat Agent`` | NS-Endpoint, S-Endpoint |
++------------------------+----------------------------------------------------+
+| ``Threat Type`` | Denial of service |
++------------------------+------------------+-----------------+---------------+
+| ``Application`` | ``Server`` | ``Mobile`` | |
++------------------------+------------------+-----------------+---------------+
+| ``Impact`` | Medium (3) | Medium (3) | |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood`` | Medium (3) | Medium (3) | |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating`` | Medium (9) | Medium (9) | |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations`` | The TF-A SPMC does not mitigate this threat. |
+| | Bounding the time for operations to complete can |
+| | be achieved by the usage of a trusted watchdog. |
+| | Other quality of service monitoring can be achieved|
+| | in the SPMC such as counting a number of operations|
+| | in a limited timeframe. |
++------------------------+----------------------------------------------------+
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
+
+.. _Arm Firmware Framework for Armv8-A: 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/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/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/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/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/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index 44c540c..8b011aa 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,10 @@
#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)
+
#endif /* CORTEX_A710_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78_ae.h b/include/lib/cpus/aarch64/cortex_a78_ae.h
index 24ae7ee..0c8adcf 100644
--- a/include/lib/cpus/aarch64/cortex_a78_ae.h
+++ b/include/lib/cpus/aarch64/cortex_a78_ae.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,4 +12,10 @@
#define CORTEX_A78_AE_MIDR U(0x410FD420)
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A78_AE_CPUECTLR_EL1 CORTEX_A78_CPUECTLR_EL1
+#define CORTEX_A78_AE_CPUECTLR_EL1_BIT_8 CORTEX_A78_CPUECTLR_EL1_BIT_8
+
#endif /* CORTEX_A78_AE_H */
diff --git a/include/lib/cpus/aarch64/cortex_demeter.h b/include/lib/cpus/aarch64/cortex_demeter.h
new file mode 100644
index 0000000..9dd0987
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_demeter.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_DEMETER_H
+#define CORTEX_DEMETER_H
+
+#define CORTEX_DEMETER_MIDR U(0x410FD4F0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_DEMETER_CPUECTLR_EL1 S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_DEMETER_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+
+#endif /* CORTEX_DEMETER_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index 7cbd8c1..948f965 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
*/
@@ -21,11 +21,24 @@
******************************************************************************/
#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_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)
+
#endif /* NEOVERSE_N2_H */
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index 5426135..3d57a5c 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -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
*/
@@ -125,7 +125,7 @@
#if ENABLE_PAUTH
CASSERT(CPU_DATA_APIAKEY_OFFSET == __builtin_offsetof
(cpu_data_t, apiakey),
- assert_cpu_data_crash_stack_offset_mismatch);
+ assert_cpu_data_pauth_stack_offset_mismatch);
#endif
#if CRASH_REPORTING
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 4f979f8..75b7647 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -21,6 +21,145 @@
#error "Cortex A710 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+/* --------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 1987031.
+ * This applies to revision r0p0, r1p0 and r2p0 of Cortex-A710. It is still
+ * open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a710_1987031_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_1987031
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ ldr x0,=0x6
+ 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,=0x40000001003ff
+ msr S3_6_c15_c8_1,x0
+ ldr x0,=0x7
+ 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,=0x40000001003f3
+ msr S3_6_c15_c8_1,x0
+ isb
+1:
+ ret x17
+endfunc errata_a710_1987031_wa
+
+func check_errata_1987031
+ /* Applies to r0p0, r1p0 and r2p0 */
+ mov x1, #0x20
+ b cpu_rev_var_ls
+endfunc check_errata_1987031
+
+/* --------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2081180.
+ * This applies to revision r0p0, r1p0 and r2p0 of Cortex-A710.
+ * It is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a710_2081180_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2081180
+ 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_a710_2081180_wa
+
+func check_errata_2081180
+ /* Applies to r0p0, r1p0 and r2p0 */
+ mov x1, #0x20
+ 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
+
/* ----------------------------------------------------
* HW will do the cache maintenance while powering down
* ----------------------------------------------------
@@ -37,20 +176,60 @@
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]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata ERRATA_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
+
+ ldp x8, x30, [sp], #16
ret
endfunc cortex_a710_errata_report
#endif
func cortex_a710_reset_func
+ mov x19, x30
+
/* Disable speculative loads */
msr SSBS, xzr
+
+ bl cpu_get_rev_var
+ mov x18, x0
+
+#if ERRATA_A710_1987031
+ mov x0, x18
+ bl errata_a710_1987031_wa
+#endif
+
+#if ERRATA_A710_2081180
+ mov x0, x18
+ 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
isb
- ret
+ ret x19
endfunc cortex_a710_reset_func
/* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 8c5a45a..3a74571 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -154,6 +154,50 @@
b cpu_rev_var_ls
endfunc check_errata_1821534
+/* --------------------------------------------------
+ * Errata Workaround for Cortex A78 Errata 1952683.
+ * This applies to revision r0p0.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_1952683_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_1952683
+ cbz x0, 1f
+
+ ldr x0,=0x5
+ msr S3_6_c15_c8_0,x0
+ ldr x0,=0xEEE10A10
+ msr S3_6_c15_c8_2,x0
+ ldr x0,=0xFFEF0FFF
+ msr S3_6_c15_c8_3,x0
+ ldr x0,=0x0010F000
+ msr S3_6_c15_c8_4,x0
+ ldr x0,=0x0010F000
+ msr S3_6_c15_c8_5,x0
+ ldr x0,=0x40000080023ff
+ msr S3_6_c15_c8_1,x0
+ ldr x0,=0x6
+ msr S3_6_c15_c8_0,x0
+ ldr x0,=0xEE640F34
+ msr S3_6_c15_c8_2,x0
+ ldr x0,=0xFFEF0FFF
+ msr S3_6_c15_c8_3,x0
+ ldr x0,=0x40000080023ff
+ msr S3_6_c15_c8_1,x0
+ isb
+1:
+ ret x17
+endfunc errata_a78_1952683_wa
+
+func check_errata_1952683
+ /* Applies to r0p0 only */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_1952683
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A78
* -------------------------------------------------
@@ -183,6 +227,11 @@
bl errata_a78_1821534_wa
#endif
+#if ERRATA_A78_1952683
+ mov x0, x18
+ bl errata_a78_1952683_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
@@ -241,6 +290,7 @@
report_errata ERRATA_A78_1941498, cortex_a78, 1941498
report_errata ERRATA_A78_1951500, cortex_a78, 1951500
report_errata ERRATA_A78_1821534, cortex_a78, 1821534
+ report_errata ERRATA_A78_1952683, cortex_a78, 1952683
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index 9aff9ac..421c174 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,12 +17,108 @@
#error "cortex_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif
+/* --------------------------------------------------
+ * Errata Workaround for A78 AE Erratum 1941500.
+ * This applies to revisions r0p0 and r0p1 of A78 AE.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_ae_1941500_wa
+ /* Compare x0 against revisions r0p0 - r0p1 */
+ mov x17, x30
+ bl check_errata_1941500
+ cbz x0, 1f
+
+ /* Set bit 8 in ECTLR_EL1 */
+ mrs x0, CORTEX_A78_AE_CPUECTLR_EL1
+ bic x0, x0, #CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
+ msr CORTEX_A78_AE_CPUECTLR_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_a78_ae_1941500_wa
+
+func check_errata_1941500
+ /* Applies to revisions r0p0 and r0p1. */
+ mov x1, #CPU_REV(0, 0)
+ mov x2, #CPU_REV(0, 1)
+ b cpu_rev_var_range
+endfunc check_errata_1941500
+
+/* --------------------------------------------------
+ * Errata Workaround for A78 AE Erratum 1951502.
+ * This applies to revisions r0p0 and r0p1 of A78 AE.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_ae_1951502_wa
+ /* Compare x0 against revisions r0p0 - r0p1 */
+ mov x17, x30
+ bl check_errata_1951502
+ cbz x0, 1f
+
+ msr S3_6_c15_c8_0, xzr
+ ldr x0, =0x10E3900002
+ msr S3_6_c15_c8_2, x0
+ ldr x0, =0x10FFF00083
+ msr S3_6_c15_c8_3, x0
+ ldr x0, =0x2001003FF
+ msr S3_6_c15_c8_1, x0
+
+ mov x0, #1
+ msr S3_6_c15_c8_0, x0
+ ldr x0, =0x10E3800082
+ msr S3_6_c15_c8_2, x0
+ ldr x0, =0x10FFF00083
+ msr S3_6_c15_c8_3, x0
+ ldr x0, =0x2001003FF
+ msr S3_6_c15_c8_1, x0
+
+ mov x0, #2
+ msr S3_6_c15_c8_0, x0
+ ldr x0, =0x10E3800200
+ msr S3_6_c15_c8_2, x0
+ ldr x0, =0x10FFF003E0
+ msr S3_6_c15_c8_3, x0
+ ldr x0, =0x2001003FF
+ msr S3_6_c15_c8_1, x0
+
+ isb
+1:
+ ret x17
+endfunc errata_a78_ae_1951502_wa
+
+func check_errata_1951502
+ /* Applies to revisions r0p0 and r0p1. */
+ mov x1, #CPU_REV(0, 0)
+ mov x2, #CPU_REV(0, 1)
+ b cpu_rev_var_range
+endfunc check_errata_1951502
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A78-AE
* -------------------------------------------------
*/
-#if ENABLE_AMU
func cortex_a78_ae_reset_func
+ mov x19, x30
+ bl cpu_get_rev_var
+ mov x18, x0
+
+#if ERRATA_A78_AE_1941500
+ mov x0, x18
+ bl errata_a78_ae_1941500_wa
+#endif
+
+#if ERRATA_A78_AE_1951502
+ mov x0, x18
+ bl errata_a78_ae_1951502_wa
+#endif
+
+#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
@@ -39,11 +136,12 @@
/* Enable group1 counters */
mov x0, #CORTEX_A78_AMU_GROUP1_MASK
msr CPUAMCNTENSET1_EL0, x0
+#endif
+
isb
- ret
+ ret x19
endfunc cortex_a78_ae_reset_func
-#endif
/* -------------------------------------------------------
* HW will do the cache maintenance while powering down
@@ -66,6 +164,19 @@
*/
#if REPORT_ERRATA
func cortex_a78_ae_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500
+ report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502
+
+ ldp x8, x30, [sp], #16
ret
endfunc cortex_a78_ae_errata_report
#endif
@@ -89,12 +200,6 @@
ret
endfunc cortex_a78_ae_cpu_reg_dump
-#if ENABLE_AMU
-#define A78_AE_RESET_FUNC cortex_a78_ae_reset_func
-#else
-#define A78_AE_RESET_FUNC CPU_NO_RESET_FUNC
-#endif
-
declare_cpu_ops cortex_a78_ae, CORTEX_A78_AE_MIDR, \
- A78_AE_RESET_FUNC, \
+ cortex_a78_ae_reset_func, \
cortex_a78_ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_demeter.S b/lib/cpus/aarch64/cortex_demeter.S
new file mode 100644
index 0000000..9ad8b86
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_demeter.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_demeter.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex Demeter must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex Demeter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+ /* ----------------------------------------------------
+ * HW will do the cache maintenance while powering down
+ * ----------------------------------------------------
+ */
+func cortex_demeter_core_pwr_dwn
+ /* ---------------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------------
+ */
+ mrs x0, CORTEX_DEMETER_CPUPWRCTLR_EL1
+ orr x0, x0, #CORTEX_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+ msr CORTEX_DEMETER_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+endfunc cortex_demeter_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Demeter. Must follow AAPCS.
+ */
+func cortex_demeter_errata_report
+ ret
+endfunc cortex_demeter_errata_report
+#endif
+
+func cortex_demeter_reset_func
+ /* Disable speculative loads */
+ msr SSBS, xzr
+ isb
+ ret
+endfunc cortex_demeter_reset_func
+
+ /* ---------------------------------------------
+ * This function provides Cortex Demeter-
+ * 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_demeter_regs, "aS"
+cortex_demeter_regs: /* The ascii list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func cortex_demeter_cpu_reg_dump
+ adr x6, cortex_demeter_regs
+ mrs x8, CORTEX_DEMETER_CPUECTLR_EL1
+ ret
+endfunc cortex_demeter_cpu_reg_dump
+
+declare_cpu_ops cortex_demeter, CORTEX_DEMETER_MIDR, \
+ cortex_demeter_reset_func, \
+ cortex_demeter_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 8d646cb..9e7bbf7 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
*/
@@ -19,11 +19,177 @@
#error "Neoverse-N2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
- /* -------------------------------------------------
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2002655.
+ * 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_2002655_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2002655
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ ldr x0,=0x6
+ 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,=0x40000001003ff
+ msr S3_6_c15_c8_1,x0
+ ldr x0,=0x7
+ 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,=0x40000001003f3
+ msr S3_6_c15_c8_1,x0
+ isb
+1:
+ ret x17
+endfunc errata_n2_2002655_wa
+
+func check_errata_2002655
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ 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
+
+ /* -------------------------------------------
* The CPU Ops reset function for Neoverse N2.
- * -------------------------------------------------
+ * -------------------------------------------
*/
func neoverse_n2_reset_func
+ mov x19, x30
+
/* Check if the PE implements SSBS */
mrs x0, id_aa64pfr1_el1
tst x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT)
@@ -37,6 +203,27 @@
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 ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, cptr_el3
@@ -53,20 +240,28 @@
#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
+ mov x18, x0
+
+#if ERRATA_N2_2002655
+ mov x0, x18
+ bl errata_n2_2002655_wa
#endif
isb
- ret
+ 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
@@ -80,7 +275,22 @@
* Errata printing function for Neoverse N2 cores. Must follow AAPCS.
*/
func neoverse_n2_errata_report
- /* No errata reported for Neoverse N2 cores */
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata ERRATA_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
+
+ ldp x8, x30, [sp], #16
ret
endfunc neoverse_n2_errata_report
#endif
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 050a56e..6103a5a 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,6 +1,6 @@
#
# Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+# Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -311,10 +311,22 @@
# well but there is no workaround for that revision.
ERRATA_A78_1951500 ?=0
+# Flag to apply erratum 1941500 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_1941500 ?=0
+
+# Flag to apply erratum 1951502 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_1951502 ?=0
+
# Flag to apply erratum 1821534 workaround during reset. This erratum applies
# to revisions r0p0 and r1p0 of the A78 cpu.
ERRATA_A78_1821534 ?=0
+# Flag to apply erratum 1952683 workaround during reset. This erratum applies
+# to revision r0p0 of the A78 cpu and was fixed in the revision r1p0.
+ERRATA_A78_1952683 ?=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
@@ -372,6 +384,10 @@
# exists in revisions r0p0, r1p0, and r2p0 as well but there is no workaround.
ERRATA_N1_1946160 ?=0
+# Flag to apply erratum 2002655 workaround during reset. This erratum applies
+# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
+ERRATA_N2_2002655 ?=0
+
# Flag to apply erratum 1774420 workaround during reset. This erratum applies
# to revisions r0p0 and r1p0 of the Neoverse V1 core, and was fixed in r1p1.
ERRATA_V1_1774420 ?=0
@@ -401,6 +417,38 @@
# to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
ERRATA_V1_2139242 ?=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.
+ERRATA_A710_1987031 ?=0
+
+# Flag to apply erratum 2081180 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
+ERRATA_A710_2081180 ?=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 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
@@ -646,10 +694,22 @@
$(eval $(call assert_boolean,ERRATA_A78_1951500))
$(eval $(call add_define,ERRATA_A78_1951500))
+# Process ERRATA_A78_AE_1941500 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
+$(eval $(call add_define,ERRATA_A78_AE_1941500))
+
+# Process ERRATA_A78_AE_1951502 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
+$(eval $(call add_define,ERRATA_A78_AE_1951502))
+
# Process ERRATA_A78_1821534 flag
$(eval $(call assert_boolean,ERRATA_A78_1821534))
$(eval $(call add_define,ERRATA_A78_1821534))
+# Process ERRATA_A78_1952683 flag
+$(eval $(call assert_boolean,ERRATA_A78_1952683))
+$(eval $(call add_define,ERRATA_A78_1952683))
+
# Process ERRATA_N1_1043202 flag
$(eval $(call assert_boolean,ERRATA_N1_1043202))
$(eval $(call add_define,ERRATA_N1_1043202))
@@ -706,6 +766,10 @@
$(eval $(call assert_boolean,ERRATA_N1_1946160))
$(eval $(call add_define,ERRATA_N1_1946160))
+# Process ERRATA_N2_2002655 flag
+$(eval $(call assert_boolean,ERRATA_N2_2002655))
+$(eval $(call add_define,ERRATA_N2_2002655))
+
# Process ERRATA_V1_1774420 flag
$(eval $(call assert_boolean,ERRATA_V1_1774420))
$(eval $(call add_define,ERRATA_V1_1774420))
@@ -734,6 +798,38 @@
$(eval $(call assert_boolean,ERRATA_V1_2139242))
$(eval $(call add_define,ERRATA_V1_2139242))
+# Process ERRATA_A710_1987031 flag
+$(eval $(call assert_boolean,ERRATA_A710_1987031))
+$(eval $(call add_define,ERRATA_A710_1987031))
+
+# Process ERRATA_A710_2081180 flag
+$(eval $(call assert_boolean,ERRATA_A710_2081180))
+$(eval $(call add_define,ERRATA_A710_2081180))
+
+# 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_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/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 56a2ad6..49951e0 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -25,7 +25,8 @@
#else /* !SUNXI_BL31_IN_DRAM */
-#define BL31_BASE (SUNXI_SRAM_A2_BASE + 0x4000)
+#define BL31_BASE (SUNXI_SRAM_A2_BASE + \
+ SUNXI_SRAM_A2_BL31_OFFSET)
#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + \
SUNXI_SRAM_A2_SIZE - SUNXI_SCP_SIZE)
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index f036816..ec50887 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -18,5 +18,6 @@
#define SUNXI_SOC_H5 0x1718
#define SUNXI_SOC_H6 0x1728
#define SUNXI_SOC_H616 0x1823
+#define SUNXI_SOC_R329 0x1851
#endif /* SUNXI_DEF_H */
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 72bfbd9..14049e8 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -128,6 +128,9 @@
case SUNXI_SOC_H616:
soc_name = "H616";
break;
+ case SUNXI_SOC_R329:
+ soc_name = "R329";
+ break;
default:
soc_name = "unknown";
break;
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index 420b507..46e7090 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -42,6 +42,7 @@
mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xe0);
mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x80);
mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00);
+ udelay(1);
}
/* We can't turn ourself off like this, but it works for other cores. */
@@ -75,7 +76,8 @@
/* Assert CPU power-on reset */
mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
/* Set CPU to start in AArch64 mode */
- mmio_setbits_32(SUNXI_CPUCFG_CLS_CTRL_REG0(cluster), BIT(24 + core));
+ mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
+ BIT(SUNXI_AA64nAA32_OFFSET + core));
/* Apply power to the CPU */
sunxi_cpu_enable_power(cluster, core);
/* Release the core output clamps */
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
index c3eeadb..aed3585 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
@@ -33,4 +33,7 @@
#define SUNXI_R_CPUCFG_SS_ENTRY_REG (SUNXI_R_CPUCFG_BASE + 0x01a8)
#define SUNXI_R_CPUCFG_HP_FLAG_REG (SUNXI_R_CPUCFG_BASE + 0x01ac)
+#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET 24
+
#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
index 6c847d3..6d10921 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
@@ -15,6 +15,7 @@
#define SUNXI_SRAM_A1_BASE 0x00010000
#define SUNXI_SRAM_A1_SIZE 0x00008000
#define SUNXI_SRAM_A2_BASE 0x00040000
+#define SUNXI_SRAM_A2_BL31_OFFSET 0x00004000
#define SUNXI_SRAM_A2_SIZE 0x00014000
#define SUNXI_SRAM_C_BASE 0x00018000
#define SUNXI_SRAM_C_SIZE 0x0001c000
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
index a2b94af..5bfda5d 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
@@ -29,4 +29,7 @@
#define SUNXI_PWR_SW_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0140)
#define SUNXI_CONFIG_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0144)
+#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET 24
+
#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index 2d7b098..58216d8 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -15,6 +15,7 @@
#define SUNXI_SRAM_A1_BASE 0x00020000
#define SUNXI_SRAM_A1_SIZE 0x00008000
#define SUNXI_SRAM_A2_BASE 0x00100000
+#define SUNXI_SRAM_A2_BL31_OFFSET 0x00004000
#define SUNXI_SRAM_A2_SIZE 0x00018000
#define SUNXI_SRAM_C_BASE 0x00028000
#define SUNXI_SRAM_C_SIZE 0x0001e000
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
index a637554..dab663b 100644
--- a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
@@ -29,4 +29,7 @@
#define SUNXI_PWR_SW_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0140)
#define SUNXI_CONFIG_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0144)
+#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET 24
+
#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_ccu.h b/plat/allwinner/sun50i_r329/include/sunxi_ccu.h
new file mode 100644
index 0000000..0e6b543
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/include/sunxi_ccu.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CCU_H
+#define SUNXI_CCU_H
+
+#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0x0f00)
+
+#define SUNXI_R_PRCM_SEC_SWITCH_REG (SUNXI_R_PRCM_BASE + 0x0290)
+
+#endif /* SUNXI_CCU_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
new file mode 100644
index 0000000..9478f32
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c) (SUNXI_C0_CPUXCFG_BASE + 0x0010)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c) (SUNXI_C0_CPUXCFG_BASE + 0x0014)
+#define SUNXI_CPUCFG_CACHE_CFG_REG (SUNXI_C0_CPUXCFG_BASE + 0x0024)
+#define SUNXI_CPUCFG_DBG_REG0 (SUNXI_C0_CPUXCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c) (SUNXI_C0_CPUXCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_GEN_CTRL_REG0(c) (SUNXI_CPUCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n) (SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n) (SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n) (SUNXI_R_CPUCFG_BASE + 0x0050 + \
+ (c) * 0x10 + (n) * 4)
+
+#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_GEN_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET 4
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_mmap.h b/plat/allwinner/sun50i_r329/include/sunxi_mmap.h
new file mode 100644
index 0000000..a4469b5
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/include/sunxi_mmap.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_MMAP_H
+#define SUNXI_MMAP_H
+
+/* Memory regions */
+#define SUNXI_ROM_BASE 0x00000000
+#define SUNXI_ROM_SIZE 0x00010000
+/*
+ * In fact all SRAM from 0x100000 is SRAM A2. However as it's too big for
+ * firmware, and the user manual gives a tip on a 2*64K/27*64K partition,
+ * only use the first 2*64K for firmwares now, with the SPL using the first
+ * 64K and BL3-1 using the second one.
+ *
+ * Only the used 2*64K SRAM is defined here, to prevent a gaint translation
+ * table to be generated.
+ */
+#define SUNXI_SRAM_BASE 0x00100000
+#define SUNXI_SRAM_SIZE 0x00020000
+#define SUNXI_SRAM_A1_BASE 0x00100000
+#define SUNXI_SRAM_A1_SIZE 0x00010000
+#define SUNXI_SRAM_A2_BASE 0x00110000
+#define SUNXI_SRAM_A2_BL31_OFFSET 0x00000000
+#define SUNXI_SRAM_A2_SIZE 0x00010000
+#define SUNXI_DEV_BASE 0x01000000
+#define SUNXI_DEV_SIZE 0x09000000
+#define SUNXI_DRAM_BASE 0x40000000
+#define SUNXI_DRAM_VIRT_BASE 0x0a000000
+
+/* Memory-mapped devices */
+#define SUNXI_WDOG_BASE 0x020000a0
+#define SUNXI_R_WDOG_BASE SUNXI_WDOG_BASE
+#define SUNXI_PIO_BASE 0x02000400
+#define SUNXI_SPC_BASE 0x02000800
+#define SUNXI_CCU_BASE 0x02001000
+#define SUNXI_UART0_BASE 0x02500000
+#define SUNXI_SYSCON_BASE 0x03000000
+#define SUNXI_DMA_BASE 0x03002000
+#define SUNXI_SID_BASE 0x03006000
+#define SUNXI_GICD_BASE 0x03021000
+#define SUNXI_GICC_BASE 0x03022000
+#define SUNXI_SPI0_BASE 0x04025000
+#define SUNXI_R_CPUCFG_BASE 0x07000400
+#define SUNXI_R_PRCM_BASE 0x07010000
+#define SUNXI_R_PIO_BASE 0x07022000
+#define SUNXI_R_UART_BASE 0x07080000
+#define SUNXI_R_I2C_BASE 0x07081400
+#define SUNXI_CPUCFG_BASE 0x08100000
+#define SUNXI_C0_CPUXCFG_BASE 0x09010000
+
+#endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_spc.h b/plat/allwinner/sun50i_r329/include/sunxi_spc.h
new file mode 100644
index 0000000..2c87bca
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/include/sunxi_spc.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_SPC_H
+#define SUNXI_SPC_H
+
+/* Get by REing stock ATF and checking initialization loop boundary */
+#define SUNXI_SPC_NUM_PORTS 11
+
+#define SUNXI_SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + 0x0000 + 0x10 * (p))
+#define SUNXI_SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + 0x0004 + 0x10 * (p))
+#define SUNXI_SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + 0x0008 + 0x10 * (p))
+
+#endif /* SUNXI_SPC_H */
diff --git a/plat/allwinner/sun50i_r329/platform.mk b/plat/allwinner/sun50i_r329/platform.mk
new file mode 100644
index 0000000..05d7cde
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/platform.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2021 Sipeed
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Without a management processor there is no SCPI support.
+SUNXI_PSCI_USE_SCPI := 0
+SUNXI_PSCI_USE_NATIVE := 1
+
+# The differences between the platforms are covered by the include files.
+include plat/allwinner/common/allwinner-common.mk
+
+# the above could be overwritten on the command line
+ifeq (${SUNXI_PSCI_USE_SCPI}, 1)
+ $(error "R329 does not support SCPI PSCI ops")
+endif
+
+# Put NOBITS memory in the first 64K of SRAM A2, overwriting U-Boot's SPL.
+SEPARATE_NOBITS_REGION := 1
diff --git a/plat/allwinner/sun50i_r329/sunxi_power.c b/plat/allwinner/sun50i_r329/sunxi_power.c
new file mode 100644
index 0000000..96a24d5
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/sunxi_power.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <sunxi_mmap.h>
+#include <sunxi_cpucfg.h>
+#include <sunxi_private.h>
+
+int sunxi_pmic_setup(uint16_t socid, const void *fdt)
+{
+ /* Currently known hardware has no PMIC */
+
+ return 0;
+}
+
+void sunxi_power_down(void)
+{
+}
+
+void sunxi_cpu_power_off_self(void)
+{
+ /* TODO: It's still unknown whether CPUIDLE exists on R329 */
+}
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index f1fd777..f80ea2f 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -32,6 +32,8 @@
FPGA_PRELOADED_CMD_LINE := 0x1000
$(eval $(call add_define,FPGA_PRELOADED_CMD_LINE))
+ENABLE_AMU := 1
+
# Treating this as a memory-constrained port for now
USE_COHERENT_MEM := 0
diff --git a/plat/arm/board/diphda/platform.mk b/plat/arm/board/diphda/platform.mk
index 5ff0862..8b89cee 100644
--- a/plat/arm/board/diphda/platform.mk
+++ b/plat/arm/board/diphda/platform.mk
@@ -59,6 +59,13 @@
${DIPHDA_CPU_LIBS} \
${DIPHDA_GIC_SOURCES}
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+ ifneq (${ENABLE_STACK_PROTECTOR},none)
+ DIPHDA_SECURITY_SOURCES := plat/arm/board/diphda/common/diphda_stack_protector.c
+ BL2_SOURCES += ${DIPHDA_SECURITY_SOURCES}
+ BL31_SOURCES += ${DIPHDA_SECURITY_SOURCES}
+ endif
+endif
FDT_SOURCES += plat/arm/board/diphda/common/fdts/diphda_spmc_manifest.dts
DIPHDA_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/diphda_spmc_manifest.dtb
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/platform.mk b/plat/arm/board/fvp/platform.mk
index 10258ad..3c70eed 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -135,6 +135,7 @@
lib/cpus/aarch64/cortex_a710.S \
lib/cpus/aarch64/cortex_makalu.S \
lib/cpus/aarch64/cortex_makalu_elp_arm.S \
+ lib/cpus/aarch64/cortex_demeter.S \
lib/cpus/aarch64/cortex_a65.S \
lib/cpus/aarch64/cortex_a65ae.S \
lib/cpus/aarch64/cortex_a78c.S
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/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/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/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk
index 773b912..30e6280 100644
--- a/plat/marvell/armada/a8k/common/a8k_common.mk
+++ b/plat/marvell/armada/a8k/common/a8k_common.mk
@@ -80,7 +80,7 @@
drivers/arm/gic/v2/gicv2_helpers.c \
plat/common/plat_gicv2.c
-PLAT_INCLUDES := -I$(BOARD_DIR) \
+PLAT_INCLUDES += -I$(BOARD_DIR) \
-I$(BOARD_DIR)/board \
-I$(CURDIR)/drivers/marvell \
-I$(PLAT_COMMON_BASE)/include \
@@ -89,8 +89,10 @@
PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a8k_common.c \
drivers/ti/uart/aarch64/16550_console.S
+ifndef BLE_PORTING_SOURCES
BLE_PORTING_SOURCES := $(BOARD_DIR)/board/dram_port.c \
$(BOARD_DIR)/board/marvell_plat_config.c
+endif
MARVELL_MOCHI_DRV += $(MARVELL_DRV_BASE)/mochi/cp110_setup.c
@@ -125,7 +127,9 @@
MARVELL_DRV += $(MARVELL_DRV_BASE)/mg_conf_cm3/mg_conf_cm3.c
endif
+ifndef BL31_PORTING_SOURCES
BL31_PORTING_SOURCES := $(BOARD_DIR)/board/marvell_plat_config.c
+endif
ifeq ($(SYSTEM_POWER_SUPPORT),1)
BL31_PORTING_SOURCES += $(BOARD_DIR)/board/system_power.c
diff --git a/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/board/marvell_plat_config.c b/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/board/marvell_plat_config.c
new file mode 100644
index 0000000..5bae8eb
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/board/marvell_plat_config.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ * Copyright (C) 2021 Semihalf.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <armada_common.h>
+#include <mvebu_def.h>
+
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map_cp0[] = {
+ /* CP0 SPI1 CS0 Direct Mode access */
+ {0xef00, 0x1000000, AMB_SPI1_CS0_ID},
+};
+
+struct addr_map_win amb_memory_map_cp1[] = {
+ /* CP1 SPI1 CS0 Direct Mode access */
+ {0xe800, 0x1000000, AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ switch (base) {
+ case MVEBU_CP_REGS_BASE(0):
+ *win = amb_memory_map_cp0;
+ *size = ARRAY_SIZE(amb_memory_map_cp0);
+ return 0;
+ case MVEBU_CP_REGS_BASE(1):
+ *win = amb_memory_map_cp1;
+ *size = ARRAY_SIZE(amb_memory_map_cp1);
+ return 0;
+ case MVEBU_CP_REGS_BASE(2):
+ default:
+ *size = 0;
+ *win = 0;
+ return 1;
+ }
+}
+#endif
+
+/*****************************************************************************
+ * IO WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+#if (CP_COUNT > 1)
+ /* SB (MCi0) internal regs */
+ {0x00000000f4000000, 0x2000000, MCI_0_TID},
+ /* SB (MCi0) PCIe0-2 on CP1 */
+ {0x00000000e2000000, 0x7000000, MCI_0_TID},
+ /*
+ * Due to lack of sufficient number of IO windows registers,
+ * below CP1 PCIE configuration must be performed in the
+ * later firmware stages. It should replace the MCI 0 indirect
+ * window, which becomes no longer needed.
+ */
+ /* {0x0000000890000000, 0x30000000, MCI_0_TID}, */
+#if (CP_COUNT > 2)
+ /* SB (MCi1) internal regs */
+ {0x00000000f6000000, 0x2000000, MCI_1_TID},
+ /* SB (MCi1) PCIe0-2 on CP2 */
+ {0x00000000e9000000, 0x6000000, MCI_1_TID},
+ /*
+ * Due to lack of sufficient number of IO windows registers,
+ * below CP2 PCIE configuration must be performed in the
+ * later firmware stages. It should replace the MCI 1 indirect
+ * window, which becomes no longer needed.
+ */
+ /* {0x00000008c0000000, 0x30000000, MCI_1_TID}, */
+#endif
+#endif
+#ifndef IMAGE_BLE
+ /* MCI 0 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID},
+ /* MCI 1 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID},
+#endif
+};
+
+/* Global Control Register - window default target */
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+ /*
+ * PIDI == iMCIP AP to SB internal MoChi connection.
+ * In other words CP0
+ */
+ return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = io_win_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(io_win_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map_cp0[] = {
+ /* SPI1_CS0 (RUNIT) window */
+ {0x00000000ef000000, 0x1000000, RUNIT_TID},
+ /* PEX2_X1 window */
+ {0x00000000e1000000, 0x1000000, PEX2_TID},
+ /* PEX1_X1 window */
+ {0x00000000e0000000, 0x1000000, PEX1_TID},
+ /* PEX0_X4 window */
+ {0x00000000c0000000, 0x20000000, PEX0_TID},
+ {0x0000000800000000, 0x90000000, PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp1[] = {
+ /* SPI1_CS0 (RUNIT) window */
+ {0x00000000e8000000, 0x1000000, RUNIT_TID},
+ /* PEX2_X1 window */
+ {0x00000000e6000000, 0x2000000, PEX2_TID},
+ {0x00000008b0000000, 0x10000000, PEX2_TID},
+ /* PEX1_X1 window */
+ {0x00000000e4000000, 0x2000000, PEX1_TID},
+ {0x00000008a0000000, 0x10000000, PEX1_TID},
+ /* PEX0_X2 window */
+ {0x00000000e2000000, 0x2000000, PEX0_TID},
+ {0x0000000890000000, 0x10000000, PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp2[] = {
+
+ /* PEX2_X1 window */
+ {0x00000000ed000000, 0x2000000, PEX2_TID},
+ {0x00000008e0000000, 0x10000000, PEX2_TID},
+ /* PEX1_X1 window */
+ {0x00000000eb000000, 0x2000000, PEX1_TID},
+ {0x00000008d0000000, 0x10000000, PEX1_TID},
+ /* PEX0_X1 window */
+ {0x00000000e9000000, 0x2000000, PEX0_TID},
+ {0x00000008c0000000, 0x10000000, PEX0_TID},
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ switch (base) {
+ case MVEBU_CP_REGS_BASE(0):
+ *win = iob_memory_map_cp0;
+ *size = ARRAY_SIZE(iob_memory_map_cp0);
+ return 0;
+ case MVEBU_CP_REGS_BASE(1):
+ *win = iob_memory_map_cp1;
+ *size = ARRAY_SIZE(iob_memory_map_cp1);
+ return 0;
+ case MVEBU_CP_REGS_BASE(2):
+ *win = iob_memory_map_cp2;
+ *size = ARRAY_SIZE(iob_memory_map_cp2);
+ return 0;
+ default:
+ *size = 0;
+ *win = 0;
+ return 1;
+ }
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = { /* IO window */
+#ifdef IMAGE_BLE
+ {0x00000000f2000000, 0x6000000, IO_0_TID}, /* IO window */
+#else
+#if LLC_SRAM
+ {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
+ {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */
+ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
+ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */
+ {0x0000002000000000, 0x70e000000, IO_0_TID}, /* IO for CV-OS */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+ return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = ccu_memory_map;
+ *size = ARRAY_SIZE(ccu_memory_map);
+
+ return 0;
+}
+
+#ifdef IMAGE_BLE
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+void *plat_get_skip_image_data(void)
+{
+ /* No recovery button on CN-9130 board? */
+ return NULL;
+}
+#endif
diff --git a/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/platform.mk b/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/platform.mk
new file mode 100644
index 0000000..ee55455
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/platform.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+# Copyright (C) 2021 Semihalf.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT := 0
+
+CP_NUM := 1
+$(eval $(call add_define,CP_NUM))
+
+DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg
+
+MARVELL_MOCHI_DRV := drivers/marvell/mochi/ap807_setup.c
+
+BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST)))
+
+#
+# CN913X CEx7 Evaluation Board shares the DRAM connectivity
+# and SerDes settings with the CN913X DB - reuse relevant
+# board-specific files.
+#
+T9130_DIR := $(BOARD_DIR)/../t9130
+PLAT_INCLUDES := -I$(T9130_DIR) \
+ -I$(T9130_DIR)/board
+BLE_PORTING_SOURCES := $(T9130_DIR)/board/dram_port.c \
+ $(BOARD_DIR)/board/marvell_plat_config.c
+
+include plat/marvell/armada/a8k/common/a8k_common.mk
+
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index 3894b74..f3aa3ea 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -82,13 +82,6 @@
return (tegra_get_chipid() >> PRE_SI_PLATFORM_SHIFT) & PRE_SI_PLATFORM_MASK;
}
-bool tegra_chipid_is_t132(void)
-{
- uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
-
- return (chip_id == TEGRA_CHIPID_TEGRA13);
-}
-
bool tegra_chipid_is_t186(void)
{
uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
deleted file mode 100644
index 6b87655..0000000
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TEGRA_DEF_H
-#define TEGRA_DEF_H
-
-#include <lib/utils_def.h>
-
-/*******************************************************************************
- * Platform BL31 specific defines.
- ******************************************************************************/
-#define BL31_SIZE U(0x40000)
-
-/*******************************************************************************
- * This value is used by the PSCI implementation during the `SYSTEM_SUSPEND`
- * call as the `state-id` field in the 'power state' parameter.
- ******************************************************************************/
-#define PSTATE_ID_SOC_POWERDN U(0xD)
-
-/*******************************************************************************
- * Platform power states (used by PSCI framework)
- *
- * - PLAT_MAX_RET_STATE should be less than lowest PSTATE_ID
- * - PLAT_MAX_OFF_STATE should be greater than the highest PSTATE_ID
- ******************************************************************************/
-#define PLAT_MAX_RET_STATE U(1)
-#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + U(1))
-
-/*******************************************************************************
- * Chip specific page table and MMU setup constants
- ******************************************************************************/
-#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 35)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 35)
-
-/*******************************************************************************
- * GIC memory map
- ******************************************************************************/
-#define TEGRA_GICD_BASE U(0x50041000)
-#define TEGRA_GICC_BASE U(0x50042000)
-
-/*******************************************************************************
- * Tegra micro-seconds timer constants
- ******************************************************************************/
-#define TEGRA_TMRUS_BASE U(0x60005010)
-#define TEGRA_TMRUS_SIZE U(0x1000)
-
-/*******************************************************************************
- * Tegra Clock and Reset Controller constants
- ******************************************************************************/
-#define TEGRA_CAR_RESET_BASE U(0x60006000)
-#define TEGRA_GPU_RESET_REG_OFFSET U(0x28C)
-#define TEGRA_GPU_RESET_GPU_SET_OFFSET U(0x290)
-#define GPU_RESET_BIT (U(1) << 24)
-#define GPU_SET_BIT (U(1) << 24)
-
-/*******************************************************************************
- * Tegra Flow Controller constants
- ******************************************************************************/
-#define TEGRA_FLOWCTRL_BASE U(0x60007000)
-
-/*******************************************************************************
- * Tegra Secure Boot Controller constants
- ******************************************************************************/
-#define TEGRA_SB_BASE U(0x6000C200)
-
-/*******************************************************************************
- * Tegra Exception Vectors constants
- ******************************************************************************/
-#define TEGRA_EVP_BASE U(0x6000F000)
-
-/*******************************************************************************
- * Tegra Miscellaneous register constants
- ******************************************************************************/
-#define TEGRA_MISC_BASE U(0x70000000)
-#define HARDWARE_REVISION_OFFSET U(0x804)
-
-/*******************************************************************************
- * Tegra UART controller base addresses
- ******************************************************************************/
-#define TEGRA_UARTA_BASE U(0x70006000)
-#define TEGRA_UARTB_BASE U(0x70006040)
-#define TEGRA_UARTC_BASE U(0x70006200)
-#define TEGRA_UARTD_BASE U(0x70006300)
-#define TEGRA_UARTE_BASE U(0x70006400)
-
-/*******************************************************************************
- * Tegra Power Mgmt Controller constants
- ******************************************************************************/
-#define TEGRA_PMC_BASE U(0x7000E400)
-
-/*******************************************************************************
- * Tegra Memory Controller constants
- ******************************************************************************/
-#define TEGRA_MC_BASE U(0x70019000)
-
-/* Memory Controller Interrupt Status */
-#define MC_INTSTATUS 0x00U
-
-/* TZDRAM carveout configuration registers */
-#define MC_SECURITY_CFG0_0 U(0x70)
-#define MC_SECURITY_CFG1_0 U(0x74)
-#define MC_SECURITY_CFG3_0 U(0x9BC)
-
-/* Video Memory carveout configuration registers */
-#define MC_VIDEO_PROTECT_BASE_HI U(0x978)
-#define MC_VIDEO_PROTECT_BASE_LO U(0x648)
-#define MC_VIDEO_PROTECT_SIZE_MB U(0x64c)
-#define MC_VIDEO_PROTECT_REG_CTRL U(0x650)
-#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3)
-
-/*******************************************************************************
- * Tegra TZRAM constants
- ******************************************************************************/
-#define TEGRA_TZRAM_BASE U(0x7C010000)
-#define TEGRA_TZRAM_SIZE U(0x10000)
-
-/*******************************************************************************
- * Tegra DRAM memory base address
- ******************************************************************************/
-#define TEGRA_DRAM_BASE ULL(0x80000000)
-#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
-
-#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index b8297fd..ab51dfe 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -49,7 +49,6 @@
/*
* Tegra chip ID identifiers
*/
-bool tegra_chipid_is_t132(void);
bool tegra_chipid_is_t186(void);
bool tegra_chipid_is_t210(void);
bool tegra_chipid_is_t210_b01(void);
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
deleted file mode 100644
index 0e2edf0..0000000
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/delay_timer.h>
-#include <denver.h>
-#include <lib/mmio.h>
-#include <lib/psci/psci.h>
-
-#include <flowctrl.h>
-#include <pmc.h>
-#include <tegra_def.h>
-#include <tegra_private.h>
-
-/*
- * Register used to clear CPU reset signals. Each CPU has two reset
- * signals: CPU reset (3:0) and Core reset (19:16)
- */
-#define CPU_CMPLX_RESET_CLR 0x344
-#define CPU_CORE_RESET_MASK 0x10001
-
-/* Clock and Reset controller registers for system clock's settings */
-#define SCLK_RATE 0x30
-#define SCLK_BURST_POLICY 0x28
-#define SCLK_BURST_POLICY_DEFAULT 0x10000000
-
-static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
-
-plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
- const plat_local_state_t *states,
- uint32_t ncpu)
-{
- plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
- uint32_t num_cpu = ncpu;
- const plat_local_state_t *local_state = states;
-
- (void)lvl;
-
- assert(ncpu != 0U);
-
- do {
- temp = *local_state;
- if ((temp < target)) {
- target = temp;
- }
- --num_cpu;
- local_state++;
- } while (num_cpu != 0U);
-
- return target;
-}
-
-int32_t tegra_soc_validate_power_state(unsigned int power_state,
- psci_power_state_t *req_state)
-{
- int state_id = psci_get_pstate_id(power_state);
- int cpu = read_mpidr() & MPIDR_CPU_MASK;
-
- /*
- * Sanity check the requested state id, power level and CPU number.
- * Currently T132 only supports SYSTEM_SUSPEND on last standing CPU
- * i.e. CPU 0
- */
- if ((state_id != PSTATE_ID_SOC_POWERDN) || (cpu != 0)) {
- ERROR("unsupported state id @ power level\n");
- return PSCI_E_INVALID_PARAMS;
- }
-
- /* Set lower power states to PLAT_MAX_OFF_STATE */
- for (uint32_t i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++)
- req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
-
- /* Set the SYSTEM_SUSPEND state-id */
- req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] =
- PSTATE_ID_SOC_POWERDN;
-
- return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_pwr_domain_on(u_register_t mpidr)
-{
- int cpu = mpidr & MPIDR_CPU_MASK;
- uint32_t mask = CPU_CORE_RESET_MASK << cpu;
-
- if (cpu_powergate_mask[cpu] == 0) {
-
- /* Deassert CPU reset signals */
- mmio_write_32(TEGRA_CAR_RESET_BASE + CPU_CMPLX_RESET_CLR, mask);
-
- /* Power on CPU using PMC */
- tegra_pmc_cpu_on(cpu);
-
- /* Fill in the CPU powergate mask */
- cpu_powergate_mask[cpu] = 1;
-
- } else {
- /* Power on CPU using Flow Controller */
- tegra_fc_cpu_on(cpu);
- }
-
- return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
- /*
- * Lock scratch registers which hold the CPU vectors
- */
- tegra_pmc_lock_cpu_vectors();
-
- return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
-{
- uint64_t val;
-
- tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
-
- /* Disable DCO operations */
- denver_disable_dco();
-
- /* Power down the CPU */
- val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
- write_actlr_el1(val | DENVER_CPU_STATE_POWER_DOWN);
-
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
-{
- (void)cpu_state;
- return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
- uint64_t val;
-
-#if ENABLE_ASSERTIONS
- int cpu = read_mpidr() & MPIDR_CPU_MASK;
-
- /* SYSTEM_SUSPEND only on CPU0 */
- assert(cpu == 0);
-#endif
-
- /* Allow restarting CPU #1 using PMC on suspend exit */
- cpu_powergate_mask[1] = 0;
-
- /* Program FC to enter suspend state */
- tegra_fc_cpu_powerdn(read_mpidr());
-
- /* Disable DCO operations */
- denver_disable_dco();
-
- /* Program the suspend state ID */
- val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
- write_actlr_el1(val | target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
-
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
-{
- return PSCI_E_NOT_SUPPORTED;
-}
-
-int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
-{
- return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_prepare_system_reset(void)
-{
- /*
- * Set System Clock (SCLK) to POR default so that the clock source
- * for the PMC APB clock would not be changed due to system reset.
- */
- mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY,
- SCLK_BURST_POLICY_DEFAULT);
- mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0);
-
- /* Wait 1 ms to make sure clock source/device logic is stabilized. */
- mdelay(1);
-
- /*
- * Program the PMC in order to restart the system.
- */
- tegra_pmc_system_reset();
-
- return PSCI_E_SUCCESS;
-}
-
-__dead2 void tegra_soc_prepare_system_off(void)
-{
- ERROR("Tegra System Off: operation not handled.\n");
- panic();
-}
diff --git a/plat/nvidia/tegra/soc/t132/plat_secondary.c b/plat/nvidia/tegra/soc/t132/plat_secondary.c
deleted file mode 100644
index f46ad3b..0000000
--- a/plat/nvidia/tegra/soc/t132/plat_secondary.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <denver.h>
-#include <lib/mmio.h>
-#include <lib/psci/psci.h>
-#include <plat/common/platform.h>
-
-#include <pmc.h>
-#include <tegra_def.h>
-
-#define SB_CSR 0x0
-#define SB_CSR_NS_RST_VEC_WR_DIS (1 << 1)
-
-/* AARCH64 CPU reset vector */
-#define SB_AA64_RESET_LOW 0x30 /* width = 31:0 */
-#define SB_AA64_RESET_HI 0x34 /* width = 11:0 */
-
-/* AARCH32 CPU reset vector */
-#define EVP_CPU_RESET_VECTOR 0x100
-
-extern void tegra_secure_entrypoint(void);
-
-/*
- * For T132, CPUs reset to AARCH32, so the reset vector is first
- * armv8_trampoline which does a warm reset to AARCH64 and starts
- * execution at the address in SB_AA64_RESET_LOW/SB_AA64_RESET_HI.
- */
-__aligned(8) const uint32_t armv8_trampoline[] = {
- 0xE3A00003, /* mov r0, #3 */
- 0xEE0C0F50, /* mcr p15, 0, r0, c12, c0, 2 */
- 0xEAFFFFFE, /* b . */
-};
-
-/*******************************************************************************
- * Setup secondary CPU vectors
- ******************************************************************************/
-void plat_secondary_setup(void)
-{
- uint32_t val;
- uint64_t reset_addr = (uint64_t)tegra_secure_entrypoint;
-
- /*
- * For T132, CPUs reset to AARCH32, so the reset vector is first
- * armv8_trampoline, which does a warm reset to AARCH64 and starts
- * execution at the address in SCRATCH34/SCRATCH35.
- */
- INFO("Setting up T132 CPU boot\n");
-
- /* initial AARCH32 reset address */
- tegra_pmc_write_32(PMC_SECURE_SCRATCH22,
- (unsigned long)&armv8_trampoline);
-
- /* set AARCH32 exception vector (read to flush) */
- mmio_write_32(TEGRA_EVP_BASE + EVP_CPU_RESET_VECTOR,
- (unsigned long)&armv8_trampoline);
- val = mmio_read_32(TEGRA_EVP_BASE + EVP_CPU_RESET_VECTOR);
-
- /* setup secondary CPU vector */
- mmio_write_32(TEGRA_SB_BASE + SB_AA64_RESET_LOW,
- (reset_addr & 0xFFFFFFFF) | 1);
- val = reset_addr >> 32;
- mmio_write_32(TEGRA_SB_BASE + SB_AA64_RESET_HI, val & 0x7FF);
-
- /* configure PMC */
- tegra_pmc_cpu_setup(reset_addr);
- tegra_pmc_lock_cpu_vectors();
-}
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
deleted file mode 100644
index 49e8b5d..0000000
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <common/bl_common.h>
-#include <drivers/console.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <memctrl.h>
-#include <plat/common/platform.h>
-#include <tegra_def.h>
-#include <tegra_platform.h>
-#include <tegra_private.h>
-
-/* sets of MMIO ranges setup */
-#define MMIO_RANGE_0_ADDR 0x50000000
-#define MMIO_RANGE_1_ADDR 0x60000000
-#define MMIO_RANGE_2_ADDR 0x70000000
-#define MMIO_RANGE_SIZE 0x200000
-
-/*
- * Table of regions to map using the MMU.
- */
-static const mmap_region_t tegra_mmap[] = {
- MAP_REGION_FLAT(MMIO_RANGE_0_ADDR, MMIO_RANGE_SIZE,
- MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(MMIO_RANGE_1_ADDR, MMIO_RANGE_SIZE,
- MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(MMIO_RANGE_2_ADDR, MMIO_RANGE_SIZE,
- MT_DEVICE | MT_RW | MT_SECURE),
- {0}
-};
-
-/*******************************************************************************
- * Set up the pagetables as per the platform memory map & initialize the MMU
- ******************************************************************************/
-const mmap_region_t *plat_get_mmio_map(void)
-{
- /* MMIO space */
- return tegra_mmap;
-}
-
-/*******************************************************************************
- * The Tegra power domain tree has a single system level power domain i.e. a
- * single root node. The first entry in the power domain descriptor specifies
- * the number of power domains at the highest power level.
- *******************************************************************************
- */
-const unsigned char tegra_power_domain_tree_desc[] = {
- /* No of root nodes */
- 1,
- /* No of clusters */
- PLATFORM_CLUSTER_COUNT,
- /* No of CPU cores */
- PLATFORM_CORE_COUNT,
-};
-
-/*******************************************************************************
- * This function returns the Tegra default topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
- return tegra_power_domain_tree_desc;
-}
-
-unsigned int plat_get_syscnt_freq2(void)
-{
- return 12000000;
-}
-
-/*******************************************************************************
- * Maximum supported UART controllers
- ******************************************************************************/
-#define TEGRA132_MAX_UART_PORTS 5
-
-/*******************************************************************************
- * This variable holds the UART port base addresses
- ******************************************************************************/
-static uint32_t tegra132_uart_addresses[TEGRA132_MAX_UART_PORTS + 1] = {
- 0, /* undefined - treated as an error case */
- TEGRA_UARTA_BASE,
- TEGRA_UARTB_BASE,
- TEGRA_UARTC_BASE,
- TEGRA_UARTD_BASE,
- TEGRA_UARTE_BASE,
-};
-
-/*******************************************************************************
- * Enable console corresponding to the console ID
- ******************************************************************************/
-void plat_enable_console(int32_t id)
-{
- static console_t uart_console;
- uint32_t console_clock;
-
- if ((id > 0) && (id < TEGRA132_MAX_UART_PORTS)) {
- /*
- * Reference clock used by the FPGAs is a lot slower.
- */
- if (tegra_platform_is_fpga()) {
- console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
- } else {
- console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
- }
-
- (void)console_16550_register(tegra132_uart_addresses[id],
- console_clock,
- TEGRA_CONSOLE_BAUDRATE,
- &uart_console);
- console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
- CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
- }
-}
-
-/*******************************************************************************
- * Initialize the GIC and SGIs
- ******************************************************************************/
-void plat_gic_setup(void)
-{
- tegra_gic_setup(NULL, 0);
- tegra_gic_init();
-}
-
-/*******************************************************************************
- * Return pointer to the BL31 params from previous bootloader
- ******************************************************************************/
-struct tegra_bl31_params *plat_get_bl31_params(void)
-{
- return NULL;
-}
-
-/*******************************************************************************
- * Return pointer to the BL31 platform params from previous bootloader
- ******************************************************************************/
-plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
-{
- return NULL;
-}
-
-/*******************************************************************************
- * Handler for early platform setup
- ******************************************************************************/
-void plat_early_platform_setup(void)
-{
- plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
-
- /* Verify chip id is t132 */
- assert(tegra_chipid_is_t132());
-
- /*
- * Do initial security configuration to allow DRAM/device access.
- */
- tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
- (uint32_t)plat_params->tzdram_size);
-}
-
-/*******************************************************************************
- * Handler for late platform setup
- ******************************************************************************/
-void plat_late_platform_setup(void)
-{
- ; /* do nothing */
-}
-
-/*******************************************************************************
- * Handler to indicate support for System Suspend
- ******************************************************************************/
-bool plat_supports_system_suspend(void)
-{
- return true;
-}
-
-/*******************************************************************************
- * Platform specific runtime setup.
- ******************************************************************************/
-void plat_runtime_setup(void)
-{
- /*
- * During cold boot, it is observed that the arbitration
- * bit is set in the Memory controller leading to false
- * error interrupts in the non-secure world. To avoid
- * this, clean the interrupt status register before
- * booting into the non-secure world
- */
- tegra_memctrl_clear_pending_interrupts();
-
- /*
- * During boot, USB3 and flash media (SDMMC/SATA) devices need
- * access to IRAM. Because these clients connect to the MC and
- * do not have a direct path to the IRAM, the MC implements AHB
- * redirection during boot to allow path to IRAM. In this mode
- * accesses to a programmed memory address aperture are directed
- * to the AHB bus, allowing access to the IRAM. This mode must be
- * disabled before we jump to the non-secure world.
- */
- tegra_memctrl_disable_ahb_redirection();
-}
diff --git a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c b/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
deleted file mode 100644
index 90c6bb2..0000000
--- a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <lib/el3_runtime/context_mgmt.h>
-
-#include <tegra_private.h>
-
-#define NS_SWITCH_AARCH32 1
-#define SCR_RW_BITPOS __builtin_ctz(SCR_RW_BIT)
-
-/*******************************************************************************
- * Tegra132 SiP SMCs
- ******************************************************************************/
-#define TEGRA_SIP_AARCH_SWITCH 0x82000004
-
-/*******************************************************************************
- * SPSR settings for AARCH32/AARCH64 modes
- ******************************************************************************/
-#define SPSR32 SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, \
- DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT)
-#define SPSR64 SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS)
-
-/*******************************************************************************
- * This function is responsible for handling all T132 SiP calls
- ******************************************************************************/
-int plat_sip_handler(uint32_t smc_fid,
- uint64_t x1,
- uint64_t x2,
- uint64_t x3,
- uint64_t x4,
- const void *cookie,
- void *handle,
- uint64_t flags)
-{
- switch (smc_fid) {
-
- case TEGRA_SIP_AARCH_SWITCH:
-
- /* clean up the high bits */
- x1 = (uint32_t)x1;
- x2 = (uint32_t)x2;
-
- if (!x1 || x2 > NS_SWITCH_AARCH32) {
- ERROR("%s: invalid parameters\n", __func__);
- return -EINVAL;
- }
-
- /* x1 = ns entry point */
- cm_set_elr_spsr_el3(NON_SECURE, x1,
- (x2 == NS_SWITCH_AARCH32) ? SPSR32 : SPSR64);
-
- /* switch NS world mode */
- cm_write_scr_el3_bit(NON_SECURE, SCR_RW_BITPOS, !x2);
-
- INFO("CPU switched to AARCH%s mode\n",
- (x2 == NS_SWITCH_AARCH32) ? "32" : "64");
- return 0;
-
- default:
- ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
- break;
- }
-
- return -ENOTSUP;
-}
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
deleted file mode 100644
index 9534c07..0000000
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-TZDRAM_BASE := 0xF5C00000
-$(eval $(call add_define,TZDRAM_BASE))
-
-PLATFORM_CLUSTER_COUNT := 1
-$(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
-
-PLATFORM_MAX_CPUS_PER_CLUSTER := 2
-$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
-
-MAX_XLAT_TABLES := 3
-$(eval $(call add_define,MAX_XLAT_TABLES))
-
-MAX_MMAP_REGIONS := 8
-$(eval $(call add_define,MAX_MMAP_REGIONS))
-
-# platform files
-PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t132
-
-BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \
- drivers/ti/uart/aarch64/16550_console.S \
- lib/cpus/aarch64/denver.S \
- ${TEGRA_DRIVERS}/flowctrl/flowctrl.c \
- ${TEGRA_DRIVERS}/memctrl/memctrl_v1.c \
- ${TEGRA_DRIVERS}/pmc/pmc.c \
- ${SOC_DIR}/plat_psci_handlers.c \
- ${SOC_DIR}/plat_sip_calls.c \
- ${SOC_DIR}/plat_setup.c \
- ${SOC_DIR}/plat_secondary.c
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-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/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index 0891d80..c02eff9 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -80,8 +80,8 @@
#define SEC_ROM_BASE 0x00000000
#define SEC_ROM_SIZE 0x00020000
-#define NS_DRAM0_BASE 0x40000000
-#define NS_DRAM0_SIZE 0xc0000000
+#define NS_DRAM0_BASE ULL(0x40000000)
+#define NS_DRAM0_SIZE ULL(0xc0000000)
#define SEC_SRAM_BASE 0x0e000000
#define SEC_SRAM_SIZE 0x00060000
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c
index cfacd1f..5259859 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/rpi4/rpi4_bl31_setup.c
@@ -201,6 +201,44 @@
enable_mmu_el3(0);
}
+/*
+ * Remove the FDT /memreserve/ entry that covers the region at the very
+ * beginning of memory (if that exists). This is where the secondaries
+ * originally spin, but we pull them out there.
+ * Having overlapping /reserved-memory and /memreserve/ regions confuses
+ * the Linux kernel, so we need to get rid of this one.
+ */
+static void remove_spintable_memreserve(void *dtb)
+{
+ uint64_t addr, size;
+ int regions = fdt_num_mem_rsv(dtb);
+ int i;
+
+ for (i = 0; i < regions; i++) {
+ if (fdt_get_mem_rsv(dtb, i, &addr, &size) != 0) {
+ return;
+ }
+ if (size == 0U) {
+ return;
+ }
+ /* We only look for the region at the beginning of DRAM. */
+ if (addr != 0U) {
+ continue;
+ }
+ /*
+ * Currently the region in the existing DTs is exactly 4K
+ * in size. Should this value ever change, there is probably
+ * a reason for that, so inform the user about this.
+ */
+ if (size == 4096U) {
+ fdt_del_mem_rsv(dtb, i);
+ return;
+ }
+ WARN("Keeping unknown /memreserve/ region at 0, size: %lld\n",
+ size);
+ }
+}
+
static void rpi4_prepare_dtb(void)
{
void *dtb = (void *)rpi4_get_dtb_address();
@@ -227,7 +265,11 @@
return;
}
- /* Reserve memory used by Trusted Firmware. */
+ /*
+ * Remove the original reserved region (used for the spintable), and
+ * replace it with a region describing the whole of Trusted Firmware.
+ */
+ remove_spintable_memreserve(dtb);
if (fdt_add_reserved_memory(dtb, "atf@0", 0, 0x80000))
WARN("Failed to add reserved memory nodes to DT.\n");
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 3e179fb..b4c42fc 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -153,8 +153,6 @@
#ifdef AARCH32_SP_OPTEE
INFO("BL2 runs OP-TEE setup\n");
- /* Initialize tzc400 after DDR initialization */
- stm32mp1_security_setup();
#else
INFO("BL2 runs SP_MIN setup\n");
#endif
@@ -384,4 +382,9 @@
return err;
}
+
+void bl2_el3_plat_prepare_exit(void)
+{
+ stm32mp1_security_setup();
+}
#endif
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index f165fb0..9c5af88 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -677,6 +677,10 @@
case IOCTL_AFI:
ret = pm_ioctl_afi(arg1, arg2);
break;
+ case IOCTL_SET_FEATURE_CONFIG:
+ case IOCTL_GET_FEATURE_CONFIG:
+ ret = pm_feature_config(ioctl_id, arg1, arg2, value);
+ break;
default:
ret = PM_RET_ERROR_NOTSUPPORTED;
break;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index 337f732..f18dc00 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -15,28 +15,43 @@
//ioctl id
enum {
- IOCTL_GET_RPU_OPER_MODE,
- IOCTL_SET_RPU_OPER_MODE,
- IOCTL_RPU_BOOT_ADDR_CONFIG,
- IOCTL_TCM_COMB_CONFIG,
- IOCTL_SET_TAPDELAY_BYPASS,
- IOCTL_SET_SGMII_MODE,
- IOCTL_SD_DLL_RESET,
- IOCTL_SET_SD_TAPDELAY,
+ IOCTL_GET_RPU_OPER_MODE = 0,
+ IOCTL_SET_RPU_OPER_MODE = 1,
+ IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
+ IOCTL_TCM_COMB_CONFIG = 3,
+ IOCTL_SET_TAPDELAY_BYPASS = 4,
+ IOCTL_SET_SGMII_MODE = 5,
+ IOCTL_SD_DLL_RESET = 6,
+ IOCTL_SET_SD_TAPDELAY = 7,
/* Ioctl for clock driver */
- IOCTL_SET_PLL_FRAC_MODE,
- IOCTL_GET_PLL_FRAC_MODE,
- IOCTL_SET_PLL_FRAC_DATA,
- IOCTL_GET_PLL_FRAC_DATA,
- IOCTL_WRITE_GGS,
- IOCTL_READ_GGS,
- IOCTL_WRITE_PGGS,
- IOCTL_READ_PGGS,
+ IOCTL_SET_PLL_FRAC_MODE = 8,
+ IOCTL_GET_PLL_FRAC_MODE = 9,
+ IOCTL_SET_PLL_FRAC_DATA = 10,
+ IOCTL_GET_PLL_FRAC_DATA = 11,
+ IOCTL_WRITE_GGS = 12,
+ IOCTL_READ_GGS = 13,
+ IOCTL_WRITE_PGGS = 14,
+ IOCTL_READ_PGGS = 15,
/* IOCTL for ULPI reset */
- IOCTL_ULPI_RESET,
+ IOCTL_ULPI_RESET = 16,
/* Set healthy bit value */
- IOCTL_SET_BOOT_HEALTH_STATUS,
- IOCTL_AFI,
+ IOCTL_SET_BOOT_HEALTH_STATUS = 17,
+ IOCTL_AFI = 18,
+ /* Probe counter read/write */
+ IOCTL_PROBE_COUNTER_READ = 19,
+ IOCTL_PROBE_COUNTER_WRITE = 20,
+ IOCTL_OSPI_MUX_SELECT = 21,
+ /* IOCTL for USB power request */
+ IOCTL_USB_SET_STATE = 22,
+ /* IOCTL to get last reset reason */
+ IOCTL_GET_LAST_RESET_REASON = 23,
+ /* AI engine NPI ISR clear */
+ IOCTL_AIE_ISR_CLEAR = 24,
+ /* Register SGI to ATF */
+ IOCTL_REGISTER_SGI = 25,
+ /* Runtime feature configuration */
+ IOCTL_SET_FEATURE_CONFIG = 26,
+ IOCTL_GET_FEATURE_CONFIG = 27,
};
//RPU operation mode
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 62260bc..5d9408c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1648,3 +1648,36 @@
EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS);
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
+
+/**
+ * pm_feature_config() - feature configuration at runtime
+ *
+ * This function is used to send IPI request to PMUFW to configure feature
+ * at runtime. The feature can be enable or disable as well as the feature
+ * can be configure at runtime using an IOCTL call.
+ *
+ * @ioctl_id The ioctl id for the feature configuration
+ * @config_id The config id of the feature to be configured
+ * @value The value to be configured
+ * @response Return to reference pointer
+ *
+ * @return Returns 0 on success or error value on failure
+ */
+enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
+ unsigned int config_id,
+ unsigned int value,
+ unsigned int *response)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD5(payload, PM_IOCTL, 0, ioctl_id, config_id, value);
+
+ if (ioctl_id == IOCTL_GET_FEATURE_CONFIG) {
+ return pm_ipi_send_sync(primary_proc, payload, response, 1);
+ } else if (ioctl_id == IOCTL_SET_FEATURE_CONFIG) {
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ } else {
+ return PM_RET_ERROR_ARGS;
+ }
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index b0c2652..ca07cef 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -202,4 +202,9 @@
enum pm_ret_status em_remove_action(unsigned int *value);
enum pm_ret_status em_send_errors(unsigned int *value);
+enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
+ unsigned int config_id,
+ unsigned int value,
+ unsigned int *response);
+
#endif /* PM_API_SYS_H */