Merge "intel: Fix Coverity Scan Defects" into integration
diff --git a/Makefile b/Makefile
index 5167d2e..547b584 100644
--- a/Makefile
+++ b/Makefile
@@ -207,9 +207,10 @@
CPP = $(CC) -E $(TF_CFLAGS_$(ARCH))
PP = $(CC) -E $(TF_CFLAGS_$(ARCH))
else ifneq ($(findstring clang,$(notdir $(CC))),)
+CLANG_CCDIR = $(if $(filter-out ./,$(dir $(CC))),$(dir $(CC)),)
TF_CFLAGS_aarch32 = $(target32-directive) $(march32-directive)
TF_CFLAGS_aarch64 = -target aarch64-elf $(march64-directive)
-LD = ld.lld
+LD = $(CLANG_CCDIR)ld.lld
ifeq (, $(shell which $(LD)))
$(error "No $(LD) in PATH, make sure it is installed or set LD to a different linker")
endif
@@ -418,11 +419,20 @@
$(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
$(warning "The SPD and its BL32 companion will be present but ignored.")
endif
- # We expect to locate an spd.mk under the specified SPD directory
- SPD_MAKE := $(wildcard services/spd/${SPD}/${SPD}.mk)
+ ifeq (${SPD},spmd)
+ # SPMD is located in std_svc directory
+ SPD_DIR := std_svc
+ else
+ # All other SPDs in spd directory
+ SPD_DIR := spd
+ endif
+
+ # We expect to locate an spd.mk under the specified SPD directory
+ SPD_MAKE := $(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk)
+
ifeq (${SPD_MAKE},)
- $(error Error: No services/spd/${SPD}/${SPD}.mk located)
+ $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located)
endif
$(info Including ${SPD_MAKE})
include ${SPD_MAKE}
@@ -777,6 +787,7 @@
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM))
$(eval $(call assert_boolean,USE_DEBUGFS))
+$(eval $(call assert_boolean,USE_FCONF_BASED_IO))
$(eval $(call assert_boolean,USE_ROMLIB))
$(eval $(call assert_boolean,USE_TBBR_DEFS))
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -845,6 +856,7 @@
$(eval $(call add_define,TRUSTED_BOARD_BOOT))
$(eval $(call add_define,USE_COHERENT_MEM))
$(eval $(call add_define,USE_DEBUGFS))
+$(eval $(call add_define,USE_FCONF_BASED_IO))
$(eval $(call add_define,USE_ROMLIB))
$(eval $(call add_define,USE_TBBR_DEFS))
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index 877af8e..b20859b 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -65,8 +65,13 @@
* No need to pad out the .rodata section to a page boundary. Next is
* the .data section, which can mapped in ROM with the same memory
* attributes as the .rodata section.
+ *
+ * Pad out to 16 bytes though as .data section needs to be 16 byte
+ * aligned and lld does not align the LMA to the aligment specified
+ * on the .data section.
*/
__RODATA_END__ = .;
+ . = ALIGN(16);
} >ROM
#else
ro . : {
@@ -92,6 +97,13 @@
*(.vectors)
__RO_END__ = .;
+
+ /*
+ * Pad out to 16 bytes as .data section needs to be 16 byte aligned and
+ * lld does not align the LMA to the aligment specified on the .data
+ * section.
+ */
+ . = ALIGN(16);
} >ROM
#endif
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index 48f08d2..42a3ded 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -55,11 +55,11 @@
/*******************************************************************************
* Top level handler for servicing FWU SMCs.
******************************************************************************/
-register_t bl1_fwu_smc_handler(unsigned int smc_fid,
- register_t x1,
- register_t x2,
- register_t x3,
- register_t x4,
+u_register_t bl1_fwu_smc_handler(unsigned int smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
void *cookie,
void *handle,
unsigned int flags)
@@ -76,7 +76,7 @@
SMC_RET1(handle, bl1_fwu_image_execute(x1, &handle, flags));
case FWU_SMC_IMAGE_RESUME:
- SMC_RET1(handle, bl1_fwu_image_resume(x1, &handle, flags));
+ SMC_RET1(handle, bl1_fwu_image_resume((register_t)x1, &handle, flags));
case FWU_SMC_SEC_IMAGE_DONE:
SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags));
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index bff8d22..e11ead6 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -226,11 +226,11 @@
/*******************************************************************************
* Top level handler for servicing BL1 SMCs.
******************************************************************************/
-register_t bl1_smc_handler(unsigned int smc_fid,
- register_t x1,
- register_t x2,
- register_t x3,
- register_t x4,
+u_register_t bl1_smc_handler(unsigned int smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
void *cookie,
void *handle,
unsigned int flags)
@@ -269,12 +269,12 @@
* BL1 SMC wrapper. This function is only used in AArch32 mode to ensure ABI
* compliance when invoking bl1_smc_handler.
******************************************************************************/
-register_t bl1_smc_wrapper(uint32_t smc_fid,
+u_register_t bl1_smc_wrapper(uint32_t smc_fid,
void *cookie,
void *handle,
unsigned int flags)
{
- register_t x1, x2, x3, x4;
+ u_register_t x1, x2, x3, x4;
assert(handle != NULL);
diff --git a/bl1/bl1_private.h b/bl1/bl1_private.h
index 927c7b8..2cfeeea 100644
--- a/bl1/bl1_private.h
+++ b/bl1/bl1_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,11 +19,11 @@
void bl1_prepare_next_image(unsigned int image_id);
-register_t bl1_fwu_smc_handler(unsigned int smc_fid,
- register_t x1,
- register_t x2,
- register_t x3,
- register_t x4,
+u_register_t bl1_fwu_smc_handler(unsigned int smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
void *cookie,
void *handle,
unsigned int flags);
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 6230562..c1338e2 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -46,6 +46,11 @@
__RODATA_START__ = .;
*(SORT_BY_ALIGNMENT(.rodata*))
+ . = ALIGN(8);
+ __FCONF_POPULATOR_START__ = .;
+ KEEP(*(.fconf_populator))
+ __FCONF_POPULATOR_END__ = .;
+
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
__PARSER_LIB_DESCS_START__ = .;
@@ -62,6 +67,11 @@
*(SORT_BY_ALIGNMENT(.text*))
*(SORT_BY_ALIGNMENT(.rodata*))
+ . = ALIGN(8);
+ __FCONF_POPULATOR_START__ = .;
+ KEEP(*(.fconf_populator))
+ __FCONF_POPULATOR_END__ = .;
+
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
__PARSER_LIB_DESCS_START__ = .;
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 58909e8..0948e94 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -31,6 +31,7 @@
services/arm_arch_svc/arm_arch_svc_setup.c \
services/std_svc/std_svc_setup.c \
${PSCI_LIB_SOURCES} \
+ ${SPMD_SOURCES} \
${SPM_SOURCES}
diff --git a/common/bl_common.c b/common/bl_common.c
index b74225b..2fcb538 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/common/desc_image_load.c b/common/desc_image_load.c
index b483597..0769226 100644
--- a/common/desc_image_load.c
+++ b/common/desc_image_load.c
@@ -215,6 +215,9 @@
bl_params_node_t *params_node;
unsigned int fw_config_id;
uintptr_t hw_config_base = 0, fw_config_base;
+#if defined(SPD_spmd)
+ uint32_t fw_config_size = 0;
+#endif
bl_mem_params_node_t *mem_params;
assert(bl2_to_next_bl_params != NULL);
@@ -249,10 +252,14 @@
if (fw_config_id != INVALID_IMAGE_ID) {
mem_params = get_bl_mem_params_node(fw_config_id);
- if (mem_params != NULL)
+ if (mem_params != NULL) {
fw_config_base = mem_params->image_info.image_base;
+#if defined(SPD_spmd)
+ fw_config_size =
+ mem_params->image_info.image_size;
+#endif
+ }
}
-
/*
* Pass hw and tb_fw config addresses to next images. NOTE - for
* EL3 runtime images (BL31 for AArch64 and BL32 for AArch32),
@@ -273,6 +280,11 @@
if (params_node->ep_info->args.arg1 == 0U)
params_node->ep_info->args.arg1 =
hw_config_base;
+#if defined(SPD_spmd)
+ if (params_node->ep_info->args.arg2 == 0U)
+ params_node->ep_info->args.arg2 =
+ fw_config_size;
+#endif
}
}
}
diff --git a/docs/components/debugfs-design.rst b/docs/components/debugfs-design.rst
index 06916f3..8ce1ba6 100644
--- a/docs/components/debugfs-design.rst
+++ b/docs/components/debugfs-design.rst
@@ -15,8 +15,9 @@
------------------
The core functionality lies in a virtual file system based on a 9p file server
-interface (`Notes on the Plan 9 Kernel Source`_). The implementation permits
-exposing virtual files, firmware drivers, and file blobs.
+interface (`Notes on the Plan 9 Kernel Source`_ and
+`Linux 9p remote filesystem protocol`_).
+The implementation permits exposing virtual files, firmware drivers, and file blobs.
Namespace
~~~~~~~~~
@@ -77,10 +78,10 @@
-------------
The communication with the 9p layer in BL31 is made through an SMC conduit
-(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS shared
-buffer is used to pass path string parameters, or e.g. to exchange data on a
-read operation. Refer to `ARM SiP Services`_ for a description of the SMC
-interface.
+(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS
+shared buffer is used to pass path string parameters, or e.g. to exchange
+data on a read operation. Refer to `ARM SiP Services`_ for a description
+of the SMC interface.
Security considerations
-----------------------
@@ -114,17 +115,9 @@
- a Linux kernel driver running at NS-EL1
- a Linux userspace application through the kernel driver
-References
-----------
-
-.. [#] `SMC Calling Convention PDD`_
-.. [#] `Notes on the Plan 9 Kernel Source`_
-.. [#] `Linux 9p remote filesystem protocol`_
-.. [#] `ARM SiP Services`_
-
--------------
-*Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/
.. _Notes on the Plan 9 Kernel Source: http://lsub.org/who/nemo/9.pdf
diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst
new file mode 100644
index 0000000..cec3ceb
--- /dev/null
+++ b/docs/components/fconf.rst
@@ -0,0 +1,85 @@
+Firmware Configuration Framework
+================================
+
+This document provides an overview of the |FCONF| framework.
+
+Introduction
+~~~~~~~~~~~~
+
+The Firmware CONfiguration Framework (|FCONF|) is an abstraction layer for
+platform specific data, allowing a "property" to be queried and a value
+retrieved without the requesting entity knowing what backing store is being used
+to hold the data.
+
+It is used to bridge new and old ways of providing platform-specific data.
+Today, information like the Chain of Trust is held within several, nested
+platform-defined tables. In the future, it may be provided as part of a device
+blob, along with the rest of the information about images to load.
+Introducing this abstraction layer will make migration easier and will preserve
+functionality for platforms that cannot / don't want to use device tree.
+
+Accessing properties
+~~~~~~~~~~~~~~~~~~~~
+
+Properties defined in the |FCONF| are grouped around namespaces and
+sub-namespaces: a.b.property.
+Examples namespace can be:
+
+- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert
+- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth
+- Arm io policies: arm.io_policies.bl2_image
+
+Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro.
+
+Defining properties
+~~~~~~~~~~~~~~~~~~~
+
+Properties composing the |FCONF| have to be stored in C structures. If another
+backing store is wanted to be used, the platform has to provide a ``populate()``
+function to fill the corresponding C structure.
+
+The ``populate()`` function must be registered to the |FCONF| framework with
+the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function would
+be called inside the generic ``fconf_populate()`` function during
+initialization.
+
+::
+
+ int fconf_populate_tbbr_dyn_config(uintptr_t config)
+ {
+ /* read dtb and fill tbbr_dyn_config struct */
+ }
+
+ FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config);
+
+Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro:
+
+::
+
+ /* generic getter */
+ #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property)
+
+ /* my specific getter */
+ #define tbbr__dyn_config_getter(id) tbbr_dyn_config.id
+
+This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to
+anything appropriate: structure, array, function, etc..
+
+Loading the property device tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``fconf_load_config()`` must be called to load the device tree containing
+the properties' values. This must be done after the io layer is initialized, as
+the |DTB| is stored on an external device (FIP).
+
+.. uml:: ../resources/diagrams/plantuml/fconf_bl1_load_config.puml
+
+Populating the properties
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once a valid device tree is available, the ``fconf_populate(config)`` function
+can be used to fill the C data structure with the data from the config |DTB|.
+This function will call all the ``populate()`` callbacks which have been
+registered with ``FCONF_REGISTER_POPULATOR()``.
+
+.. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml
diff --git a/docs/components/index.rst b/docs/components/index.rst
index f1904c0..ae78b2b 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -8,7 +8,9 @@
spd/index
arm-sip-service
+ debugfs-design
exception-handling
+ fconf
firmware-update
platform-interrupt-controller-API
ras
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 5fc1335..d0d6ef6 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -2696,13 +2696,13 @@
--------------
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _Arm ARM: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.e/index.html
+.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 031836a..8854a79 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -578,6 +578,11 @@
exposing a virtual filesystem interface through BL31 as a SiP SMC function.
Default is 0.
+- ``USE_FCONF_BASED_IO``: This flag determines whether to use IO based on the
+ firmware configuration framework. This allows moving the io_policies into a
+ configuration device tree, instead of static structure in the code base.
+
+
- ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
This feature creates a library of functions to be placed in ROM and thus
reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 491b160..4dda1dc 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -6,11 +6,13 @@
.. |COT| replace:: :term:`COT`
.. |CSS| replace:: :term:`CSS`
.. |CVE| replace:: :term:`CVE`
+.. |DTB| replace:: :term:`DTB`
.. |DS-5| replace:: :term:`DS-5`
.. |DSU| replace:: :term:`DSU`
.. |DT| replace:: :term:`DT`
.. |EL| replace:: :term:`EL`
.. |EHF| replace:: :term:`EHF`
+.. |FCONF| replace:: :term:`FCONF`
.. |FDT| replace:: :term:`FDT`
.. |FIP| replace:: :term:`FIP`
.. |FVP| replace:: :term:`FVP`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 2f19df5..3da30b0 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -42,12 +42,18 @@
DT
Device Tree
+ DTB
+ Device Tree Blob
+
EL
Exception Level
EHF
Exception Handling Framework
+ FCONF
+ Firmware Configuration Framework
+
FDT
Flattened Device Tree
diff --git a/docs/perf/index.rst b/docs/perf/index.rst
index 0f49b48..1482b80 100644
--- a/docs/perf/index.rst
+++ b/docs/perf/index.rst
@@ -8,7 +8,8 @@
psci-performance-juno
tsp
+ performance-monitoring-unit
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/perf/performance-monitoring-unit.rst b/docs/perf/performance-monitoring-unit.rst
new file mode 100644
index 0000000..5dd1af5
--- /dev/null
+++ b/docs/perf/performance-monitoring-unit.rst
@@ -0,0 +1,158 @@
+Performance Monitoring Unit
+===========================
+
+The Performance Monitoring Unit (PMU) allows recording of architectural and
+microarchitectural events for profiling purposes.
+
+This document gives an overview of the PMU counter configuration to assist with
+implementation and to complement the PMU security guidelines given in the
+:ref:`Secure Development Guidelines` document.
+
+.. note::
+ This section applies to Armv8-A implementations which have version 3
+ of the Performance Monitors Extension (PMUv3).
+
+PMU Counters
+------------
+
+The PMU makes 32 counters available at all privilege levels:
+
+- 31 programmable event counters: ``PMEVCNTR<n>``, where ``n`` is ``0`` to
+ ``30``.
+- A dedicated cycle counter: ``PMCCNTR``.
+
+Architectural mappings
+~~~~~~~~~~~~~~~~~~~~~~
+
++--------------+---------+----------------------------+
+| Counters | State | System Register Name |
++==============+=========+============================+
+| | AArch64 | ``PMEVCNTR<n>_EL0[63*:0]`` |
+| Programmable +---------+----------------------------+
+| | AArch32 | ``PMEVCNTR<n>[31:0]`` |
++--------------+---------+----------------------------+
+| | AArch64 | ``PMCCNTR_EL0[63:0]`` |
+| Cycle +---------+----------------------------+
+| | AArch32 | ``PMCCNTR[63:0]`` |
++--------------+---------+----------------------------+
+
+.. note::
+ Bits [63:32] are only available if ARMv8.5-PMU is implemented. Refer to the
+ `Arm ARM`_ for a detailed description of ARMv8.5-PMU features.
+
+Configuring the PMU for counting events
+---------------------------------------
+
+Each programmable counter has an associated register, ``PMEVTYPER<n>`` which
+configures it. The cycle counter has the ``PMCCFILTR_EL0`` register, which has
+an identical function and bit field layout as ``PMEVTYPER<n>``. In addition,
+the counters are enabled (permitted to increment) via the ``PMCNTENSET`` and
+``PMCR`` registers. These can be accessed at all privilege levels.
+
+Architectural mappings
+~~~~~~~~~~~~~~~~~~~~~~
+
++-----------------------------+------------------------+
+| AArch64 | AArch32 |
++=============================+========================+
+| ``PMEVTYPER<n>_EL0[63*:0]`` | ``PMEVTYPER<n>[31:0]`` |
++-----------------------------+------------------------+
+| ``PMCCFILTR_EL0[63*:0]`` | ``PMCCFILTR[31:0]`` |
++-----------------------------+------------------------+
+| ``PMCNTENSET_EL0[63*:0]`` | ``PMCNTENSET[31:0]`` |
++-----------------------------+------------------------+
+| ``PMCR_EL0[63*:0]`` | ``PMCR[31:0]`` |
++-----------------------------+------------------------+
+
+.. note::
+ Bits [63:32] are reserved.
+
+Relevant register fields
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+For ``PMEVTYPER<n>_EL0``/``PMEVTYPER<n>`` and ``PMCCFILTR_EL0/PMCCFILTR``, the
+most important fields are:
+
+- ``P``:
+
+ - Bit 31.
+ - If set to ``0``, will increment the associated ``PMEVCNTR<n>`` at EL1.
+
+- ``NSK``:
+
+ - Bit 29.
+ - If equal to the ``P`` bit it enables the associated ``PMEVCNTR<n>`` at
+ Non-secure EL1.
+ - Reserved if EL3 not implemented.
+
+- ``NSH``:
+
+ - Bit 27.
+ - If set to ``1``, will increment the associated ``PMEVCNTR<n>`` at EL2.
+ - Reserved if EL2 not implemented.
+
+- ``SH``:
+
+ - Bit 24.
+ - If different to the ``NSH`` bit it enables the associated ``PMEVCNTR<n>``
+ at Secure EL2.
+ - Reserved if Secure EL2 not implemented.
+
+- ``M``:
+
+ - Bit 26.
+ - If equal to the ``P`` bit it enables the associated ``PMEVCNTR<n>`` at
+ EL3.
+
+- ``evtCount[15:10]``:
+
+ - Extension to ``evtCount[9:0]``. Reserved unless ARMv8.1-PMU implemented.
+
+- ``evtCount[9:0]``:
+
+ - The event number that the associated ``PMEVCNTR<n>`` will count.
+
+For ``PMCNTENSET_EL0``/``PMCNTENSET``, the most important fields are:
+
+- ``P[30:0]``:
+
+ - Setting bit ``P[n]`` to ``1`` enables counter ``PMEVCNTR<n>``.
+ - The effects of ``PMEVTYPER<n>`` are applied on top of this.
+ In other words, the counter will not increment at any privilege level or
+ security state unless it is enabled here.
+
+- ``C``:
+
+ - Bit 31.
+ - If set to ``1`` enables the cycle counter ``PMCCNTR``.
+
+For ``PMCR``/``PMCR_EL0``, the most important fields are:
+
+- ``DP``:
+
+ - Bit 5.
+ - If set to ``1`` it disables the cycle counter ``PMCCNTR`` where event
+ counting (by ``PMEVCNTR<n>``) is prohibited (e.g. EL2 and the Secure
+ world).
+ - If set to ``0``, ``PMCCNTR`` will not be affected by this bit and
+ therefore will be able to count where the programmable counters are
+ prohibited.
+
+- ``E``:
+
+ - Bit 0.
+ - Enables/disables counting altogether.
+ - The effects of ``PMCNTENSET`` and ``PMCR.DP`` are applied on top of this.
+ In other words, if this bit is ``0`` then no counters will increment
+ regardless of how the other PMU system registers or bit fields are
+ configured.
+
+.. rubric:: References
+
+- `Arm ARM`_
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 37010e1..40e9661 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -277,15 +277,15 @@
-C cluster0.NUM_CORES=4 \
-C cluster1.NUM_CORES=4 \
-C cache_state_modelled=1 \
- -C cluster0.cpu0.RVBAR=0x04020000 \
- -C cluster0.cpu1.RVBAR=0x04020000 \
- -C cluster0.cpu2.RVBAR=0x04020000 \
- -C cluster0.cpu3.RVBAR=0x04020000 \
- -C cluster1.cpu0.RVBAR=0x04020000 \
- -C cluster1.cpu1.RVBAR=0x04020000 \
- -C cluster1.cpu2.RVBAR=0x04020000 \
- -C cluster1.cpu3.RVBAR=0x04020000 \
- --data cluster0.cpu0="<path-to>/bl31.bin"@0x04020000 \
+ -C cluster0.cpu0.RVBAR=0x04001000 \
+ -C cluster0.cpu1.RVBAR=0x04001000 \
+ -C cluster0.cpu2.RVBAR=0x04001000 \
+ -C cluster0.cpu3.RVBAR=0x04001000 \
+ -C cluster1.cpu0.RVBAR=0x04001000 \
+ -C cluster1.cpu1.RVBAR=0x04001000 \
+ -C cluster1.cpu2.RVBAR=0x04001000 \
+ -C cluster1.cpu3.RVBAR=0x04001000 \
+ --data cluster0.cpu0="<path-to>/bl31.bin"@0x04001000 \
--data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000 \
--data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
--data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index 43a5721..507046f 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -25,6 +25,99 @@
many normal world requests (a *Denial of Service* or *DoS* attack). It should
have a mechanism for throttling or ignoring normal world requests.
+Preventing Secure-world timing information leakage via PMU counters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Secure world needs to implement some defenses to prevent the Non-secure
+world from making it leak timing information. In general, higher privilege
+levels must defend from those below when the PMU is treated as an attack
+vector.
+
+Refer to the :ref:`Performance Monitoring Unit` guide for detailed information
+on the PMU registers.
+
+Timing leakage attacks from the Non-secure world
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since the Non-secure world has access to the ``PMCR`` register, it can
+configure the PMU to increment counters at any exception level and in both
+Secure and Non-secure state. Thus, it attempts to leak timing information from
+the Secure world.
+
+Shown below is an example of such a configuration:
+
+- ``PMEVTYPER0_EL0`` and ``PMCCFILTR_EL0``:
+
+ - Set ``P`` to ``0``.
+ - Set ``NSK`` to ``1``.
+ - Set ``M`` to ``0``.
+ - Set ``NSH`` to ``0``.
+ - Set ``SH`` to ``1``.
+
+- ``PMCNTENSET_EL0``:
+
+ - Set ``P[0]`` to ``1``.
+ - Set ``C`` to ``1``.
+
+- ``PMCR_EL0``:
+
+ - Set ``DP`` to ``0``.
+ - Set ``E`` to ``1``.
+
+This configuration instructs ``PMEVCNTR0_EL0`` and ``PMCCNTR_EL0`` to increment
+at Secure EL1, Secure EL2 (if implemented) and EL3.
+
+Since the Non-secure world has fine-grained control over where (at which
+exception levels) it instructs counters to increment, obtaining event counts
+would allow it to carry out side-channel timing attacks against the Secure
+world. Examples include Spectre, Meltdown, as well as extracting secrets from
+cryptographic algorithms with data-dependent variations in their execution
+time.
+
+Secure world mitigation strategies
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``MDCR_EL3`` register allows EL3 to configure the PMU (among other things).
+The `Arm ARM`_ details all of the bit fields in this register, but for the PMU
+there are two bits which determine the permissions of the counters:
+
+- ``SPME`` for the programmable counters.
+- ``SCCD`` for the cycle counter.
+
+Depending on the implemented features, the Secure world can prohibit counting
+in AArch64 state via the following:
+
+- ARMv8.2-Debug not implemented:
+
+ - Prohibit general event counters and the cycle counter:
+ ``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1 && !ExternalSecureNoninvasiveDebugEnabled()``.
+
+ - ``MDCR_EL3.SPME`` resets to ``0``, so by default general events should
+ not be counted in the Secure world.
+ - The ``PMCR_EL0.DP`` bit therefore needs to be set to ``1`` when EL3 is
+ entered and ``PMCR_EL0`` needs to be saved and restored in EL3.
+ - ``ExternalSecureNoninvasiveDebugEnabled()`` is an authentication
+ interface which is implementation-defined unless ARMv8.4-Debug is
+ implemented. The `Arm ARM`_ has detailed information on this topic.
+
+ - The only other way is to disable the ``PMCR_EL0.E`` bit upon entering
+ EL3, which disables counting altogether.
+
+- ARMv8.2-Debug implemented:
+
+ - Prohibit general event counters: ``MDCR_EL3.SPME == 0``.
+ - Prohibit cycle counter: ``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1``.
+ ``PMCR_EL0`` therefore needs to be saved and restored in EL3.
+
+- ARMv8.5-PMU implemented:
+
+ - Prohibit general event counters: as in ARMv8.2-Debug.
+ - Prohibit cycle counter: ``MDCR_EL3.SCCD == 1``
+
+In Aarch32 execution state the ``MDCR_EL3`` alias is the ``SDCR`` register,
+which has some of the bit fields of ``MDCR_EL3``, most importantly the ``SPME``
+and ``SCCD`` bits.
+
Build options
-------------
@@ -71,6 +164,12 @@
NB: The ``Werror`` flag is enabled by default in TF-A and can be disabled by
setting the ``E`` build flag to 0.
+.. rubric:: References
+
+- `Arm ARM`_
+
--------------
*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+
+.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml
new file mode 100644
index 0000000..c36e544
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml
@@ -0,0 +1,52 @@
+@startuml
+
+box "BL1 common code"
+ participant bl1_main
+ participant bl_common
+end box
+
+box "arm platform code" #LightBlue
+ participant fvp_bl1_setup
+ participant arm_bl1_setup
+ participant arm_io_storage
+end box
+
+box "platform common code"
+ participant plat_bl1_common
+ participant fconf
+end box
+
+bl1_main -> fvp_bl1_setup : bl1_platform_setup()
+fvp_bl1_setup -> arm_bl1_setup : arm_bl1_platform_setup()
+arm_bl1_setup -> arm_io_storage : plat_arm_io_setup()
+note over arm_io_storage : register and setup fip
+arm_bl1_setup -> fconf : fconf_load_config()
+activate fconf
+ note over fconf
+ create and populate an
+ image_desc_t for TB_FW_CONFIG
+ end note
+ fconf -> bl_common : load_auth_image(TB_FW_CONFIG_ID, &image_info)
+ activate bl_common
+ note over bl_common
+ load and auth image from fip
+ with info from plat_io_policy
+ end note
+ bl_common -> arm_io_storage
+ arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, tb_fw_cfg)
+ note over fconf: use staticaly defined policies in bl1
+ fconf <- bl_common : image_info
+ deactivate bl_common
+ note over fconf : get tb_fw_config_dtb from image_info
+ fconf -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID)
+ fconf <- plat_bl1_common : BL2_IMAGE_DESC
+ note over fconf
+ set ep_info.args.arg0 of BL2_IMAGE_DESC
+ to TB_FW_CONFIG base address
+ end note
+arm_bl1_setup <- fconf
+deactivate fconf
+
+== load & auth, prepare and jump to BL2 ==
+
+@enduml
diff --git a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml
new file mode 100644
index 0000000..98a3ff1
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml
@@ -0,0 +1,41 @@
+@startuml
+
+box "BL2 common code"
+ participant bl2_entrypoint
+ participant bl2_main
+end box
+
+box "platform common code"
+ participant fconf
+ participant fconf_tbbr_getter
+end box
+
+box "arm platform code" #LightBlue
+ participant arm_bl2_setup
+ participant arm_io_storage
+ participant arm_fconf_io
+end box
+
+== bl2 setup ==
+bl2_entrypoint -> bl2_main : bl2_setup()
+bl2_main -> arm_bl2_setup : bl2_early_platform_setup2(\n\t arg0, arg1, arg2, arg3)
+note over arm_bl2_setup
+ arg0 = tb_fw_config
+ arg1 = mem_layout
+end note
+arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t tb_fw_config, mem_layout)
+activate arm_bl2_setup
+ arm_bl2_setup -> fconf: fconf_polulate(tb_fw_config)
+ activate fconf
+ fconf -> fconf_tbbr_getter: fconf_populate_tbbr_dyn_config(uintptr_t dtb)
+ note over fconf_tbbr_getter: read tbbr propeties from dtb
+ fconf -> arm_fconf_io: fconf_populate_arm_io_policies(uintptr_t dtb)
+ note over arm_fconf_io: read arm io propeties from dtb
+ deactivate fconf
+ arm_bl2_setup -> arm_io_storage : plat_arm_io_setup()
+ note over arm_io_storage: use populated properties
+deactivate arm_bl2_setup
+
+== bl2 main ==
+
+@enduml
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 3fb2d1a..91ee1be 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,7 @@
#include <drivers/auth/auth_mod.h>
#include <drivers/auth/crypto_mod.h>
#include <drivers/auth/img_parser_mod.h>
+#include <lib/fconf/fconf_tbbr_getter.h>
#include <plat/common/platform.h>
/* ASN.1 tags */
@@ -302,9 +303,8 @@
const auth_img_desc_t *img_desc = NULL;
assert(parent_id != NULL);
-
/* Get the image descriptor */
- img_desc = cot_desc_ptr[img_id];
+ img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
/* Check if the image has no parent (ROT) */
if (img_desc->parent == NULL) {
@@ -353,7 +353,7 @@
int rc, i;
/* Get the image descriptor from the chain of trust */
- img_desc = cot_desc_ptr[img_id];
+ img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
/* Ask the parser to check the image integrity */
rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len);
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index 6dd4ae2..6f00b18 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,7 +18,12 @@
/*
- * Maximum key and hash sizes (in DER format)
+ * Maximum key and hash sizes (in DER format).
+ *
+ * Both RSA and ECDSA keys may be used at the same time. In this case, the key
+ * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA
+ * ones for all key sizes we support, they impose the minimum size of these
+ * buffers.
*/
#if TF_MBEDTLS_USE_RSA
#if TF_MBEDTLS_KEY_SIZE == 1024
@@ -32,11 +37,19 @@
#else
#error "Invalid value for TF_MBEDTLS_KEY_SIZE"
#endif
-#else
-#define PK_DER_LEN 294
+#else /* Only using ECDSA keys. */
+#define PK_DER_LEN 91
#endif
+#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
+#define HASH_DER_LEN 51
+#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384
+#define HASH_DER_LEN 67
+#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512
#define HASH_DER_LEN 83
+#else
+#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID"
+#endif
/*
* The platform must allocate buffers to store the authentication parameters
diff --git a/drivers/cfi/v2m/v2m_flash.c b/drivers/cfi/v2m/v2m_flash.c
index aadafbc..6690189 100644
--- a/drivers/cfi/v2m/v2m_flash.c
+++ b/drivers/cfi/v2m/v2m_flash.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,7 +27,7 @@
#define DWS_WORD_LOCK_RETRIES 1000
/* Helper macro to detect end of command */
-#define NOR_CMD_END (NOR_DWS | NOR_DWS << 16l)
+#define NOR_CMD_END (NOR_DWS | (NOR_DWS << 16l))
/* Helper macros to access two flash banks in parallel */
#define NOR_2X16(d) ((d << 16) | (d & 0xffff))
diff --git a/drivers/marvell/mochi/cp110_setup.c b/drivers/marvell/mochi/cp110_setup.c
index b4b4e0c..7186f98 100644
--- a/drivers/marvell/mochi/cp110_setup.c
+++ b/drivers/marvell/mochi/cp110_setup.c
@@ -303,7 +303,7 @@
DOMAIN_SYSTEM_SHAREABLE);
}
-static void amb_bridge_init(uintptr_t base)
+void cp110_amb_init(uintptr_t base)
{
uint32_t reg;
@@ -399,7 +399,7 @@
cp110_stream_id_init(cp110_base, stream_id);
/* Open AMB bridge for comphy for CP0 & CP1*/
- amb_bridge_init(cp110_base);
+ cp110_amb_init(cp110_base);
/* Reset RTC if needed */
cp110_rtc_init(cp110_base);
@@ -411,7 +411,7 @@
#if PCI_EP_SUPPORT
INFO("%s: Initialize CPx - base = %lx\n", __func__, cp110_base);
- amb_bridge_init(cp110_base);
+ cp110_amb_init(cp110_base);
/* Configure PCIe clock */
cp110_pcie_clk_cfg(cp110_base);
diff --git a/drivers/renesas/rcar/board/board.c b/drivers/renesas/rcar/board/board.c
index df17802..cd194ff 100644
--- a/drivers/renesas/rcar/board/board.c
+++ b/drivers/renesas/rcar/board/board.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights
* reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -33,7 +33,7 @@
#define SXS_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
#define SX_ID { 0x10U, 0x11U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
#define SKP_ID { 0x10U, 0x10U, 0x20U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
-#define SK_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
+#define SK_ID { 0x10U, 0x30U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
#define EB4_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
#define EB_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
#define DR_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
index 1d6e83a..ac83c9a 100644
--- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
+++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -510,6 +510,14 @@
dsb_sev();
}
+static void dbwait_loop(uint32_t wait_loop)
+{
+ uint32_t i;
+
+ for (i = 0; i < wait_loop; i++)
+ wait_dbcmd();
+}
+
/* DDRPHY register access (raw) */
static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd)
{
@@ -866,6 +874,7 @@
uint8_t WL;
uint8_t nwr;
uint8_t nrtp;
+ uint8_t odtlon;
uint8_t MR1;
uint8_t MR2;
};
@@ -877,21 +886,21 @@
#define JS1_MR2(f) (0x00 | ((f) << 3) | (f))
const struct _jedec_spec1 js1[JS1_FREQ_TBL_NUM] = {
/* 533.333Mbps */
- { 800, 6, 6, 4, 6, 8, JS1_MR1(0), JS1_MR2(0) | 0x40 },
+ { 800, 6, 6, 4, 6, 8, 0, JS1_MR1(0), JS1_MR2(0) | 0x40 },
/* 1066.666Mbps */
- { 1600, 10, 12, 8, 10, 8, JS1_MR1(1), JS1_MR2(1) | 0x40 },
+ { 1600, 10, 12, 8, 10, 8, 0, JS1_MR1(1), JS1_MR2(1) | 0x40 },
/* 1600.000Mbps */
- { 2400, 14, 16, 12, 16, 8, JS1_MR1(2), JS1_MR2(2) | 0x40 },
+ { 2400, 14, 16, 12, 16, 8, 6, JS1_MR1(2), JS1_MR2(2) | 0x40 },
/* 2133.333Mbps */
- { 3200, 20, 22, 10, 20, 8, JS1_MR1(3), JS1_MR2(3) },
+ { 3200, 20, 22, 10, 20, 8, 4, JS1_MR1(3), JS1_MR2(3) },
/* 2666.666Mbps */
- { 4000, 24, 28, 12, 24, 10, JS1_MR1(4), JS1_MR2(4) },
+ { 4000, 24, 28, 12, 24, 10, 4, JS1_MR1(4), JS1_MR2(4) },
/* 3200.000Mbps */
- { 4800, 28, 32, 14, 30, 12, JS1_MR1(5), JS1_MR2(5) },
+ { 4800, 28, 32, 14, 30, 12, 6, JS1_MR1(5), JS1_MR2(5) },
/* 3733.333Mbps */
- { 5600, 32, 36, 16, 34, 14, JS1_MR1(6), JS1_MR2(6) },
+ { 5600, 32, 36, 16, 34, 14, 6, JS1_MR1(6), JS1_MR2(6) },
/* 4266.666Mbps */
- { 6400, 36, 40, 18, 40, 16, JS1_MR1(7), JS1_MR2(7) }
+ { 6400, 36, 40, 18, 40, 16, 8, JS1_MR1(7), JS1_MR2(7) }
};
struct _jedec_spec2 {
@@ -921,7 +930,8 @@
#define js2_tzqcalns 19
#define js2_tzqlat 20
#define js2_tiedly 21
-#define JS2_TBLCNT 22
+#define js2_tODTon_min 22
+#define JS2_TBLCNT 23
#define js2_trcpb (JS2_TBLCNT)
#define js2_trcab (JS2_TBLCNT + 1)
@@ -954,7 +964,8 @@
/*tMRD*/ {14000, 10},
/*tZQCALns*/ {1000 * 10, 0},
/*tZQLAT*/ {30000, 10},
-/*tIEdly*/ {12500, 0}
+/*tIEdly*/ {12500, 0},
+/*tODTon_min*/ {1500, 0}
}, {
/*tSR */ {15000, 3},
/*tXP */ {7500, 3},
@@ -977,7 +988,8 @@
/*tMRD*/ {14000, 10},
/*tZQCALns*/ {1000 * 10, 0},
/*tZQLAT*/ {30000, 10},
-/*tIEdly*/ {12500, 0}
+/*tIEdly*/ {12500, 0},
+/*tODTon_min*/ {1500, 0}
}
};
@@ -1452,7 +1464,7 @@
if ((prr_product == PRR_PRODUCT_M3N) ||
(prr_product == PRR_PRODUCT_V3H)) {
ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
- _reg_PHY_RDDATA_EN_OE_DLY, dataS);
+ _reg_PHY_RDDATA_EN_OE_DLY, dataS - 2);
}
ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1, RL - dataS);
@@ -1498,9 +1510,10 @@
/* DDRPHY INT START */
if ((prr_product == PRR_PRODUCT_H3) && (prr_cut <= PRR_PRODUCT_11)) {
- /* non */
+ /* non */
} else {
regif_pll_wa();
+ dbwait_loop(5);
}
/* FREQ_SEL_MULTICAST & PER_CS_TRAINING_MULTICAST SET (for safety) */
@@ -2067,12 +2080,18 @@
/* DBTR9.TRDPR : tRTP */
mmio_write_32(DBSC_DBTR(9), js2[js2_trtp]);
- /* DBTR10.TWR : nwr */
+ /* DBTR10.TWR : nWR */
mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nwr);
- /* DBTR11.TRDWR : RL + tDQSCK + BL/2 + Rounddown(tRPST) - WL + tWPRE */
+ /*
+ * DBTR11.TRDWR : RL + BL / 2 + Rounddown(tRPST) + PHY_ODTLoff -
+ * odtlon + tDQSCK - tODTon,min +
+ * PCB delay (out+in) + tPHY_ODToff
+ */
mmio_write_32(DBSC_DBTR(11),
- RL + js2[js2_tdqsck] + (16 / 2) + 1 - WL + 2 + 2);
+ RL + (16 / 2) + 1 + 2 - js1[js1_ind].odtlon +
+ js2[js2_tdqsck] - js2[js2_tODTon_min] +
+ _f_scale(ddr_mbps, ddr_mbpsdiv, 1300, 0));
/* DBTR12.TWRRD : WL + 1 + BL/2 + tWTR */
data_l = WL + 1 + (16 / 2) + js2[js2_twtr];
@@ -2338,10 +2357,23 @@
}
}
if ((prr_product == PRR_PRODUCT_H3) && (prr_cut > PRR_PRODUCT_11)) {
+#if RCAR_DRAM_SPLIT == 2
+ if (board_cnf->phyvalid == 0x05) {
+ mmio_write_32(DBSC_DBTR(24),
+ (rdlat_max << 24) + (rdlat_min << 16) +
+ mmio_read_32(DBSC_DBTR(24)));
+ } else {
+ mmio_write_32(DBSC_DBTR(24),
+ ((rdlat_max * 2 - rdlat_min + 4) << 24) +
+ ((rdlat_min + 2) << 16) +
+ mmio_read_32(DBSC_DBTR(24)));
+ }
+#else /*RCAR_DRAM_SPLIT == 2 */
mmio_write_32(DBSC_DBTR(24),
((rdlat_max * 2 - rdlat_min + 4) << 24) +
((rdlat_min + 2) << 16) +
mmio_read_32(DBSC_DBTR(24)));
+#endif /*RCAR_DRAM_SPLIT == 2 */
} else {
mmio_write_32(DBSC_DBTR(24),
((rdlat_max + 2) << 24) +
@@ -2383,37 +2415,6 @@
mmio_write_32(DBSC_DBRFCNF1, 0x00080000 | (data_l & 0x0000ffff));
mmio_write_32(DBSC_DBRFCNF2, 0x00010000 | DBSC_REFINTS);
-#ifdef DDR_BACKUPMODE
- if (ddr_backup == DRAM_BOOT_STATUS_WARM) {
-#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0,1 only) */
- DEBUG(" DEBUG_MESS : DDR_BACKUPMODE_HALF ", 1);
- send_dbcmd(0x08040001);
- wait_dbcmd();
- send_dbcmd(0x0A040001);
- wait_dbcmd();
- send_dbcmd(0x04040010);
- wait_dbcmd();
-
- if (prr_product == PRR_PRODUCT_H3) {
- send_dbcmd(0x08140001);
- wait_dbcmd();
- send_dbcmd(0x0A140001);
- wait_dbcmd();
- send_dbcmd(0x04140010);
- wait_dbcmd();
- }
-#else /* DDR_BACKUPMODE_HALF //for All channels */
- send_dbcmd(0x08840001);
- wait_dbcmd();
- send_dbcmd(0x0A840001);
- wait_dbcmd();
-
- send_dbcmd(0x04840010);
- wait_dbcmd();
-#endif /* DDR_BACKUPMODE_HALF */
- }
-#endif /* DDR_BACKUPMODE */
-
#if RCAR_REWT_TRAINING != 0
/* Periodic-WriteDQ Training seeting */
if (((prr_product == PRR_PRODUCT_H3) &&
@@ -2422,12 +2423,7 @@
(prr_cut == PRR_PRODUCT_10))) {
/* non : H3 Ver.1.x/M3-W Ver.1.0 not support */
} else {
- /*
- * H3 Ver.2.0 or later/M3-W Ver.1.1 or
- * later/M3-N/V3H -> Periodic-WriteDQ Training seeting
- */
-
- /* Periodic WriteDQ Training seeting */
+ /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H */
mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000000);
ddr_setval_ach_as(_reg_PHY_WDQLVL_PATT, 0x04);
@@ -2440,7 +2436,6 @@
_reg_PI_WDQLVL_CS_MAP));
ddr_setval_ach(_reg_PI_LONG_COUNT_MASK, 0x1f);
ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00);
- ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100);
ddr_setval_ach(_reg_PI_WDQLVL_ROTATE, 0x01);
ddr_setval_ach(_reg_PI_TREF_F0, 0x0000);
ddr_setval_ach(_reg_PI_TREF_F1, 0x0000);
@@ -2458,8 +2453,10 @@
mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000011);
}
#endif /* RCAR_REWT_TRAINING */
- /* periodic dram zqcal and phy ctrl update enable */
+ /* periodic dram zqcal enable */
mmio_write_32(DBSC_DBCALCNF, 0x01000010);
+
+ /* periodic phy ctrl update enable */
if (((prr_product == PRR_PRODUCT_H3) &&
(prr_cut <= PRR_PRODUCT_11)) ||
((prr_product == PRR_PRODUCT_M3) &&
@@ -2477,7 +2474,36 @@
#endif /* RCAR_DRAM_SPLIT == 2 */
}
+#ifdef DDR_BACKUPMODE
+ /* SRX */
+ if (ddr_backup == DRAM_BOOT_STATUS_WARM) {
+#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0, 1 only) */
+ NOTICE("BL2: [DEBUG_MESS] DDR_BACKUPMODE_HALF\n");
+ send_dbcmd(0x0A040001);
+ if (Prr_Product == PRR_PRODUCT_H3)
+ send_dbcmd(0x0A140001);
+#else /* DDR_BACKUPMODE_HALF */ /* for All channels */
+ send_dbcmd(0x0A840001);
+#endif /* DDR_BACKUPMODE_HALF */
+ }
+#endif /* DDR_BACKUPMODE */
+
+ /* set Auto Refresh */
mmio_write_32(DBSC_DBRFEN, 0x00000001);
+
+#if RCAR_REWT_TRAINING != 0
+ /* Periodic WriteDQ Traning */
+ if (((prr_product == PRR_PRODUCT_H3) &&
+ (prr_cut <= PRR_PRODUCT_11)) ||
+ ((prr_product == PRR_PRODUCT_M3) &&
+ (prr_cut == PRR_PRODUCT_10))) {
+ /* non : H3 Ver.1.x/M3-W Ver.1.0 not support */
+ } else {
+ /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H */
+ ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100);
+ }
+#endif /* RCAR_REWT_TRAINING */
+
/* dram access enable */
mmio_write_32(DBSC_DBACEN, 0x00000001);
@@ -3026,6 +3052,9 @@
return INITDRAM_ERR_O;
MSG_LF(__func__ ":5\n");
+ /* Dummy PDE */
+ send_dbcmd(0x08840000);
+
/* PDX */
send_dbcmd(0x08840001);
@@ -3477,10 +3506,13 @@
{
uint32_t err, retry_cnt;
const uint32_t retry_max = 0x10;
- uint32_t ch, ddr_csn, mr14_bkup[4][4];
+ uint32_t datal, ch, ddr_csn, mr14_bkup[4][4];
+
+ datal = RL + js2[js2_tdqsck] + (16 / 2) + 1 - WL + 2 + 2 + 19;
+ if ((mmio_read_32(DBSC_DBTR(11)) & 0xFF) > datal)
+ datal = mmio_read_32(DBSC_DBTR(11)) & 0xFF;
+ ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, datal);
- ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW,
- (mmio_read_32(DBSC_DBTR(11)) & 0xFF) + 19);
if (((prr_product == PRR_PRODUCT_H3) && (prr_cut > PRR_PRODUCT_11)) ||
(prr_product == PRR_PRODUCT_M3N) ||
(prr_product == PRR_PRODUCT_V3H)) {
diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
index f8caade..de126de 100644
--- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
+++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -1571,8 +1571,13 @@
{
uint32_t md;
- md = (mmio_read_32(RST_MODEMR) >> 17) & 0x5;
- md = (md | (md >> 1)) & 0x3;
+ if (prr_product == PRR_PRODUCT_V3H) {
+ md = (mmio_read_32(RST_MODEMR) >> 19) & 0x1;
+ md = (md | (md << 1)) & 0x3; /* 0 or 3 */
+ } else {
+ md = (mmio_read_32(RST_MODEMR) >> 17) & 0x5;
+ md = (md | (md >> 1)) & 0x3;
+ }
switch (md) {
case 0x0:
*mbps = 3200;
@@ -1722,8 +1727,13 @@
#endif
}
} else if (prr_product == PRR_PRODUCT_M3) {
- /* RENESAS Starter Kit(M3-W/SIP 8Gbit 1rank) board */
- brd = 3;
+ if (prr_cut >= PRR_PRODUCT_30) {
+ /* RENESAS Starter Kit (M3-W Ver.3.0/SIP) */
+ brd = 18;
+ } else {
+ /* RENESAS Starter Kit(M3-W/SIP 8Gbit 1rank) board */
+ brd = 3;
+ }
} else {
/* RENESAS Starter Kit(M3-N/SIP) board */
brd = 11;
diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
index 5047e5c..56363eb 100644
--- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
+++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#define RCAR_DDR_VERSION "rev.0.37"
+#define RCAR_DDR_VERSION "rev.0.40"
#define DRAM_CH_CNT 0x04
#define SLICE_CNT 0x04
#define CS_CNT 0x02
@@ -22,7 +22,7 @@
/* for ddr deisity setting */
#define DBMEMCONF_REG(d3, row, bank, col, dw) \
- ((d3) << 30 | ((row) << 24) | ((bank) << 16) | ((col) << 8) | (dw))
+ (((d3) << 30) | ((row) << 24) | ((bank) << 16) | ((col) << 8) | (dw))
#define DBMEMCONF_REGD(density) \
(DBMEMCONF_REG((density) % 2, ((density) + 1) / \
diff --git a/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
index 8d80842..fb3032d 100644
--- a/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
+++ b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -116,7 +116,7 @@
/*0859*/ 0x00000200,
/*085a*/ 0x00000004,
/*085b*/ 0x4041a151,
- /*085c*/ 0x0141c0a0,
+ /*085c*/ 0x0141a0a0,
/*085d*/ 0x0000c0c0,
/*085e*/ 0x0e0c000e,
/*085f*/ 0x10001000,
diff --git a/fdts/corstone700.dts b/fdts/corstone700.dts
index 16cf412..c13d3b2 100644
--- a/fdts/corstone700.dts
+++ b/fdts/corstone700.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,9 +14,10 @@
#size-cells = <1>;
chosen {
- bootargs = "console=ttyAMA0 root=/dev/vda2 rw loglevel=9";
- linux,initrd-start = <0x02a00000>;
- linux,initrd-end = <0x04000000>;
+ bootargs = "console=ttyAMA0 \
+ root=mtd:physmap-flash.0 \
+ ro \
+ loglevel=9";
};
cpus {
@@ -32,9 +33,9 @@
};
- memory@2000000 {
+ memory@80000000 {
device_type = "memory";
- reg = <0x02000000 0x02000000>;
+ reg = <0x80000000 0x80000000>;
};
gic: interrupt-controller@1c000000 {
@@ -68,14 +69,21 @@
clock-output-names = "smclk";
};
+ uartclk: uartclk {
+ /* UART clock - 32MHz */
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32000000>;
+ clock-output-names = "uartclk";
+ };
serial0: uart@1a510000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x1a510000 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 19 4>;
- clocks = <&refclk100mhz>, <&smbclk>;
- clock-names = "apb_pclk", "smclk";
+ clocks = <&uartclk>, <&refclk100mhz>;
+ clock-names = "uartclk", "apb_pclk";
};
serial1: uart@1a520000 {
@@ -83,8 +91,8 @@
reg = <0x1a520000 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 20 4>;
- clocks = <&refclk100mhz>, <&smbclk>;
- clock-names = "apb_pclk", "smclk";
+ clocks = <&uartclk>, <&refclk100mhz>;
+ clock-names = "uartclk", "apb_pclk";
};
timer {
diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi
index 94ed67d..5b0470d 100644
--- a/fdts/fvp-base-gicv3-psci-common.dtsi
+++ b/fdts/fvp-base-gicv3-psci-common.dtsi
@@ -39,7 +39,7 @@
#address-cells = <2>;
#size-cells = <0>;
- cpu-map {
+ CPU_MAP:cpu-map {
cluster0 {
core0 {
cpu = <&CPU0>;
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
index 48269a0..daa2e66 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
@@ -6,7 +6,7 @@
/dts-v1/;
-#include "fvp-base-gicv3-psci-common.dtsi"
+#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
&CPU0 {
reg = <0x0 0x0>;
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi
new file mode 100644
index 0000000..f3f7684
--- /dev/null
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include "fvp-base-gicv3-psci-common.dtsi"
+
+/* DynamIQ based designs have upto 8 CPUs in each cluster */
+
+&CPU_MAP {
+ cluster0 {
+ core0 {
+ cpu = <&CPU0>;
+ };
+ core1 {
+ cpu = <&CPU1>;
+ };
+ core2 {
+ cpu = <&CPU2>;
+ };
+ core3 {
+ cpu = <&CPU3>;
+ };
+ core4 {
+ cpu = <&CPU4>;
+ };
+ core5 {
+ cpu = <&CPU5>;
+ };
+ core6 {
+ cpu = <&CPU6>;
+ };
+ core7 {
+ cpu = <&CPU7>;
+ };
+ };
+};
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq.dts b/fdts/fvp-base-gicv3-psci-dynamiq.dts
index 51c7aca..b8b0445 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq.dts
@@ -6,7 +6,7 @@
/dts-v1/;
-#include "fvp-base-gicv3-psci-common.dtsi"
+#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
&CPU0 {
reg = <0x0 0x0>;
diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h
index d81f434..e6447f2 100644
--- a/include/bl1/bl1.h
+++ b/include/bl1/bl1.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -67,16 +67,16 @@
struct entry_point_info;
-register_t bl1_smc_wrapper(uint32_t smc_fid,
+u_register_t bl1_smc_wrapper(uint32_t smc_fid,
void *cookie,
void *handle,
unsigned int flags);
-register_t bl1_smc_handler(unsigned int smc_fid,
- register_t x1,
- register_t x2,
- register_t x3,
- register_t x4,
+u_register_t bl1_smc_handler(unsigned int smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
void *cookie,
void *handle,
unsigned int flags);
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index 0e6ffd6..a301ad5 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -53,7 +53,7 @@
/* UUID specification - used to refer to data accessed using UUIDs (i.e. FIP
* images) */
typedef struct io_uuid_spec {
- const uuid_t uuid;
+ uuid_t uuid;
} io_uuid_spec_t;
/* Block specification - used to refer to data on a device supporting
diff --git a/include/drivers/marvell/mochi/cp110_setup.h b/include/drivers/marvell/mochi/cp110_setup.h
index 3686257..f8cd26b 100644
--- a/include/drivers/marvell/mochi/cp110_setup.h
+++ b/include/drivers/marvell/mochi/cp110_setup.h
@@ -51,5 +51,6 @@
void cp110_init(uintptr_t cp110_base, uint32_t stream_id);
void cp110_ble_init(uintptr_t cp110_base);
+void cp110_amb_init(uintptr_t base);
#endif /* CP110_SETUP_H */
diff --git a/include/lib/el3_runtime/aarch32/context.h b/include/lib/el3_runtime/aarch32/context.h
index c5567c9..5604c8e 100644
--- a/include/lib/el3_runtime/aarch32/context.h
+++ b/include/lib/el3_runtime/aarch32/context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -37,7 +37,7 @@
#define WORD_SHIFT U(2)
#define DEFINE_REG_STRUCT(name, num_regs) \
typedef struct name { \
- uint32_t _regs[num_regs]; \
+ uint32_t ctx_regs[num_regs]; \
} __aligned(8) name##_t
/* Constants to determine the size of individual context structures */
@@ -47,8 +47,8 @@
#undef CTX_REG_ALL
-#define read_ctx_reg(ctx, offset) ((ctx)->_regs[offset >> WORD_SHIFT])
-#define write_ctx_reg(ctx, offset, val) (((ctx)->_regs[offset >> WORD_SHIFT]) \
+#define read_ctx_reg(ctx, offset) ((ctx)->ctx_regs[offset >> WORD_SHIFT])
+#define write_ctx_reg(ctx, offset, val) (((ctx)->ctx_regs[offset >> WORD_SHIFT]) \
= val)
typedef struct cpu_context {
regs_t regs_ctx;
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 7a1f3a3..4158c02 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -230,7 +230,7 @@
#define DWORD_SHIFT U(3)
#define DEFINE_REG_STRUCT(name, num_regs) \
typedef struct name { \
- uint64_t _regs[num_regs]; \
+ uint64_t ctx_regs[num_regs]; \
} __aligned(16) name##_t
/* Constants to determine the size of individual context structures */
@@ -288,8 +288,8 @@
* Macros to access members of any of the above structures using their
* offsets
*/
-#define read_ctx_reg(ctx, offset) ((ctx)->_regs[(offset) >> DWORD_SHIFT])
-#define write_ctx_reg(ctx, offset, val) (((ctx)->_regs[(offset) >> DWORD_SHIFT]) \
+#define read_ctx_reg(ctx, offset) ((ctx)->ctx_regs[(offset) >> DWORD_SHIFT])
+#define write_ctx_reg(ctx, offset, val) (((ctx)->ctx_regs[(offset) >> DWORD_SHIFT]) \
= (uint64_t) (val))
/*
diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h
new file mode 100644
index 0000000..f58ff57
--- /dev/null
+++ b/include/lib/fconf/fconf.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_H
+#define FCONF_H
+
+#include <stdint.h>
+
+/* Public API */
+#define FCONF_GET_PROPERTY(a, b, c) a##__##b##_getter(c)
+
+#define FCONF_REGISTER_POPULATOR(name, callback) \
+ __attribute__((used, section(".fconf_populator"))) \
+ const struct fconf_populator name##__populator = { \
+ .info = #name, \
+ .populate = callback \
+ };
+
+/*
+ * Populator callback
+ *
+ * This structure are used by the fconf_populate function and should only be
+ * defined by the FCONF_REGISTER_POPULATOR macro.
+ */
+struct fconf_populator {
+ /* Description of the data loaded by the callback */
+ const char *info;
+
+ /* Callback used by fconf_populate function with a provided config dtb.
+ * Return 0 on success, err_code < 0 otherwise.
+ */
+ int (*populate)(uintptr_t config);
+};
+
+/* Load firmware configuration dtb */
+void fconf_load_config(void);
+
+/* Top level populate function
+ *
+ * This function takes a configuration dtb and calls all the registered
+ * populator callback with it.
+ *
+ * Panic on error.
+ */
+void fconf_populate(uintptr_t config);
+
+/* FCONF specific getter */
+#define fconf__dtb_getter(prop) fconf_dtb_info.prop
+
+/* Structure used to locally keep a reference to the config dtb. */
+struct fconf_dtb_info_t {
+ uintptr_t base_addr;
+ size_t size;
+};
+
+extern struct fconf_dtb_info_t fconf_dtb_info;
+
+#endif /* FCONF_H */
diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h
new file mode 100644
index 0000000..0fda8c9
--- /dev/null
+++ b/include/lib/fconf/fconf_dyn_cfg_getter.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_DYN_CFG_GETTER_H
+#define FCONF_DYN_CFG_GETTER_H
+
+#include <lib/fconf/fconf.h>
+
+/* Dynamic configuration related getter */
+#define dyn_cfg__dtb_getter(id) dyn_cfg_dtb_info_getter(id)
+
+struct dyn_cfg_dtb_info_t {
+ uintptr_t config_addr;
+ size_t config_max_size;
+ unsigned int config_id;
+};
+
+struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id);
+int fconf_populate_dtb_registry(uintptr_t config);
+
+#endif /* FCONF_DYN_CFG_GETTER_H */
diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h
new file mode 100644
index 0000000..eddc0c4
--- /dev/null
+++ b/include/lib/fconf/fconf_tbbr_getter.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_TBBR_GETTER_H
+#define FCONF_TBBR_GETTER_H
+
+#include <lib/fconf/fconf.h>
+
+/* TBBR related getter */
+#define tbbr__cot_getter(id) cot_desc_ptr[id]
+
+#define tbbr__dyn_config_getter(id) tbbr_dyn_config.id
+
+struct tbbr_dyn_config_t {
+ uint32_t disable_auth;
+ void *mbedtls_heap_addr;
+ size_t mbedtls_heap_size;
+};
+
+extern struct tbbr_dyn_config_t tbbr_dyn_config;
+
+int fconf_populate_tbbr_dyn_config(uintptr_t config);
+
+#endif /* FCONF_TBBR_GETTER_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index c825bf4..7df6b0d 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -229,6 +229,14 @@
ARM_EL3_TZC_DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
+#if defined(SPD_spmd)
+#define ARM_MAP_TRUSTED_DRAM MAP_REGION_FLAT( \
+ PLAT_ARM_TRUSTED_DRAM_BASE, \
+ PLAT_ARM_TRUSTED_DRAM_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+#endif
+
+
/*
* Mapping for the BL1 RW region. This mapping is needed by BL2 in order to
* share the Mbed TLS heap. Since the heap is allocated inside BL1, it resides
@@ -477,6 +485,12 @@
# define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
# define BL32_LIMIT (ARM_AP_TZC_DRAM1_BASE + \
ARM_AP_TZC_DRAM1_SIZE)
+# elif defined(SPD_spmd)
+# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
+# define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
+# define BL32_BASE PLAT_ARM_TRUSTED_DRAM_BASE
+# define BL32_LIMIT (PLAT_ARM_TRUSTED_DRAM_BASE \
+ + (UL(1) << 21))
# elif ARM_BL31_IN_DRAM
# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + \
PLAT_ARM_MAX_BL31_SIZE)
@@ -511,12 +525,12 @@
/*
* BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no
- * SPD and no SPM, as they are the only ones that can be used as BL32.
+ * SPD and no SPM-MM, as they are the only ones that can be used as BL32.
*/
#if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME
# if defined(SPD_none) && !SPM_MM
# undef BL32_BASE
-# endif /* defined(SPD_none) && !SPM_MM*/
+# endif /* defined(SPD_none) && !SPM_MM */
#endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */
/*******************************************************************************
diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h
index 3ad6d54..2dc94ab 100644
--- a/include/plat/arm/common/arm_dyn_cfg_helpers.h
+++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,12 +10,7 @@
#include <stdint.h>
/* Function declarations */
-int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id,
- uint64_t *config_addr, uint32_t *config_size);
int arm_dyn_tb_fw_cfg_init(void *dtb, int *node);
-int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth);
-int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
- size_t *heap_size);
int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr,
size_t heap_size);
diff --git a/include/plat/arm/common/arm_fconf_getter.h b/include/plat/arm/common/arm_fconf_getter.h
new file mode 100644
index 0000000..28913a4
--- /dev/null
+++ b/include/plat/arm/common/arm_fconf_getter.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARM_FCONF_GETTER
+#define ARM_FCONF_GETTER
+
+#include <lib/fconf/fconf.h>
+
+/* ARM io policies */
+#define arm__io_policies_getter(id) &policies[id]
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+extern struct plat_io_policy policies[];
+int fconf_populate_arm_io_policies(uintptr_t config);
+
+#endif /* ARM_FCONF_GETTER */
diff --git a/include/plat/arm/common/arm_fconf_io_storage.h b/include/plat/arm/common/arm_fconf_io_storage.h
new file mode 100644
index 0000000..02ee66c
--- /dev/null
+++ b/include/plat/arm/common/arm_fconf_io_storage.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ARM_FCONF_IO_STORAGE_H
+#define ARM_FCONF_IO_STORAGE_H
+
+#include <stdint.h>
+
+/* IO devices handle */
+extern uintptr_t memmap_dev_handle;
+extern uintptr_t fip_dev_handle;
+
+/* Function declarations */
+int open_fip(const uintptr_t spec);
+int open_memmap(const uintptr_t spec);
+
+#endif /* ARM_FCONF_IO_STORAGE_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 32dc9f9..025a64f 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -6,6 +6,7 @@
#ifndef PLAT_ARM_H
#define PLAT_ARM_H
+#include <stdbool.h>
#include <stdint.h>
#include <drivers/arm/tzc_common.h>
@@ -148,7 +149,7 @@
#define ARM_ROTPK_DEVEL_ECDSA_ID 3
/* IO storage utility functions */
-void arm_io_setup(void);
+int arm_io_setup(void);
/* Security utility functions */
void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions);
@@ -222,11 +223,9 @@
void arm_sp_min_plat_runtime_setup(void);
/* FIP TOC validity check */
-int arm_io_is_toc_valid(void);
+bool arm_io_is_toc_valid(void);
/* Utility functions for Dynamic Config */
-void arm_load_tb_fw_config(void);
-void arm_bl2_set_tb_cfg_addr(void *dtb);
void arm_bl2_dyn_cfg_init(void);
void arm_bl1_set_mbedtls_heap(void);
int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
@@ -256,7 +255,7 @@
void plat_arm_interconnect_enter_coherency(void);
void plat_arm_interconnect_exit_coherency(void);
void plat_arm_program_trusted_mailbox(uintptr_t address);
-int plat_arm_bl1_fwu_needed(void);
+bool plat_arm_bl1_fwu_needed(void);
__dead2 void plat_arm_error_handler(int err);
/*
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 332cfca..f5bd298 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,9 @@
#include <stdint.h>
#include <lib/psci/psci.h>
+#if defined(SPD_spmd)
+ #include <services/spm_core_manifest.h>
+#endif
/*******************************************************************************
* Forward declarations
@@ -272,7 +275,11 @@
int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size);
int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
void **rd_base, size_t *rd_size);
-
+#if defined(SPD_spmd)
+int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
+ const void *ptr,
+ size_t size);
+#endif
/*******************************************************************************
* Mandatory BL image load functions(may be overridden).
******************************************************************************/
diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h
new file mode 100644
index 0000000..49ba408
--- /dev/null
+++ b/include/services/spci_svc.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPCI_SVC_H
+#define SPCI_SVC_H
+
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <tools_share/uuid.h>
+
+/* SPCI error codes. */
+#define SPCI_ERROR_NOT_SUPPORTED -1
+#define SPCI_ERROR_INVALID_PARAMETER -2
+#define SPCI_ERROR_NO_MEMORY -3
+#define SPCI_ERROR_BUSY -4
+#define SPCI_ERROR_INTERRUPTED -5
+#define SPCI_ERROR_DENIED -6
+#define SPCI_ERROR_RETRY -7
+
+/* The macros below are used to identify SPCI calls from the SMC function ID */
+#define SPCI_FNUM_MIN_VALUE U(0x60)
+#define SPCI_FNUM_MAX_VALUE U(0x7f)
+#define is_spci_fid(fid) __extension__ ({ \
+ __typeof__(fid) _fid = (fid); \
+ ((GET_SMC_NUM(_fid) >= SPCI_FNUM_MIN_VALUE) && \
+ (GET_SMC_NUM(_fid) <= SPCI_FNUM_MAX_VALUE)); })
+
+/* SPCI_VERSION helpers */
+#define SPCI_VERSION_MAJOR U(0)
+#define SPCI_VERSION_MAJOR_SHIFT 16
+#define SPCI_VERSION_MAJOR_MASK U(0x7FFF)
+#define SPCI_VERSION_MINOR U(9)
+#define SPCI_VERSION_MINOR_SHIFT 0
+#define SPCI_VERSION_MINOR_MASK U(0xFFFF)
+
+#define MAKE_SPCI_VERSION(major, minor) \
+ ((((major) & SPCI_VERSION_MAJOR_MASK) << SPCI_VERSION_MAJOR_SHIFT) | \
+ (((minor) & SPCI_VERSION_MINOR_MASK) << SPCI_VERSION_MINOR_SHIFT))
+#define SPCI_VERSION_COMPILED MAKE_SPCI_VERSION(SPCI_VERSION_MAJOR, \
+ SPCI_VERSION_MINOR)
+
+/* SPCI_MSG_SEND helpers */
+#define SPCI_MSG_SEND_ATTRS_BLK_SHIFT U(0)
+#define SPCI_MSG_SEND_ATTRS_BLK_MASK U(0x1)
+#define SPCI_MSG_SEND_ATTRS_BLK U(0)
+#define SPCI_MSG_SEND_ATTRS_BLK_NOT U(1)
+#define SPCI_MSG_SEND_ATTRS(blk) \
+ (((blk) & SPCI_MSG_SEND_ATTRS_BLK_MASK) \
+ << SPCI_MSG_SEND_ATTRS_BLK_SHIFT)
+
+/* Get SPCI fastcall std FID from function number */
+#define SPCI_FID(smc_cc, func_num) \
+ ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ ((smc_cc) << FUNCID_CC_SHIFT) | \
+ (OEN_STD_START << FUNCID_OEN_SHIFT) | \
+ ((func_num) << FUNCID_NUM_SHIFT))
+
+/* SPCI function numbers */
+#define SPCI_FNUM_ERROR U(0x60)
+#define SPCI_FNUM_SUCCESS U(0x61)
+#define SPCI_FNUM_INTERRUPT U(0x62)
+#define SPCI_FNUM_VERSION U(0x63)
+#define SPCI_FNUM_FEATURES U(0x64)
+#define SPCI_FNUM_RX_RELEASE U(0x65)
+#define SPCI_FNUM_RXTX_MAP U(0x66)
+#define SPCI_FNUM_RXTX_UNMAP U(0x67)
+#define SPCI_FNUM_PARTITION_INFO_GET U(0x68)
+#define SPCI_FNUM_ID_GET U(0x69)
+#define SPCI_FNUM_MSG_POLL U(0x6A)
+#define SPCI_FNUM_MSG_WAIT U(0x6B)
+#define SPCI_FNUM_MSG_YIELD U(0x6C)
+#define SPCI_FNUM_MSG_RUN U(0x6D)
+#define SPCI_FNUM_MSG_SEND U(0x6E)
+#define SPCI_FNUM_MSG_SEND_DIRECT_REQ U(0x6F)
+#define SPCI_FNUM_MSG_SEND_DIRECT_RESP U(0x70)
+#define SPCI_FNUM_MEM_DONATE U(0x71)
+#define SPCI_FNUM_MEM_LEND U(0x72)
+#define SPCI_FNUM_MEM_SHARE U(0x73)
+#define SPCI_FNUM_MEM_RETRIEVE_REQ U(0x74)
+#define SPCI_FNUM_MEM_RETRIEVE_RESP U(0x75)
+#define SPCI_FNUM_MEM_RELINQUISH U(0x76)
+#define SPCI_FNUM_MEM_RECLAIM U(0x77)
+
+/* SPCI SMC32 FIDs */
+#define SPCI_ERROR SPCI_FID(SMC_32, SPCI_FNUM_ERROR)
+#define SPCI_SUCCESS_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_SUCCESS)
+#define SPCI_INTERRUPT SPCI_FID(SMC_32, SPCI_FNUM_INTERRUPT)
+#define SPCI_VERSION SPCI_FID(SMC_32, SPCI_FNUM_VERSION)
+#define SPCI_FEATURES SPCI_FID(SMC_32, SPCI_FNUM_FEATURES)
+#define SPCI_RX_RELEASE SPCI_FID(SMC_32, SPCI_FNUM_RX_RELEASE)
+#define SPCI_RXTX_MAP_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_RXTX_MAP)
+#define SPCI_RXTX_UNMAP SPCI_FID(SMC_32, SPCI_FNUM_RXTX_UNMAP)
+#define SPCI_PARTITION_INFO_GET SPCI_FID(SMC_32, SPCI_FNUM_PARTITION_INFO_GET)
+#define SPCI_ID_GET SPCI_FID(SMC_32, SPCI_FNUM_ID_GET)
+#define SPCI_MSG_POLL SPCI_FID(SMC_32, SPCI_FNUM_MSG_POLL)
+#define SPCI_MSG_WAIT SPCI_FID(SMC_32, SPCI_FNUM_MSG_WAIT)
+#define SPCI_MSG_YIELD SPCI_FID(SMC_32, SPCI_FNUM_MSG_YIELD)
+#define SPCI_MSG_RUN SPCI_FID(SMC_32, SPCI_FNUM_MSG_RUN)
+#define SPCI_MSG_SEND SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND)
+#define SPCI_MSG_SEND_DIRECT_REQ_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
+#define SPCI_MSG_SEND_DIRECT_RESP_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
+#define SPCI_MEM_DONATE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_DONATE)
+#define SPCI_MEM_LEND_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_LEND)
+#define SPCI_MEM_SHARE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_SHARE)
+#define SPCI_MEM_RETRIEVE_REQ_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_REQ)
+#define SPCI_MEM_RETRIEVE_RESP SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_RESP)
+#define SPCI_MEM_RELINQUISH SPCI_FID(SMC_32, SPCI_FNUM_MEM_RELINQUISH)
+#define SPCI_MEM_RECLAIM SPCI_FID(SMC_32, SPCI_FNUM_MEM_RECLAIM)
+
+/* SPCI SMC64 FIDs */
+#define SPCI_SUCCESS_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_SUCCESS)
+#define SPCI_RXTX_MAP_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_RXTX_MAP)
+#define SPCI_MSG_SEND_DIRECT_REQ_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
+#define SPCI_MSG_SEND_DIRECT_RESP_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
+#define SPCI_MEM_DONATE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_DONATE)
+#define SPCI_MEM_LEND_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_LEND)
+#define SPCI_MEM_SHARE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_SHARE)
+#define SPCI_MEM_RETRIEVE_REQ_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MEM_RETRIEVE_REQ)
+
+/*
+ * Reserve a special value for traffic targeted to the Hypervisor or SPM.
+ */
+#define SPCI_TARGET_INFO_MBZ U(0x0)
+
+/*
+ * Reserve a special value for MBZ parameters.
+ */
+#define SPCI_PARAM_MBZ U(0x0)
+
+#endif /* SPCI_SVC_H */
diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h
new file mode 100644
index 0000000..06ecc13
--- /dev/null
+++ b/include/services/spm_core_manifest.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_MANIFEST_H
+#define SPMC_MANIFEST_H
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Attribute Section
+ ******************************************************************************/
+
+typedef struct spm_core_manifest_sect_attribute {
+ /*
+ * SPCI version (mandatory).
+ */
+ uint32_t major_version;
+ uint32_t minor_version;
+
+ /*
+ * Run-Time Exception Level (mandatory):
+ * - 1: SEL1
+ * - 2: SEL2
+ */
+ uint32_t runtime_el;
+
+ /*
+ * Run-Time Execution state (optional):
+ * - 0: AArch64 (default)
+ * - 1: AArch32
+ */
+ uint32_t exec_state;
+
+ /*
+ * Address of binary image containing SPM core in bytes (optional).
+ */
+ uint64_t load_address;
+
+ /*
+ * Offset from the base of the partition's binary image to the entry
+ * point of the partition.
+ */
+ uint64_t entrypoint;
+
+ /*
+ * Size of binary image containing SPM core in bytes (mandatory).
+ */
+ uint32_t binary_size;
+
+} spmc_manifest_sect_attribute_t;
+
+#endif /* SPMC_MANIFEST_H */
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
new file mode 100644
index 0000000..6e4caf2
--- /dev/null
+++ b/include/services/spmd_svc.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMD_SVC_H
+#define SPMD_SVC_H
+
+#ifndef __ASSEMBLER__
+#include <services/spci_svc.h>
+#include <stdint.h>
+
+int32_t spmd_setup(void);
+uint64_t spmd_smc_handler(uint32_t smc_fid,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPMD_SVC_H */
diff --git a/include/tools_share/uuid.h b/include/tools_share/uuid.h
index 7d00432..36be9ed 100644
--- a/include/tools_share/uuid.h
+++ b/include/tools_share/uuid.h
@@ -27,7 +27,7 @@
*/
/*
- * Portions copyright (c) 2014, ARM Limited and Contributors.
+ * Portions copyright (c) 2014-2020, ARM Limited and Contributors.
* All rights reserved.
*/
@@ -56,6 +56,11 @@
uint8_t node[_UUID_NODE_LEN];
};
+union uuid_helper_t {
+ struct uuid uuid_struct;
+ uint32_t word[4];
+};
+
/* XXX namespace pollution? */
typedef struct uuid uuid_t;
diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c
new file mode 100644
index 0000000..a6da56b
--- /dev/null
+++ b/lib/fconf/fconf.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <lib/fconf/fconf.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+struct fconf_dtb_info_t fconf_dtb_info;
+
+void fconf_load_config(void)
+{
+ int err;
+ /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */
+ image_info_t arm_tb_fw_info = {
+ .h.type = (uint8_t)PARAM_IMAGE_BINARY,
+ .h.version = (uint8_t)VERSION_2,
+ .h.size = (uint16_t)sizeof(image_info_t),
+ .h.attr = 0,
+ .image_base = ARM_TB_FW_CONFIG_BASE,
+ .image_max_size = (uint32_t)
+ (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE)
+ };
+
+ VERBOSE("FCONF: Loading FW_CONFIG\n");
+ err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info);
+ if (err != 0) {
+ /* Return if FW_CONFIG is not loaded */
+ VERBOSE("Failed to load FW_CONFIG\n");
+ return;
+ }
+
+ /* At this point we know that a DTB is indeed available */
+ fconf_dtb_info.base_addr = arm_tb_fw_info.image_base;
+ fconf_dtb_info.size = (size_t)arm_tb_fw_info.image_size;
+
+#if !BL2_AT_EL3
+ image_desc_t *desc;
+
+ /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
+ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+ assert(desc != NULL);
+ desc->ep_info.args.arg0 = arm_tb_fw_info.image_base;
+#endif
+
+ INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base);
+}
+
+void fconf_populate(uintptr_t config)
+{
+ assert(config != 0UL);
+
+ /* Check if the pointer to DTB is correct */
+ if (fdt_check_header((void *)config) != 0) {
+ ERROR("FCONF: Invalid DTB file passed for FW_CONFIG\n");
+ panic();
+ }
+
+ INFO("FCONF: Reading firmware configuration file from: 0x%lx\n", config);
+
+ /* Go through all registered populate functions */
+ IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_START__, start);
+ IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_END__, end);
+ const struct fconf_populator *populator;
+
+ for (populator = start; populator != end; populator++) {
+ assert((populator->info != NULL) && (populator->populate != NULL));
+
+ INFO("FCONF: Reading firmware configuration information for: %s\n", populator->info);
+ if (populator->populate(config) != 0) {
+ /* TODO: handle property miss */
+ panic();
+ }
+ }
+
+ /* save local pointer to the config dtb */
+ fconf_dtb_info.base_addr = config;
+}
diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk
new file mode 100644
index 0000000..7031969
--- /dev/null
+++ b/lib/fconf/fconf.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Add Firmware Configuration files
+FCONF_SOURCES := lib/fconf/fconf.c \
+ lib/fconf/fconf_dyn_cfg_getter.c
+
+BL1_SOURCES += ${FCONF_SOURCES}
+BL2_SOURCES += ${FCONF_SOURCES}
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
new file mode 100644
index 0000000..d313a56
--- /dev/null
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+
+/* We currently use TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */
+#define MAX_DTB_INFO U(5)
+
+static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO];
+static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos);
+
+struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id)
+{
+ unsigned int index;
+ struct dyn_cfg_dtb_info_t *info;
+
+ /* Positions index to the proper config-id */
+ for (index = 0; index < MAX_DTB_INFO; index++) {
+ if (dtb_infos[index].config_id == config_id) {
+ info = &dtb_infos[index];
+ break;
+ }
+ }
+
+ if (index == MAX_DTB_INFO) {
+ WARN("FCONF: Invalid config id %u\n", config_id);
+ info = NULL;
+ }
+
+ return info;
+}
+
+int fconf_populate_dtb_registry(uintptr_t config)
+{
+ int rc;
+ int node, child;
+ struct dyn_cfg_dtb_info_t *dtb_info;
+
+ /* As libfdt use void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Find the node offset point to "arm,dyn_cfg-dtb_registry" compatible property */
+ const char *compatible_str = "arm,dyn_cfg-dtb_registry";
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ fdt_for_each_subnode(child, dtb, node) {
+ dtb_info = pool_alloc(&dtb_info_pool);
+
+ /* Read configuration dtb information */
+ rc = fdtw_read_cells(dtb, child, "load-address", 2, &dtb_info->config_addr);
+ if (rc < 0) {
+ ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
+ return rc;
+ }
+
+ rc = fdtw_read_cells(dtb, child, "max-size", 1, &dtb_info->config_max_size);
+ if (rc < 0) {
+ ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
+ return rc;
+ }
+
+ rc = fdtw_read_cells(dtb, child, "id", 1, &dtb_info->config_id);
+ if (rc < 0) {
+ ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
+ return rc;
+ }
+
+ VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n");
+ VERBOSE("\tload-address = %lx\n", dtb_info->config_addr);
+ VERBOSE("\tmax-size = 0x%zx\n", dtb_info->config_max_size);
+ VERBOSE("\tconfig-id = %u\n", dtb_info->config_id);
+ }
+
+ if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
+ ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
+ return child;
+ }
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(dyn_cfg, fconf_populate_dtb_registry);
diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c
new file mode 100644
index 0000000..c6df9c8
--- /dev/null
+++ b/lib/fconf/fconf_tbbr_getter.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <lib/fconf/fconf_tbbr_getter.h>
+#include <libfdt.h>
+
+struct tbbr_dyn_config_t tbbr_dyn_config;
+
+int fconf_populate_tbbr_dyn_config(uintptr_t config)
+{
+ int err;
+ int node;
+
+ /* As libfdt use void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Assert the node offset point to "arm,tb_fw" compatible property */
+ const char *compatible_str = "arm,tb_fw";
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ /* Locate the disable_auth cell and read the value */
+ err = fdtw_read_cells(dtb, node, "disable_auth", 1, &tbbr_dyn_config.disable_auth);
+ if (err < 0) {
+ WARN("FCONF: Read cell failed for `disable_auth`\n");
+ return err;
+ }
+
+ /* Check if the value is boolean */
+ if ((tbbr_dyn_config.disable_auth != 0U) && (tbbr_dyn_config.disable_auth != 1U)) {
+ WARN("Invalid value for `disable_auth` cell %d\n", tbbr_dyn_config.disable_auth);
+ return -1;
+ }
+
+#if defined(DYN_DISABLE_AUTH)
+ if (tbbr_dyn_config.disable_auth == 1)
+ dyn_disable_auth();
+#endif
+
+ /* Retrieve the Mbed TLS heap details from the DTB */
+ err = fdtw_read_cells(dtb, node,
+ "mbedtls_heap_addr", 2, &tbbr_dyn_config.mbedtls_heap_addr);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for mbedtls_heap\n");
+ return err;
+ }
+
+ err = fdtw_read_cells(dtb, node,
+ "mbedtls_heap_size", 1, &tbbr_dyn_config.mbedtls_heap_size);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for mbedtls_heap\n");
+ return err;
+ }
+
+ VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n",
+ tbbr_dyn_config.disable_auth);
+ VERBOSE("FCONF:tbbr.mbedtls_heap_addr cell found with value = %p\n",
+ tbbr_dyn_config.mbedtls_heap_addr);
+ VERBOSE("FCONF:tbbr.mbedtls_heap_size cell found with value = %zu\n",
+ tbbr_dyn_config.mbedtls_heap_size);
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(tbbr, fconf_populate_tbbr_dyn_config);
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 5ab15c6..cced276 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -601,7 +601,7 @@
unsigned int level;
/* Unlock top down. No unlocking required for level 0. */
- for (level = end_pwrlvl; level >= PSCI_CPU_PWR_LVL + 1U; level--) {
+ for (level = end_pwrlvl; level >= (PSCI_CPU_PWR_LVL + 1U); level--) {
parent_idx = parent_nodes[level - 1U];
psci_lock_release(&psci_non_cpu_pd_nodes[parent_idx]);
}
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 1fa26cc..b6925d3 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -67,6 +67,17 @@
$(if $(__numeric),$(error $(1) must be numeric))
endef
+# CREATE_SEQ is a recursive function to create sequence of numbers from 1 to
+# $(2) and assign the sequence to $(1)
+define CREATE_SEQ
+$(if $(word $(2), $($(1))),\
+ $(eval $(1) += $(words $($(1))))\
+ $(eval $(1) := $(filter-out 0,$($(1)))),\
+ $(eval $(1) += $(words $($(1))))\
+ $(call CREATE_SEQ,$(1),$(2))\
+)
+endef
+
# IMG_LINKERFILE defines the linker script corresponding to a BL stage
# $(1) = BL stage (2, 30, 31, 32, 33)
define IMG_LINKERFILE
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index fff336c..e8e990d 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -201,6 +201,9 @@
# Build option to add debugfs support
USE_DEBUGFS := 0
+# Build option to fconf based io
+USE_FCONF_BASED_IO := 0
+
# Build option to choose whether Trusted Firmware uses library at ROM
USE_ROMLIB := 0
diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
new file mode 100644
index 0000000..2f2d265
--- /dev/null
+++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained in this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x2001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x83000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ };
+};
diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
deleted file mode 100644
index 7b3aa11..0000000
--- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- plat_arm_bl2 {
- compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x83000000>;
- hw_config_max_size = <0x01000000>;
- /* Disable authentication for development */
- disable_auth = <0x0>;
- };
-};
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index d42b2bf..7198842 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -1,9 +1,12 @@
#
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
+
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
@@ -67,7 +70,7 @@
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
ifdef UNIX_MK
-FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb
+FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
@@ -77,7 +80,7 @@
# Add the HW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
-FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \
+FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \
${FVP_HW_CONFIG_DTS}
endif
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index da63430..459156b 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -17,7 +17,7 @@
ifeq (${ARM_ROTPK_LOCATION}, regs)
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
- KEY_ALG := rsa
+ CRYPTO_ALG=rsa
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
@@ -25,7 +25,7 @@
$(warning Development keys support for FVP is deprecated. Use `regs` \
option instead)
else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
- KEY_ALG := ecdsa
+ CRYPTO_ALG=ec
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
@@ -50,7 +50,7 @@
ifndef ROT_KEY
$(error Cannot generate hash: no ROT_KEY defined)
endif
- openssl rsa -in $< -pubout -outform DER | openssl dgst \
+ openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | openssl dgst \
-sha256 -binary > $@
# Certificate NV-Counters. Use values corresponding to tied off values in
diff --git a/plat/arm/board/corstone700/corstone700_plat.c b/plat/arm/board/corstone700/corstone700_plat.c
index cee6fd6..e2ade70 100644
--- a/plat/arm/board/corstone700/corstone700_plat.c
+++ b/plat/arm/board/corstone700/corstone700_plat.c
@@ -1,10 +1,12 @@
/*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/bl_common.h>
+
+#include <mhu.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
@@ -26,6 +28,7 @@
*/
void __init plat_arm_pwrc_setup(void)
{
+ mhu_secure_init();
}
unsigned int plat_get_syscnt_freq2(void)
diff --git a/plat/arm/board/corstone700/corstone700_stack_protector.c b/plat/arm/board/corstone700/corstone700_stack_protector.c
new file mode 100644
index 0000000..6fd09da
--- /dev/null
+++ b/plat/arm/board/corstone700/corstone700_stack_protector.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <plat/common/platform.h>
+
+static uint32_t plat_generate_random_number(void)
+{
+ uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U);
+ uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U);
+ uint64_t cntpct = read_cntpct_el0();
+
+ /* Generate 32-bit pattern: saving the 2 least significant bytes
+ * in random_lo and random_hi
+ */
+ uint16_t random_lo = (uint16_t)(
+ (((uint64_t)return_addr) << 13) ^ frame_addr ^ cntpct
+ );
+
+ uint16_t random_hi = (uint16_t)(
+ (((uint64_t)frame_addr) << 15) ^ return_addr ^ cntpct
+ );
+
+ return (((uint32_t)random_hi) << 16) | random_lo;
+}
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ return plat_generate_random_number(); /* a 32-bit pattern is returned */
+}
diff --git a/plat/arm/board/corstone700/corstone700_topology.c b/plat/arm/board/corstone700/corstone700_topology.c
index d9445e0..904f5ab 100644
--- a/plat/arm/board/corstone700/corstone700_topology.c
+++ b/plat/arm/board/corstone700/corstone700_topology.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,8 +8,8 @@
#include <plat/common/platform.h>
/* The Corstone700 power domain tree descriptor */
-static unsigned char corstone700_power_domain_tree_desc
- [PLAT_ARM_CLUSTER_COUNT + 2];
+static unsigned char corstone700_power_domain_tree_desc[PLAT_ARM_CLUSTER_COUNT
+ + 2];
/*******************************************************************************
* This function dynamically constructs the topology according to
* CLUSTER_COUNT and returns it.
diff --git a/plat/arm/board/corstone700/drivers/mhu/mhu.c b/plat/arm/board/corstone700/drivers/mhu/mhu.c
new file mode 100644
index 0000000..2231d11
--- /dev/null
+++ b/plat/arm/board/corstone700/drivers/mhu/mhu.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+
+#include "mhu.h"
+#include <plat_arm.h>
+#include <platform_def.h>
+
+ARM_INSTANTIATE_LOCK;
+
+#pragma weak plat_arm_pwrc_setup
+
+/*
+ * Slot 31 is reserved because the MHU hardware uses this register bit to
+ * indicate a non-secure access attempt. The total number of available slots is
+ * therefore 31 [30:0].
+ */
+#define MHU_MAX_SLOT_ID 30
+
+void mhu_secure_message_start(uintptr_t address, unsigned int slot_id)
+{
+ unsigned int intr_stat_check;
+ uint64_t timeout_cnt;
+ volatile uint8_t expiration;
+
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+ arm_lock_get();
+
+ /*
+ * Make sure any previous command has finished
+ * and polling timeout not expired
+ */
+
+ timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT);
+
+ do {
+ intr_stat_check = (mmio_read_32(address + CPU_INTR_S_STAT) &
+ (1 << slot_id));
+
+ expiration = timeout_elapsed(timeout_cnt);
+
+ } while ((intr_stat_check != 0U) && (expiration == 0U));
+
+ /*
+ * Note: No risk of timer overflows while waiting
+ * for the timeout expiration.
+ * According to Armv8 TRM: System counter roll-over
+ * time of not less than 40 years
+ */
+}
+
+void mhu_secure_message_send(uintptr_t address,
+ unsigned int slot_id,
+ unsigned int message)
+{
+ unsigned char access_ready;
+ uint64_t timeout_cnt;
+ volatile uint8_t expiration;
+
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+ assert((mmio_read_32(address + CPU_INTR_S_STAT) &
+ (1 << slot_id)) == 0U);
+
+ MHU_V2_ACCESS_REQUEST(address);
+
+ timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT);
+
+ do {
+ access_ready = MHU_V2_IS_ACCESS_READY(address);
+ expiration = timeout_elapsed(timeout_cnt);
+
+ } while ((access_ready == 0U) && (expiration == 0U));
+
+ /*
+ * Note: No risk of timer overflows while waiting
+ * for the timeout expiration.
+ * According to Armv8 TRM: System counter roll-over
+ * time of not less than 40 years
+ */
+
+ mmio_write_32(address + CPU_INTR_S_SET, message);
+}
+
+void mhu_secure_message_end(uintptr_t address, unsigned int slot_id)
+{
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+ /*
+ * Clear any response we got by writing one in the relevant slot bit to
+ * the CLEAR register
+ */
+ MHU_V2_CLEAR_REQUEST(address);
+
+ arm_lock_release();
+}
+
+void __init mhu_secure_init(void)
+{
+ arm_lock_init();
+
+ /*
+ * The STAT register resets to zero. Ensure it is in the expected state,
+ * as a stale or garbage value would make us think it's a message we've
+ * already sent.
+ */
+
+ assert(mmio_read_32(PLAT_SDK700_MHU0_SEND + CPU_INTR_S_STAT) == 0);
+}
diff --git a/plat/arm/board/corstone700/drivers/mhu/mhu.h b/plat/arm/board/corstone700/drivers/mhu/mhu.h
new file mode 100644
index 0000000..3808746
--- /dev/null
+++ b/plat/arm/board/corstone700/drivers/mhu/mhu.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MHU_H
+#define MHU_H
+
+#define MHU_POLL_INTR_STAT_TIMEOUT 50000 /*timeout value in us*/
+
+/* CPU MHU secure channel registers */
+#define CPU_INTR_S_STAT 0x00
+#define CPU_INTR_S_SET 0x0C
+
+/* MHUv2 Control Registers Offsets */
+#define MHU_V2_MSG_CFG_OFFSET 0xF80
+#define MHU_V2_ACCESS_REQ_OFFSET 0xF88
+#define MHU_V2_ACCESS_READY_OFFSET 0xF8C
+
+#define MHU_V2_ACCESS_REQUEST(addr) \
+ mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1)
+
+#define MHU_V2_CLEAR_REQUEST(addr) \
+ mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0)
+
+#define MHU_V2_IS_ACCESS_READY(addr) \
+ (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1)
+
+void mhu_secure_message_start(uintptr_t address, unsigned int slot_id);
+void mhu_secure_message_send(uintptr_t address,
+ unsigned int slot_id,
+ unsigned int message);
+void mhu_secure_message_end(uintptr_t address, unsigned int slot_id);
+void mhu_secure_init(void);
+
+#endif /* MHU_H */
diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h
index 8dff3ec..0fb74e4 100644
--- a/plat/arm/board/corstone700/include/platform_def.h
+++ b/plat/arm/board/corstone700/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,20 +9,35 @@
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
+
#include <plat/arm/board/common/v2m_def.h>
#include <plat/arm/common/arm_spm_def.h>
#include <plat/common/common_def.h>
+/* PL011 UART related constants */
+#ifdef V2M_IOFPGA_UART0_CLK_IN_HZ
+#undef V2M_IOFPGA_UART0_CLK_IN_HZ
+#endif
+
+#ifdef V2M_IOFPGA_UART1_CLK_IN_HZ
+#undef V2M_IOFPGA_UART1_CLK_IN_HZ
+#endif
+
+#define V2M_IOFPGA_UART0_CLK_IN_HZ 32000000
+#define V2M_IOFPGA_UART1_CLK_IN_HZ 32000000
+
/* Core/Cluster/Thread counts for Corstone700 */
#define CORSTONE700_CLUSTER_COUNT U(1)
#define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4)
#define CORSTONE700_MAX_PE_PER_CPU U(1)
-#define CORSTONE700_CORE_COUNT (CORSTONE700_CLUSTER_COUNT * \
- CORSTONE700_MAX_CPUS_PER_CLUSTER * \
- CORSTONE700_MAX_PE_PER_CPU)
-#define PLATFORM_CORE_COUNT CORSTONE700_CORE_COUNT
+
#define PLAT_ARM_CLUSTER_COUNT CORSTONE700_CLUSTER_COUNT
+#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
+ CORSTONE700_MAX_CPUS_PER_CLUSTER * \
+ CORSTONE700_MAX_PE_PER_CPU)
+
+
/* UART related constants */
#define PLAT_ARM_BOOT_UART_BASE 0x1a510000
#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ
@@ -85,8 +100,12 @@
ARM_BL_REGIONS)
/* GIC related constants */
-#define PLAT_ARM_GICD_BASE 0x1C010000
-#define PLAT_ARM_GICC_BASE 0x1C02F000
+#define PLAT_ARM_GICD_BASE 0x1C010000
+#define PLAT_ARM_GICC_BASE 0x1C02F000
+
+/* MHUv2 Secure Channel receiver and sender */
+#define PLAT_SDK700_MHU0_SEND 0x1B800000
+#define PLAT_SDK700_MHU0_RECV 0x1B810000
/* Timer/watchdog related constants */
#define ARM_SYS_CNTCTL_BASE UL(0x1a200000)
@@ -101,46 +120,46 @@
* Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The
* power levels have a 1:1 mapping with the MPIDR affinity levels.
*/
-#define ARM_PWR_LVL0 MPIDR_AFFLVL0
-#define ARM_PWR_LVL1 MPIDR_AFFLVL1
-#define ARM_PWR_LVL2 MPIDR_AFFLVL2
+#define ARM_PWR_LVL0 MPIDR_AFFLVL0
+#define ARM_PWR_LVL1 MPIDR_AFFLVL1
+#define ARM_PWR_LVL2 MPIDR_AFFLVL2
/*
* Macros for local power states in ARM platforms encoded by State-ID field
* within the power-state parameter.
*/
/* Local power state for power domains in Run state. */
-#define ARM_LOCAL_STATE_RUN U(0)
+#define ARM_LOCAL_STATE_RUN U(0)
/* Local power state for retention. Valid only for CPU power domains */
-#define ARM_LOCAL_STATE_RET U(1)
+#define ARM_LOCAL_STATE_RET U(1)
/* Local power state for OFF/power-down. Valid for CPU and cluster
* power domains
*/
-#define ARM_LOCAL_STATE_OFF U(2)
+#define ARM_LOCAL_STATE_OFF U(2)
-#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
-#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
+#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
+#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
-#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000))
+#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000))
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
/*
* This macro defines the deepest retention state possible. A higher state
* ID will represent an invalid or a power down state.
*/
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_RET_STATE 1
/*
* This macro defines the deepest power down states possible. Any state ID
* higher than this is invalid.
*/
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_OFF_STATE 2
-#define PLATFORM_STACK_SIZE UL(0x440)
+#define PLATFORM_STACK_SIZE UL(0x440)
-#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
+#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
ARM_SHARED_RAM_BASE, \
ARM_SHARED_RAM_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
@@ -170,21 +189,21 @@
#define CORSTONE700_DEVICE_BASE (0x1A000000)
#define CORSTONE700_DEVICE_SIZE (0x26000000)
-#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \
- CORSTONE700_DEVICE_BASE, \
- CORSTONE700_DEVICE_SIZE, \
- MT_DEVICE | MT_RW | MT_SECURE)
+#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \
+ CORSTONE700_DEVICE_BASE,\
+ CORSTONE700_DEVICE_SIZE,\
+ MT_DEVICE | MT_RW | MT_SECURE)
-#define ARM_IRQ_SEC_PHY_TIMER 29
+#define ARM_IRQ_SEC_PHY_TIMER 29
-#define ARM_IRQ_SEC_SGI_0 8
-#define ARM_IRQ_SEC_SGI_1 9
-#define ARM_IRQ_SEC_SGI_2 10
-#define ARM_IRQ_SEC_SGI_3 11
-#define ARM_IRQ_SEC_SGI_4 12
-#define ARM_IRQ_SEC_SGI_5 13
-#define ARM_IRQ_SEC_SGI_6 14
-#define ARM_IRQ_SEC_SGI_7 15
+#define ARM_IRQ_SEC_SGI_0 8
+#define ARM_IRQ_SEC_SGI_1 9
+#define ARM_IRQ_SEC_SGI_2 10
+#define ARM_IRQ_SEC_SGI_3 11
+#define ARM_IRQ_SEC_SGI_4 12
+#define ARM_IRQ_SEC_SGI_5 13
+#define ARM_IRQ_SEC_SGI_6 14
+#define ARM_IRQ_SEC_SGI_7 15
/*
* Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3
@@ -192,7 +211,7 @@
* as Group 0 interrupts.
*/
#define ARM_G1S_IRQ_PROPS(grp) \
- INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
(grp), GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \
(grp), GIC_INTR_CFG_EDGE), \
@@ -217,11 +236,11 @@
* as Group 0 interrupts.
*/
#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
- ARM_G1S_IRQ_PROPS(grp), \
- INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, \
- GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL), \
- INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \
- GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) \
+ ARM_G1S_IRQ_PROPS(grp), \
+ INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \
+ GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL)
#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk
index bff3589..a4d4f22 100644
--- a/plat/arm/board/corstone700/platform.mk
+++ b/plat/arm/board/corstone700/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -11,16 +11,19 @@
plat/arm/common/arm_common.c \
lib/xlat_tables/aarch32/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
- ${CORSTONE700_CPU_LIBS}
+ ${CORSTONE700_CPU_LIBS} \
+ plat/arm/board/corstone700/drivers/mhu/mhu.c
-PLAT_INCLUDES := -Iplat/arm/board/corstone700/include
+PLAT_INCLUDES := -Iplat/arm/board/corstone700/include \
+ -Iinclude/plat/arm/common \
+ -Iplat/arm/board/corstone700/drivers/mhu
NEED_BL32 := yes
-CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- plat/common/plat_gicv2.c \
+CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ plat/common/plat_gicv2.c \
plat/arm/common/arm_gicv2.c
# BL1/BL2 Image not a part of the capsule Image for Corstone700
diff --git a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
index 57e1ec3..acee6c3 100644
--- a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
+++ b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -15,4 +15,10 @@
plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c \
${CORSTONE700_GIC_SOURCES}
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+ ifneq (${ENABLE_STACK_PROTECTOR},none)
+ BL32_SOURCES += plat/arm/board/corstone700/corstone700_stack_protector.c
+ endif
+endif
+
include plat/arm/common/sp_min/arm_sp_min.mk
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
new file mode 100644
index 0000000..d0f6033
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x4001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x82000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+
+ /*
+ * Load SoC and TOS firmware configs at the base of
+ * non shared SRAM. The runtime checks ensure we don't
+ * overlap BL2, BL31 or BL32. The NT firmware config
+ * is loaded at base of DRAM.
+ */
+ soc_fw-config {
+ load-address = <0x0 0x04001000>;
+ max-size = <0x200>;
+ id = <SOC_FW_CONFIG_ID>;
+ };
+
+ tos_fw-config {
+ load-address = <0x0 0x04001200>;
+ max-size = <0x200>;
+ id = <TOS_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0x80000000>;
+ max-size = <0x200>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+
+ arm-io_policies {
+ fip-handles {
+ compatible = "arm,io-fip-handle";
+ scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>;
+ bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>;
+ bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>;
+ bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>;
+ bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>;
+ bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>;
+ hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>;
+ soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>;
+ tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>;
+ nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>;
+ t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>;
+ scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>;
+ soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>;
+ tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>;
+ nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>;
+ scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>;
+ soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>;
+ tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>;
+ nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>;
+ };
+ };
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
new file mode 100644
index 0000000..e1c106f
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+/ {
+ compatible = "spci-core-manifest-1.0";
+
+ attribute {
+ maj_ver = <0x0>;
+ min_ver = <0x9>;
+ runtime_el = <0x1>;
+ exec_state = <0x0>;
+ load_address = <0x0 0x6000000>;
+ entrypoint = <0x0 0x6000000>;
+ };
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
deleted file mode 100644
index ce58938..0000000
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- plat_arm_bl2 {
- compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x82000000>;
- hw_config_max_size = <0x01000000>;
- /* Disable authentication for development */
- disable_auth = <0x0>;
- /*
- * Load SoC and TOS firmware configs at the base of
- * non shared SRAM. The runtime checks ensure we don't
- * overlap BL2, BL31 or BL32. The NT firmware config
- * is loaded at base of DRAM.
- */
- soc_fw_config_addr = <0x0 0x04001000>;
- soc_fw_config_max_size = <0x200>;
- tos_fw_config_addr = <0x0 0x04001200>;
- tos_fw_config_max_size = <0x200>;
- nt_fw_config_addr = <0x0 0x80000000>;
- nt_fw_config_max_size = <0x200>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
- };
-};
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index ffaa93d..2c880fc 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -86,6 +86,9 @@
#ifdef __aarch64__
ARM_MAP_DRAM2,
#endif
+#if defined(SPD_spmd)
+ ARM_MAP_TRUSTED_DRAM,
+#endif
#ifdef SPD_tspd
ARM_MAP_TSP_SEC_MEM,
#endif
diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c
index 9c4c1d5..109d321 100644
--- a/plat/arm/board/fvp/fvp_io_storage.c
+++ b/plat/arm/board/fvp/fvp_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -120,18 +120,22 @@
{
int io_result;
- arm_io_setup();
+ io_result = arm_io_setup();
+ if (io_result < 0) {
+ panic();
+ }
/* Register the additional IO devices on this platform */
io_result = register_io_dev_sh(&sh_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ panic();
+ }
/* Open connections to devices and cache the handles */
io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
- assert(io_result == 0);
-
- /* Ignore improbable errors in release builds */
- (void)io_result;
+ if (io_result < 0) {
+ panic();
+ }
}
/*
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 602ea6d..bfe207a 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -116,12 +116,18 @@
# define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - FVP_BL2_ROMLIB_OPTIMIZATION)
#endif
+#if RESET_TO_BL31
+/* Size of Trusted SRAM - the first 4KB of shared memory */
+#define PLAT_ARM_MAX_BL31_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \
+ ARM_SHARED_RAM_SIZE)
+#else
/*
* Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
* calculated using the current BL31 PROGBITS debug size plus the sizes of
* BL2 and BL1-RW
*/
#define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000)
+#endif /* RESET_TO_BL31 */
#ifndef __aarch64__
/*
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 6ccdd28..b1b9ed4 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -20,6 +20,8 @@
fdt fdt_check_header
fdt fdt_node_offset_by_compatible
fdt fdt_setprop_inplace_namelen_partial
+fdt fdt_first_subnode
+fdt fdt_next_subnode
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 6fb34c4..6037435 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -10,6 +10,11 @@
# Use the SP804 timer instead of the generic one
FVP_USE_SP804_TIMER := 0
+# Use fconf based io for FVP
+ifeq ($(BL2_AT_EL3), 0)
+USE_FCONF_BASED_IO := 1
+endif
+
# Default cluster count for FVP
FVP_CLUSTER_COUNT := 2
@@ -205,12 +210,12 @@
ifdef UNIX_MK
FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts
FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \
- ${PLAT}_tb_fw_config.dts \
+ ${PLAT}_fw_config.dts \
${PLAT}_soc_fw_config.dts \
${PLAT}_nt_fw_config.dts \
)
-FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
@@ -222,6 +227,14 @@
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config))
endif
+ifeq (${SPD},spmd)
+FDT_SOURCES += plat/arm/board/fvp/fdts/${PLAT}_spmc_manifest.dts
+FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb
+
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config))
+endif
+
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
new file mode 100644
index 0000000..147c8f3
--- /dev/null
+++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x80001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x82000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ };
+};
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
deleted file mode 100644
index 9ab2d96..0000000
--- a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- plat_arm_bl2 {
- compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x82000000>;
- hw_config_max_size = <0x01000000>;
- /* Disable authentication for development */
- disable_auth = <0x0>;
- };
-};
diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk
index 4d21f4b..7883719 100644
--- a/plat/arm/board/fvp_ve/platform.mk
+++ b/plat/arm/board/fvp_ve/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -72,9 +72,9 @@
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
ifdef UNIX_MK
-FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
+FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
-FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb
+FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
@@ -116,6 +116,9 @@
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
+
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
new file mode 100644
index 0000000..cab6f2b
--- /dev/null
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x4001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ /* Platform Config */
+ compatible = "arm,tb_fw";
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
deleted file mode 100644
index a8ab6c5..0000000
--- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- /* Disable authentication for development */
- disable_auth = <0x0>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
-};
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 6ccdd28..b1b9ed4 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -20,6 +20,8 @@
fdt fdt_check_header
fdt fdt_node_offset_by_compatible
fdt fdt_setprop_inplace_namelen_partial
+fdt fdt_first_subnode
+fdt fdt_next_subnode
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 89398d6..25a27da 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -60,17 +60,13 @@
* The following function checks if Firmware update is needed,
* by checking if TOC in FIP image is valid or watchdog reset happened.
******************************************************************************/
-int plat_arm_bl1_fwu_needed(void)
+bool plat_arm_bl1_fwu_needed(void)
{
const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR;
/* Check if TOC is invalid or watchdog reset happened. */
- if ((arm_io_is_toc_valid() != 1) ||
- (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT))
- && is_watchdog_reset()))
- return 1;
-
- return 0;
+ return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) ||
+ (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset()));
}
/*******************************************************************************
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index a85ad53..27650d2 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -156,8 +156,8 @@
endif
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts
-TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts
new file mode 100644
index 0000000..81e4cc1
--- /dev/null
+++ b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x4001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts
deleted file mode 100644
index 9acec13..0000000
--- a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- nt_fw_config_addr = <0x0 0xFEF00000>;
- nt_fw_config_max_size = <0x0100000>;
-
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
-};
diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk
index 67f5777..c7e3c7d 100644
--- a/plat/arm/board/rddaniel/platform.mk
+++ b/plat/arm/board/rddaniel/platform.mk
@@ -28,8 +28,8 @@
plat/arm/common/arm_nor_psci_mem_protect.c
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts
-TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
new file mode 100644
index 0000000..2719ab4
--- /dev/null
+++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x4001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
deleted file mode 100644
index 766dc00..0000000
--- a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- nt_fw_config_addr = <0x0 0xFEF00000>;
- nt_fw_config_max_size = <0x0100000>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
-};
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
index 88aa634..1a4dd17 100644
--- a/plat/arm/board/rde1edge/platform.mk
+++ b/plat/arm/board/rde1edge/platform.mk
@@ -35,8 +35,8 @@
endif
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
-TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
new file mode 100644
index 0000000..ba74b75
--- /dev/null
+++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x80001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
+
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
deleted file mode 100644
index b14d7ad..0000000
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- nt_fw_config_addr = <0x0 0xFEF00000>;
- nt_fw_config_max_size = <0x0100000>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
-};
diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk
index 04f70f3..135676d 100644
--- a/plat/arm/board/rdn1edge/platform.mk
+++ b/plat/arm/board/rdn1edge/platform.mk
@@ -39,8 +39,8 @@
BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
-TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
@@ -51,8 +51,9 @@
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
-ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),1 2))
- $(error "Chip count for RDN1Edge platform should either 1 or 2, currently \
+$(eval $(call CREATE_SEQ,SEQ,2))
+ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ $(error "Chip count for RDN1Edge platform should be one of $(SEQ), currently \
set to ${CSS_SGI_CHIP_COUNT}.")
endif
diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
new file mode 100644
index 0000000..605cc08
--- /dev/null
+++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x4001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
diff --git a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
deleted file mode 100644
index b14d7ad..0000000
--- a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- nt_fw_config_addr = <0x0 0xFEF00000>;
- nt_fw_config_max_size = <0x0100000>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
-};
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index 76cc4e2..d91f829 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -35,8 +35,8 @@
endif
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts
-TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
new file mode 100644
index 0000000..a0d0ea9
--- /dev/null
+++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x4001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x83000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ };
+};
diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
deleted file mode 100644
index 9502549..0000000
--- a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- plat_arm_bl2 {
- compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x83000000>;
- hw_config_max_size = <0x01000000>;
- };
-};
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
index f096ca5..355b9ee 100644
--- a/plat/arm/board/sgm775/platform.mk
+++ b/plat/arm/board/sgm775/platform.mk
@@ -8,7 +8,7 @@
SGM775_BASE= plat/arm/board/sgm775
-FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_tb_fw_config.dts
+FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_fw_config.dts
PLAT_INCLUDES +=-I${SGM775_BASE}/include/
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index b19a7c3..c2f49c2 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <arch.h>
#include <bl1/bl1.h>
#include <common/bl_common.h>
+#include <lib/fconf/fconf.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
@@ -143,7 +144,10 @@
{
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
- arm_load_tb_fw_config();
+
+ /* Load fw config */
+ fconf_load_config();
+
#if TRUSTED_BOARD_BOOT
/* Share the Mbed TLS heap info with other images */
arm_bl1_set_mbedtls_heap();
@@ -184,9 +188,9 @@
* On Arm platforms, the FWU process is triggered when the FIP image has
* been tampered with.
*/
-int plat_arm_bl1_fwu_needed(void)
+bool plat_arm_bl1_fwu_needed(void)
{
- return (arm_io_is_toc_valid() != 1);
+ return !arm_io_is_toc_valid();
}
/*******************************************************************************
@@ -195,8 +199,5 @@
******************************************************************************/
unsigned int bl1_plat_get_next_image_id(void)
{
- if (plat_arm_bl1_fwu_needed() != 0)
- return NS_BL1U_IMAGE_ID;
-
- return BL2_IMAGE_ID;
+ return plat_arm_bl1_fwu_needed() ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID;
}
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 9adb1ea..dd39208 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -14,6 +14,7 @@
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/generic_delay_timer.h>
+#include <lib/fconf/fconf.h>
#ifdef SPD_opteed
#include <lib/optee_utils.h>
#endif
@@ -58,11 +59,13 @@
/* Setup the BL2 memory layout */
bl2_tzram_layout = *mem_layout;
+ /* Fill the properties struct with the info from the config dtb */
+ if (tb_fw_config != 0U) {
+ fconf_populate(tb_fw_config);
+ }
+
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
-
- if (tb_fw_config != 0U)
- arm_bl2_set_tb_cfg_addr((void *)tb_fw_config);
}
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 9f4bc21..17058d1 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -177,12 +177,20 @@
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif
+ifeq (${USE_FCONF_BASED_IO}, 0)
+ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c
+else
+ARM_IO_SOURCES += plat/arm/common/arm_fconf_io_storage.c \
+ plat/arm/common/fconf/arm_fconf_io.c
+endif
+
BL1_SOURCES += drivers/io/io_fip.c \
drivers/io/io_memmap.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl1_setup.c \
plat/arm/common/arm_err.c \
- plat/arm/common/arm_io_storage.c
+ ${ARM_IO_SOURCES}
+
ifdef EL3_PAYLOAD_BASE
# Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from
# their holding pen
@@ -196,7 +204,10 @@
drivers/io/io_storage.c \
plat/arm/common/arm_bl2_setup.c \
plat/arm/common/arm_err.c \
- plat/arm/common/arm_io_storage.c
+ ${ARM_IO_SOURCES}
+
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
@@ -265,12 +276,20 @@
lib/extensions/pauth/pauth_helpers.S
endif
+ifeq (${SPD},spmd)
+BL31_SOURCES += plat/common/plat_spmd_manifest.c \
+ common/fdt_wrappers.c \
+ ${LIBFDT_SRCS}
+
+endif
+
ifneq (${TRUSTED_BOARD_BOOT},0)
# Include common TBB sources
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
+ lib/fconf/fconf_tbbr_getter.c
# Include the selected chain of trust sources.
ifeq (${COT},tbbr)
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index e6c5a73..443d40f 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,13 +16,13 @@
#if TRUSTED_BOARD_BOOT
#include <drivers/auth/mbedtls/mbedtls_config.h>
#endif
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/fconf/fconf_tbbr_getter.h>
#include <plat/arm/common/arm_dyn_cfg_helpers.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-/* Variable to store the address to TB_FW_CONFIG passed from BL1 */
-static void *tb_fw_cfg_dtb;
-
#if TRUSTED_BOARD_BOOT
static void *mbedtls_heap_addr;
@@ -57,20 +57,10 @@
#elif defined(IMAGE_BL2)
- int err;
-
/* If in BL2, retrieve the already allocated heap's info from DTB */
- if (tb_fw_cfg_dtb != NULL) {
- err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr,
- heap_size);
- if (err < 0) {
- ERROR("BL2: unable to retrieve shared Mbed TLS heap information from DTB\n");
- panic();
- }
- } else {
- ERROR("BL2: DTB missing, cannot get Mbed TLS heap\n");
- panic();
- }
+ *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr);
+ *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size);
+
#endif
return 0;
@@ -83,6 +73,7 @@
void arm_bl1_set_mbedtls_heap(void)
{
int err;
+ uintptr_t tb_fw_cfg_dtb;
/*
* If tb_fw_cfg_dtb==NULL then DTB is not present for the current
@@ -96,8 +87,15 @@
* information, we would need to call plat_get_mbedtls_heap to retrieve
* the default heap's address and size.
*/
- if ((tb_fw_cfg_dtb != NULL) && (mbedtls_heap_addr != NULL)) {
- err = arm_set_dtb_mbedtls_heap_info(tb_fw_cfg_dtb,
+
+ /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/
+ tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr);
+
+ if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) {
+ /* As libfdt use void *, we can't avoid this cast */
+ void *dtb = (void *)tb_fw_cfg_dtb;
+
+ err = arm_set_dtb_mbedtls_heap_info(dtb,
mbedtls_heap_addr, mbedtls_heap_size);
if (err < 0) {
ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n");
@@ -108,111 +106,34 @@
* images. It's critical because BL2 won't be able to proceed
* without the heap info.
*/
- flush_dcache_range((uintptr_t)tb_fw_cfg_dtb,
- fdt_totalsize(tb_fw_cfg_dtb));
+ flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb));
}
}
#endif /* TRUSTED_BOARD_BOOT */
/*
- * Helper function to load TB_FW_CONFIG and populate the load information to
- * arg0 of BL2 entrypoint info.
- */
-void arm_load_tb_fw_config(void)
-{
- int err;
- uintptr_t config_base = 0UL;
- image_desc_t *desc;
-
- image_desc_t arm_tb_fw_info = {
- .image_id = TB_FW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = ARM_TB_FW_CONFIG_BASE,
- .image_info.image_max_size =
- ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE
- };
-
- VERBOSE("BL1: Loading TB_FW_CONFIG\n");
- err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info.image_info);
- if (err != 0) {
- /* Return if TB_FW_CONFIG is not loaded */
- VERBOSE("Failed to load TB_FW_CONFIG\n");
- return;
- }
-
- /* At this point we know that a DTB is indeed available */
- config_base = arm_tb_fw_info.image_info.image_base;
- tb_fw_cfg_dtb = (void *)config_base;
-
- /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */
- desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
- assert(desc != NULL);
- desc->ep_info.args.arg0 = config_base;
-
- INFO("BL1: TB_FW_CONFIG loaded at address = 0x%lx\n", config_base);
-
-#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
- int tb_fw_node;
- uint32_t disable_auth = 0;
-
- err = arm_dyn_tb_fw_cfg_init((void *)config_base, &tb_fw_node);
- if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG loaded\n");
- panic();
- }
-
- err = arm_dyn_get_disable_auth((void *)config_base, tb_fw_node, &disable_auth);
- if (err < 0)
- return;
-
- if (disable_auth == 1)
- dyn_disable_auth();
-#endif
-}
-
-/*
- * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1.
- */
-void arm_bl2_set_tb_cfg_addr(void *dtb)
-{
- assert(dtb != NULL);
- tb_fw_cfg_dtb = dtb;
-}
-
-/*
* BL2 utility function to initialize dynamic configuration specified by
* TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
* specified in TB_FW_CONFIG.
*/
void arm_bl2_dyn_cfg_init(void)
{
- int err = 0, tb_fw_node;
unsigned int i;
bl_mem_params_node_t *cfg_mem_params = NULL;
- uint64_t image_base;
- uint32_t image_size;
+ uintptr_t image_base;
+ size_t image_size;
const unsigned int config_ids[] = {
HW_CONFIG_ID,
SOC_FW_CONFIG_ID,
NT_FW_CONFIG_ID,
-#ifdef SPD_tspd
- /* Currently tos_fw_config is only present for TSP */
+#if defined(SPD_tspd) || defined(SPD_spmd)
+ /* tos_fw_config is only present for TSPD/SPMD */
TOS_FW_CONFIG_ID
#endif
};
- if (tb_fw_cfg_dtb == NULL) {
- VERBOSE("No TB_FW_CONFIG specified\n");
- return;
- }
-
- err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node);
- if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG passed from BL1\n");
- panic();
- }
+ const struct dyn_cfg_dtb_info_t *dtb_info;
/* Iterate through all the fw config IDs */
for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
@@ -223,14 +144,16 @@
continue;
}
- err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node,
- config_ids[i], &image_base, &image_size);
- if (err < 0) {
+ dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]);
+ if (dtb_info == NULL) {
VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n",
config_ids[i]);
continue;
}
+ image_base = dtb_info->config_addr;
+ image_size = dtb_info->config_max_size;
+
/*
* Do some runtime checks on the load addresses of soc_fw_config,
* tos_fw_config, nt_fw_config. This is not a comprehensive check
@@ -262,8 +185,8 @@
}
- cfg_mem_params->image_info.image_base = (uintptr_t)image_base;
- cfg_mem_params->image_info.image_max_size = image_size;
+ cfg_mem_params->image_info.image_base = image_base;
+ cfg_mem_params->image_info.image_max_size = (uint32_t)image_size;
/*
* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from
@@ -271,16 +194,4 @@
*/
cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
}
-
-#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
- uint32_t disable_auth = 0;
-
- err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node,
- &disable_auth);
- if (err < 0)
- return;
-
- if (disable_auth == 1)
- dyn_disable_auth();
-#endif
}
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index daf0f0a..909c4a6 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -15,128 +15,6 @@
#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
-typedef struct config_load_info_prop {
- unsigned int config_id;
- const char *config_addr;
- const char *config_max_size;
-} config_load_info_prop_t;
-
-static const config_load_info_prop_t prop_names[] = {
- {HW_CONFIG_ID, "hw_config_addr", "hw_config_max_size"},
- {SOC_FW_CONFIG_ID, "soc_fw_config_addr", "soc_fw_config_max_size"},
- {TOS_FW_CONFIG_ID, "tos_fw_config_addr", "tos_fw_config_max_size"},
- {NT_FW_CONFIG_ID, "nt_fw_config_addr", "nt_fw_config_max_size"}
-};
-
-/*******************************************************************************
- * Helper to read the load information corresponding to the `config_id` in
- * TB_FW_CONFIG. This function expects the following properties to be defined :
- * <config>_addr size : 2 cells
- * <config>_max_size size : 1 cell
- *
- * Arguments:
- * void *dtb - pointer to the TB_FW_CONFIG in memory
- * int node - The node offset to appropriate node in the
- * DTB.
- * unsigned int config_id - The configuration id
- * uint64_t *config_addr - Returns the `config` load address if read
- * is successful.
- * uint32_t *config_size - Returns the `config` size if read is
- * successful.
- *
- * Returns 0 on success and -1 on error.
- ******************************************************************************/
-int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id,
- uint64_t *config_addr, uint32_t *config_size)
-{
- int err;
- unsigned int i;
-
- assert(dtb != NULL);
- assert(config_addr != NULL);
- assert(config_size != NULL);
-
- for (i = 0; i < ARRAY_SIZE(prop_names); i++) {
- if (prop_names[i].config_id == config_id)
- break;
- }
-
- if (i == ARRAY_SIZE(prop_names)) {
- WARN("Invalid config id %d\n", config_id);
- return -1;
- }
-
- /* Check if the pointer to DT is correct */
- assert(fdt_check_header(dtb) == 0);
-
- /* Assert the node offset point to "arm,tb_fw" compatible property */
- assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
-
- err = fdtw_read_cells(dtb, node, prop_names[i].config_addr, 2,
- (void *) config_addr);
- if (err < 0) {
- WARN("Read cell failed for %s\n", prop_names[i].config_addr);
- return -1;
- }
-
- err = fdtw_read_cells(dtb, node, prop_names[i].config_max_size, 1,
- (void *) config_size);
- if (err < 0) {
- WARN("Read cell failed for %s\n", prop_names[i].config_max_size);
- return -1;
- }
-
- VERBOSE("Dyn cfg: Read config_id %d load info from TB_FW_CONFIG 0x%llx 0x%x\n",
- config_id, (unsigned long long)*config_addr, *config_size);
-
- return 0;
-}
-
-/*******************************************************************************
- * Helper to read the `disable_auth` property in config DTB. This function
- * expects the following properties to be present in the config DTB.
- * name : disable_auth size : 1 cell
- *
- * Arguments:
- * void *dtb - pointer to the TB_FW_CONFIG in memory
- * int node - The node offset to appropriate node in the
- * DTB.
- * uint64_t *disable_auth - The value of `disable_auth` property on
- * successful read. Must be 0 or 1.
- *
- * Returns 0 on success and -1 on error.
- ******************************************************************************/
-int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth)
-{
- int err;
-
- assert(dtb != NULL);
- assert(disable_auth != NULL);
-
- /* Check if the pointer to DT is correct */
- assert(fdt_check_header(dtb) == 0);
-
- /* Assert the node offset point to "arm,tb_fw" compatible property */
- assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
-
- /* Locate the disable_auth cell and read the value */
- err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth);
- if (err < 0) {
- WARN("Read cell failed for `disable_auth`\n");
- return -1;
- }
-
- /* Check if the value is boolean */
- if ((*disable_auth != 0U) && (*disable_auth != 1U)) {
- WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth);
- return -1;
- }
-
- VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n",
- *disable_auth);
- return 0;
-}
-
/*******************************************************************************
* Validate the tb_fw_config is a valid DTB file and returns the node offset
* to "arm,tb_fw" property.
@@ -169,47 +47,6 @@
}
/*
- * Reads and returns the Mbed TLS shared heap information from the DTB.
- * This function is supposed to be called *only* when a DTB is present.
- * This function is supposed to be called only by BL2.
- *
- * Returns:
- * 0 = success
- * -1 = error. In this case the values of heap_addr, heap_size should be
- * considered as garbage by the caller.
- */
-int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
- size_t *heap_size)
-{
- int err, dtb_root;
-
- /* Verify the DTB is valid and get the root node */
- err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
- if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS heap information from DTB\n");
- return -1;
- }
-
- /* Retrieve the Mbed TLS heap details from the DTB */
- err = fdtw_read_cells(dtb, dtb_root,
- DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr);
- if (err < 0) {
- ERROR("Error while reading %s from DTB\n",
- DTB_PROP_MBEDTLS_HEAP_ADDR);
- return -1;
- }
- err = fdtw_read_cells(dtb, dtb_root,
- DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size);
- if (err < 0) {
- ERROR("Error while reading %s from DTB\n",
- DTB_PROP_MBEDTLS_HEAP_SIZE);
- return -1;
- }
- return 0;
-}
-
-
-/*
* This function writes the Mbed TLS heap address and size in the DTB. When it
* is called, it is guaranteed that a DTB is available. However it is not
* guaranteed that the shared Mbed TLS heap implementation is used. Thus we
diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c
new file mode 100644
index 0000000..341622a
--- /dev/null
+++ b/plat/arm/common/arm_fconf_io_storage.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_memmap.h>
+#include <drivers/io/io_storage.h>
+#include <lib/utils.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <plat/arm/common/arm_fconf_getter.h>
+#include <plat/arm/common/arm_fconf_io_storage.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+uintptr_t memmap_dev_handle;
+
+/* Weak definitions may be overridden in specific ARM standard platform */
+#pragma weak plat_arm_io_setup
+#pragma weak plat_arm_get_alt_image_source
+
+int open_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(fip_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+int open_memmap(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+ if (result == 0) {
+ result = io_open(memmap_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using Memmap\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+int arm_io_setup(void)
+{
+ int io_result;
+
+ io_result = register_io_dev_fip(&fip_dev_con);
+ if (io_result < 0) {
+ return io_result;
+ }
+
+ io_result = register_io_dev_memmap(&memmap_dev_con);
+ if (io_result < 0) {
+ return io_result;
+ }
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+ &fip_dev_handle);
+ if (io_result < 0) {
+ return io_result;
+ }
+
+ io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+ &memmap_dev_handle);
+
+ return io_result;
+}
+
+void plat_arm_io_setup(void)
+{
+ int err;
+
+ err = arm_io_setup();
+ if (err < 0) {
+ panic();
+ }
+}
+
+int plat_arm_get_alt_image_source(
+ unsigned int image_id __unused,
+ uintptr_t *dev_handle __unused,
+ uintptr_t *image_spec __unused)
+{
+ /* By default do not try an alternative */
+ return -ENOENT;
+}
+
+/* Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int result;
+ const struct plat_io_policy *policy;
+
+ assert(image_id < MAX_NUMBER_IDS);
+
+ policy = FCONF_GET_PROPERTY(arm, io_policies, image_id);
+ result = policy->check(policy->image_spec);
+ if (result == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ } else {
+ VERBOSE("Trying alternative IO\n");
+ result = plat_arm_get_alt_image_source(image_id, dev_handle,
+ image_spec);
+ }
+
+ return result;
+}
+
+/*
+ * See if a Firmware Image Package is available,
+ * by checking if TOC is valid or not.
+ */
+bool arm_io_is_toc_valid(void)
+{
+ return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0);
+}
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index fc1eb49..f5d8a41 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -292,32 +292,41 @@
}
-void arm_io_setup(void)
+int arm_io_setup(void)
{
int io_result;
io_result = register_io_dev_fip(&fip_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
io_result = register_io_dev_memmap(&memmap_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
/* Open connections to devices and cache the handles */
io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
&fip_dev_handle);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
&memmap_dev_handle);
- assert(io_result == 0);
- /* Ignore improbable errors in release builds */
- (void)io_result;
+ return io_result;
}
void plat_arm_io_setup(void)
{
- arm_io_setup();
+ int err;
+
+ err = arm_io_setup();
+ if (err < 0) {
+ panic();
+ }
}
int plat_arm_get_alt_image_source(
@@ -357,12 +366,8 @@
* See if a Firmware Image Package is available,
* by checking if TOC is valid or not.
*/
-int arm_io_is_toc_valid(void)
+bool arm_io_is_toc_valid(void)
{
- int result;
-
- result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
-
- return (result == 0);
+ return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0);
}
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
new file mode 100644
index 0000000..3c0586f
--- /dev/null
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/io/io_storage.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <plat/arm/common/arm_fconf_getter.h>
+#include <plat/arm/common/arm_fconf_io_storage.h>
+#include <platform_def.h>
+
+const io_block_spec_t fip_block_spec = {
+ .offset = PLAT_ARM_FIP_BASE,
+ .length = PLAT_ARM_FIP_MAX_SIZE
+};
+
+const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = {
+ [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2},
+ [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG},
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+/* By default, ARM platforms load images from the FIP */
+struct plat_io_policy policies[MAX_NUMBER_IDS] = {
+ [FIP_IMAGE_ID] = {
+ &memmap_dev_handle,
+ (uintptr_t)&fip_block_spec,
+ open_memmap
+ },
+ [BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[BL2_IMAGE_ID],
+ open_fip
+ },
+ [TB_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID],
+ open_fip
+ },
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TRUSTED_BOOT_FW_CERT_ID],
+ open_fip
+ },
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+#ifdef IMAGE_BL2
+
+#if TRUSTED_BOARD_BOOT
+#define FCONF_ARM_IO_UUID_NUMBER 19
+#else
+#define FCONF_ARM_IO_UUID_NUMBER 10
+#endif
+
+static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER];
+static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids);
+
+struct policies_load_info {
+ unsigned int image_id;
+ const char *name;
+};
+
+/* image id to property name table */
+static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = {
+ {SCP_BL2_IMAGE_ID, "scp_bl2_uuid"},
+ {BL31_IMAGE_ID, "bl31_uuid"},
+ {BL32_IMAGE_ID, "bl32_uuid"},
+ {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
+ {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"},
+ {BL33_IMAGE_ID, "bl33_uuid"},
+ {HW_CONFIG_ID, "hw_cfg_uuid"},
+ {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
+ {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
+ {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
+#if TRUSTED_BOARD_BOOT
+ {TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"},
+ {SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"},
+ {SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"},
+ {TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"},
+ {NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"},
+ {SCP_FW_CONTENT_CERT_ID, "scp_fw_content_cert_uuid"},
+ {SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"},
+ {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"},
+ {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"},
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+int fconf_populate_arm_io_policies(uintptr_t config)
+{
+ int err, node;
+ unsigned int i;
+
+ union uuid_helper_t uuid_helper;
+ io_uuid_spec_t *uuid_ptr;
+
+ /* As libfdt uses void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Assert the node offset point to "arm,io-fip-handle" compatible property */
+ const char *compatible_str = "arm,io-fip-handle";
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ /* Locate the uuid cells and read the value for all the load info uuid */
+ for (i = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) {
+ uuid_ptr = pool_alloc(&fconf_arm_uuids_pool);
+ err = fdtw_read_array(dtb, node, load_info[i].name, 4, &uuid_helper.word);
+ if (err < 0) {
+ WARN("FCONF: Read cell failed for %s\n", load_info[i].name);
+ return err;
+ }
+
+ VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
+ load_info[i].name,
+ uuid_helper.word[0], uuid_helper.word[1],
+ uuid_helper.word[2], uuid_helper.word[3]);
+
+ uuid_ptr->uuid = uuid_helper.uuid_struct;
+ policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr;
+ policies[load_info[i].image_id].dev_handle = &fip_dev_handle;
+ policies[load_info[i].image_id].check = open_fip;
+ }
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(arm_io, fconf_populate_arm_io_policies);
+
+#endif /* IMAGE_BL2 */
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
new file mode 100644
index 0000000..4c78979
--- /dev/null
+++ b/plat/common/plat_spmd_manifest.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <libfdt.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <errno.h>
+#include <platform_def.h>
+#include <services/spm_core_manifest.h>
+
+/*******************************************************************************
+ * Attribute section handler
+ ******************************************************************************/
+static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr,
+ const void *fdt,
+ int node)
+{
+ int rc = 0;
+
+ assert(attr && fdt);
+
+ rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version);
+ if (rc) {
+ ERROR("Missing SPCI major version in SPM core manifest.\n");
+ return -ENOENT;
+ }
+
+ rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version);
+ if (rc) {
+ ERROR("Missing SPCI minor version in SPM core manifest.\n");
+ return -ENOENT;
+ }
+
+ rc = fdtw_read_cells(fdt, node, "runtime_el", 1, &attr->runtime_el);
+ if (rc) {
+ ERROR("Missing SPM core runtime EL in manifest.\n");
+ return -ENOENT;
+ }
+
+ rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state);
+ if (rc)
+ NOTICE("Execution state not specified in SPM core manifest.\n");
+
+ rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size);
+ if (rc)
+ NOTICE("Binary size not specified in SPM core manifest.\n");
+
+ rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address);
+ if (rc)
+ NOTICE("Load address not specified in SPM core manifest.\n");
+
+ rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint);
+ if (rc)
+ NOTICE("Entrypoint not specified in SPM core manifest.\n");
+
+ VERBOSE("SPM core manifest attribute section:\n");
+ VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version);
+ VERBOSE(" runtime_el: 0x%x\n", attr->runtime_el);
+ VERBOSE(" binary_size: 0x%x\n", attr->binary_size);
+ VERBOSE(" load_address: 0x%llx\n", attr->load_address);
+ VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Root node handler
+ ******************************************************************************/
+static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest,
+ const void *fdt,
+ int root)
+{
+ int node;
+ char *str;
+
+ str = "attribute";
+ node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
+ if (node < 0) {
+ ERROR("Root node doesn't contain subnode '%s'\n", str);
+ return -ENOENT;
+ }
+
+ return manifest_parse_attribute(manifest, fdt, node);
+}
+
+/*******************************************************************************
+ * Platform handler to parse a SPM core manifest.
+ ******************************************************************************/
+int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
+ const void *ptr,
+ size_t size)
+{
+ int rc;
+ int root_node;
+
+ assert(manifest != NULL);
+ assert(ptr != NULL);
+
+ INFO("Reading SPM core manifest at address %p\n", ptr);
+
+ rc = fdt_check_header(ptr);
+ if (rc != 0) {
+ ERROR("Wrong format for SPM core manifest (%d).\n", rc);
+ return -EINVAL;
+ }
+
+ INFO("Reading SPM core manifest at address %p\n", ptr);
+
+ root_node = fdt_node_offset_by_compatible(ptr, -1,
+ "arm,spci-core-manifest-1.0");
+ if (root_node < 0) {
+ ERROR("Unrecognized SPM core manifest\n");
+ return -ENOENT;
+ }
+
+ INFO("Reading SPM core manifest at address %p\n", ptr);
+ return manifest_parse_root(manifest, ptr, root_node);
+}
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 9587d48..f328207 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -46,7 +46,7 @@
{0},
};
-boot_source_type boot_source;
+boot_source_type boot_source = BOOT_SOURCE;
void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
u_register_t x2, u_register_t x4)
@@ -59,7 +59,6 @@
if (socfpga_get_handoff(&reverse_handoff_ptr))
return;
config_pinmux(&reverse_handoff_ptr);
- boot_source = reverse_handoff_ptr.boot_source;
config_clkmgr_handoff(&reverse_handoff_ptr);
enable_nonsecure_access();
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index b4e0921..6c9d81c 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -12,6 +12,7 @@
/* Platform Setting */
#define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX
+#define BOOT_SOURCE BOOT_SOURCE_SDMMC
/* Register Mapping */
#define SOCFPGA_MMC_REG_BASE 0xff808000
diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index 889d137..ba0f7f3 100644
--- a/plat/intel/soc/common/include/socfpga_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -125,7 +125,6 @@
uint32_t misc_magic;
uint32_t misc_length;
uint32_t _pad_0x618_0x620[2];
- uint32_t boot_source;
} handoff;
int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr);
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 7d183db..78ca253 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -45,7 +45,7 @@
{0},
};
-boot_source_type boot_source;
+boot_source_type boot_source = BOOT_SOURCE;
void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
u_register_t x2, u_register_t x4)
@@ -58,7 +58,6 @@
if (socfpga_get_handoff(&reverse_handoff_ptr))
return;
config_pinmux(&reverse_handoff_ptr);
- boot_source = reverse_handoff_ptr.boot_source;
config_clkmgr_handoff(&reverse_handoff_ptr);
enable_nonsecure_access();
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 9dc5151..a2bd57b 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -10,7 +10,8 @@
#include <platform_def.h>
/* Platform Setting */
-#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10
+#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10
+#define BOOT_SOURCE BOOT_SOURCE_SDMMC
/* Register Mapping */
#define SOCFPGA_MMC_REG_BASE 0xff808000
diff --git a/plat/marvell/a8k/common/mss/mss_a8k.mk b/plat/marvell/a8k/common/mss/mss_a8k.mk
index 58f23d8..efd03c5 100644
--- a/plat/marvell/a8k/common/mss/mss_a8k.mk
+++ b/plat/marvell/a8k/common/mss/mss_a8k.mk
@@ -8,7 +8,8 @@
PLAT_MARVELL := plat/marvell
A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss
-BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c
+BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c \
+ $(MARVELL_MOCHI_DRV)
BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c
diff --git a/plat/marvell/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/a8k/common/mss/mss_bl2_setup.c
index 728ee54..09b8446 100644
--- a/plat/marvell/a8k/common/mss/mss_bl2_setup.c
+++ b/plat/marvell/a8k/common/mss/mss_bl2_setup.c
@@ -74,6 +74,12 @@
/* Set the default target id to PIDI */
mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID);
+ /* Open AMB bridge required for MG access */
+ cp110_amb_init(MVEBU_CP_REGS_BASE(0));
+
+ if (CP_COUNT == 2)
+ cp110_amb_init(MVEBU_CP_REGS_BASE(1));
+
return 0;
}
diff --git a/plat/marvell/common/mss/mss_scp_bl2_format.h b/plat/marvell/common/mss/mss_scp_bl2_format.h
index 7cf8d32..7150f0a 100644
--- a/plat/marvell/common/mss/mss_scp_bl2_format.h
+++ b/plat/marvell/common/mss/mss_scp_bl2_format.h
@@ -8,7 +8,7 @@
#ifndef MSS_SCP_BL2_FORMAT_H
#define MSS_SCP_BL2_FORMAT_H
-#define MAX_NR_OF_FILES 5
+#define MAX_NR_OF_FILES 8
#define FILE_MAGIC 0xddd01ff
#define HEADER_VERSION 0x1
@@ -31,6 +31,7 @@
MSS_CP3,
MG_CP0,
MG_CP1,
+ MG_CP2,
};
typedef struct img_header {
diff --git a/plat/marvell/common/mss/mss_scp_bootloader.c b/plat/marvell/common/mss/mss_scp_bootloader.c
index 7e442c6..4473d81 100644
--- a/plat/marvell/common/mss/mss_scp_bootloader.c
+++ b/plat/marvell/common/mss/mss_scp_bootloader.c
@@ -42,6 +42,8 @@
#define MSS_HANDSHAKE_TIMEOUT 50
+#define MG_CM3_SRAM_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000)
+
static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl)
{
int timeout = MSS_HANDSHAKE_TIMEOUT;
@@ -59,6 +61,28 @@
return 0;
}
+static int mg_image_load(uintptr_t src_addr, uint32_t size, uintptr_t mg_regs)
+{
+ if (size > MG_SRAM_SIZE) {
+ ERROR("image is too big to fit into MG CM3 memory\n");
+ return 1;
+ }
+
+ NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n",
+ src_addr, size, mg_regs);
+
+ /* Copy image to MG CM3 SRAM */
+ memcpy((void *)mg_regs, (void *)src_addr, size);
+
+ /*
+ * Don't release MG CM3 from reset - it will be done by next step
+ * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which
+ * has enabeld 802.3. auto-neg) will be choosen.
+ */
+
+ return 0;
+}
+
static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs)
{
uint32_t i, loop_num, timeout;
@@ -225,12 +249,21 @@
}
break;
case MG_CP0:
- /* TODO: */
- NOTICE("Load image to CP0 MG not supported\n");
- break;
case MG_CP1:
- /* TODO: */
- NOTICE("Load image to CP1 MG not supported\n");
+ case MG_CP2:
+ cp_index = cm3_type - MG_CP0;
+ if (bl2_plat_get_cp_count(0) <= cp_index) {
+ NOTICE("Skipping MG CP%d related image\n",
+ cp_index);
+ break;
+ }
+ NOTICE("Load image to CP%d MG\n", cp_index);
+ ret = mg_image_load(single_img, image_size,
+ MG_CM3_SRAM_BASE(cp_index));
+ if (ret != 0) {
+ ERROR("SCP Image load failed\n");
+ return -1;
+ }
break;
default:
ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type);
@@ -261,7 +294,7 @@
}
if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) {
- ERROR("SCP_BL2 concatenated image contains to many images\n");
+ ERROR("SCP_BL2 concatenated image contains too many images\n");
return -1;
}
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 578892e..8910967 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -16,6 +16,8 @@
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/console.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_storage.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
#include <plat/common/platform.h>
@@ -33,6 +35,7 @@
#endif
#include "io_common.h"
+#include "io_rcar.h"
#include "qos_init.h"
#include "rcar_def.h"
#include "rcar_private.h"
@@ -382,10 +385,28 @@
return 0;
}
+static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest)
+{
+ uint32_t cert, len;
+ int ret;
+
+ ret = rcar_get_certificate(certid, &cert);
+ if (ret) {
+ ERROR("%s : cert file load error", __func__);
+ return 1;
+ }
+
+ rcar_read_certificate((uint64_t) cert, &len, dest);
+
+ return 0;
+}
+
int bl2_plat_handle_post_image_load(unsigned int image_id)
{
static bl2_to_bl31_params_mem_t *params;
bl_mem_params_node_t *bl_mem_params;
+ uintptr_t dest;
+ int ret;
if (!params) {
params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE;
@@ -396,8 +417,17 @@
switch (image_id) {
case BL31_IMAGE_ID:
+ ret = rcar_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID,
+ &dest);
+ if (!ret)
+ bl_mem_params->image_info.image_base = dest;
break;
case BL32_IMAGE_ID:
+ ret = rcar_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID,
+ &dest);
+ if (!ret)
+ bl_mem_params->image_info.image_base = dest;
+
memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info,
sizeof(entry_point_info_t));
break;
diff --git a/plat/renesas/rcar/include/rcar_version.h b/plat/renesas/rcar/include/rcar_version.h
index 2d400e0..67cbd71 100644
--- a/plat/renesas/rcar/include/rcar_version.h
+++ b/plat/renesas/rcar/include/rcar_version.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,8 +9,8 @@
#include <arch_helpers.h>
-#define VERSION_OF_RENESAS "2.0.4"
-#define VERSION_OF_RENESAS_MAXLEN (128)
+#define VERSION_OF_RENESAS "2.0.6"
+#define VERSION_OF_RENESAS_MAXLEN 128
extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN];
diff --git a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
index 4f58b68..091a6f7 100644
--- a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
+++ b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
@@ -4,16 +4,25 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
+
#include <platform_def.h>
#include <common/bl_common.h>
#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <plat/common/platform.h>
#include "../uniphier.h"
+static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN;
+
void tsp_early_platform_setup(void)
{
- uniphier_console_setup();
+ uniphier_soc = uniphier_get_soc_id();
+ if (uniphier_soc == UNIPHIER_SOC_UNKNOWN)
+ plat_error_handler(-ENOTSUP);
+
+ uniphier_console_setup(uniphier_soc);
}
void tsp_platform_setup(void)
@@ -22,6 +31,6 @@
void tsp_plat_arch_setup(void)
{
- uniphier_mmap_setup();
+ uniphier_mmap_setup(uniphier_soc);
enable_mmu_el1(0);
}
diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h
index 729dc5c..ee520ad 100644
--- a/plat/socionext/uniphier/uniphier.h
+++ b/plat/socionext/uniphier/uniphier.h
@@ -25,7 +25,8 @@
#define UNIPHIER_BOOT_DEVICE_EMMC 0
#define UNIPHIER_BOOT_DEVICE_NAND 1
#define UNIPHIER_BOOT_DEVICE_NOR 2
-#define UNIPHIER_BOOT_DEVICE_USB 3
+#define UNIPHIER_BOOT_DEVICE_SD 3
+#define UNIPHIER_BOOT_DEVICE_USB 4
#define UNIPHIER_BOOT_DEVICE_RSV 0xffffffff
unsigned int uniphier_get_boot_master(unsigned int soc);
@@ -34,11 +35,13 @@
#define UNIPHIER_BOOT_MASTER_SCP 1
#define UNIPHIER_BOOT_MASTER_EXT 2
-void uniphier_console_setup(void);
+void uniphier_console_setup(unsigned int soc);
struct io_block_dev_spec;
-int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec);
-int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec);
+int uniphier_emmc_init(unsigned int soc,
+ struct io_block_dev_spec **block_dev_spec);
+int uniphier_nand_init(unsigned int soc,
+ struct io_block_dev_spec **block_dev_spec);
int uniphier_usb_init(unsigned int soc,
struct io_block_dev_spec **block_dev_spec);
@@ -54,7 +57,7 @@
void uniphier_scp_system_off(void);
void uniphier_scp_system_reset(void);
-void uniphier_mmap_setup(void);
+void uniphier_mmap_setup(unsigned int soc);
void uniphier_cci_init(unsigned int soc);
void uniphier_cci_enable(void);
@@ -66,6 +69,8 @@
void uniphier_gic_cpuif_disable(void);
void uniphier_gic_pcpu_init(void);
+void uniphier_psci_init(unsigned int soc);
+
unsigned int uniphier_calc_core_pos(u_register_t mpidr);
#endif /* UNIPHIER_H */
diff --git a/plat/socionext/uniphier/uniphier_bl2_setup.c b/plat/socionext/uniphier/uniphier_bl2_setup.c
index 11d837c..7a7f786 100644
--- a/plat/socionext/uniphier/uniphier_bl2_setup.c
+++ b/plat/socionext/uniphier/uniphier_bl2_setup.c
@@ -25,39 +25,37 @@
#define UNIPHIER_IMAGE_BUF_SIZE 0x00100000UL
static uintptr_t uniphier_mem_base = UNIPHIER_MEM_BASE;
+static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN;
static int uniphier_bl2_kick_scp;
void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
u_register_t x2, u_register_t x3)
{
- uniphier_console_setup();
+ uniphier_soc = uniphier_get_soc_id();
+ if (uniphier_soc == UNIPHIER_SOC_UNKNOWN)
+ plat_error_handler(-ENOTSUP);
+
+ uniphier_console_setup(uniphier_soc);
}
void bl2_el3_plat_arch_setup(void)
{
- unsigned int soc;
int skip_scp = 0;
int ret;
- uniphier_mmap_setup();
+ uniphier_mmap_setup(uniphier_soc);
enable_mmu_el3(0);
/* add relocation offset (run-time-address - link-address) */
uniphier_mem_base += BL_CODE_BASE - BL2_BASE;
- soc = uniphier_get_soc_id();
- if (soc == UNIPHIER_SOC_UNKNOWN) {
- ERROR("unsupported SoC\n");
- plat_error_handler(-ENOTSUP);
- }
-
- ret = uniphier_io_setup(soc, uniphier_mem_base);
+ ret = uniphier_io_setup(uniphier_soc, uniphier_mem_base);
if (ret) {
ERROR("failed to setup io devices\n");
plat_error_handler(ret);
}
- switch (uniphier_get_boot_master(soc)) {
+ switch (uniphier_get_boot_master(uniphier_soc)) {
case UNIPHIER_BOOT_MASTER_THIS:
INFO("Booting from this SoC\n");
skip_scp = 1;
diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c
index 47f2378..f2f0b29 100644
--- a/plat/socionext/uniphier/uniphier_bl31_setup.c
+++ b/plat/socionext/uniphier/uniphier_bl31_setup.c
@@ -21,6 +21,7 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
+static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN;
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
@@ -37,7 +38,11 @@
bl_params_node_t *bl_params = ((bl_params_t *)from_bl2)->head;
- uniphier_console_setup();
+ uniphier_soc = uniphier_get_soc_id();
+ if (uniphier_soc == UNIPHIER_SOC_UNKNOWN)
+ plat_error_handler(-ENOTSUP);
+
+ uniphier_console_setup(uniphier_soc);
while (bl_params) {
if (bl_params->image_id == BL32_IMAGE_ID)
@@ -53,32 +58,34 @@
panic();
}
-#define UNIPHIER_SYS_CNTCTL_BASE 0x60E00000
+static const uintptr_t uniphier_cntctl_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x60e00000,
+ [UNIPHIER_SOC_LD20] = 0x60e00000,
+ [UNIPHIER_SOC_PXS3] = 0x60e00000,
+};
void bl31_platform_setup(void)
{
- unsigned int soc;
+ uintptr_t cntctl_base;
- soc = uniphier_get_soc_id();
- if (soc == UNIPHIER_SOC_UNKNOWN) {
- ERROR("unsupported SoC\n");
- plat_error_handler(-ENOTSUP);
- }
-
- uniphier_cci_init(soc);
+ uniphier_cci_init(uniphier_soc);
uniphier_cci_enable();
/* Initialize the GIC driver, cpu and distributor interfaces */
- uniphier_gic_driver_init(soc);
+ uniphier_gic_driver_init(uniphier_soc);
uniphier_gic_init();
+ assert(uniphier_soc < ARRAY_SIZE(uniphier_cntctl_base));
+ cntctl_base = uniphier_cntctl_base[uniphier_soc];
+
/* Enable and initialize the System level generic timer */
- mmio_write_32(UNIPHIER_SYS_CNTCTL_BASE + CNTCR_OFF,
- CNTCR_FCREQ(0U) | CNTCR_EN);
+ mmio_write_32(cntctl_base + CNTCR_OFF, CNTCR_FCREQ(0U) | CNTCR_EN);
+
+ uniphier_psci_init(uniphier_soc);
}
void bl31_plat_arch_setup(void)
{
- uniphier_mmap_setup();
+ uniphier_mmap_setup(uniphier_soc);
enable_mmu_el3(0);
}
diff --git a/plat/socionext/uniphier/uniphier_boot_device.c b/plat/socionext/uniphier/uniphier_boot_device.c
index 462c085..36a9908 100644
--- a/plat/socionext/uniphier/uniphier_boot_device.c
+++ b/plat/socionext/uniphier/uniphier_boot_device.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,22 +13,29 @@
#include "uniphier.h"
-#define UNIPHIER_PINMON0 0x5f900100
-#define UNIPHIER_PINMON2 0x5f900108
+#define UNIPHIER_PINMON0 0x0
+#define UNIPHIER_PINMON2 0x8
-static int uniphier_ld11_is_usb_boot(uint32_t pinmon)
+static const uintptr_t uniphier_pinmon_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x5f900100,
+ [UNIPHIER_SOC_LD20] = 0x5f900100,
+ [UNIPHIER_SOC_PXS3] = 0x5f900100,
+};
+
+static bool uniphier_ld11_is_usb_boot(uint32_t pinmon)
{
return !!(~pinmon & 0x00000080);
}
-static int uniphier_ld20_is_usb_boot(uint32_t pinmon)
+static bool uniphier_ld20_is_usb_boot(uint32_t pinmon)
{
return !!(~pinmon & 0x00000780);
}
-static int uniphier_pxs3_is_usb_boot(uint32_t pinmon)
+static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon)
{
- uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2);
+ uintptr_t pinmon_base = uniphier_pinmon_base[UNIPHIER_SOC_PXS3];
+ uint32_t pinmon2 = mmio_read_32(pinmon_base + UNIPHIER_PINMON2);
return !!(pinmon2 & BIT(31));
}
@@ -106,20 +113,25 @@
}
struct uniphier_boot_device_info {
- int (*is_usb_boot)(uint32_t pinmon);
+ bool have_boot_swap;
+ bool (*is_sd_boot)(uint32_t pinmon);
+ bool (*is_usb_boot)(uint32_t pinmon);
unsigned int (*get_boot_device)(uint32_t pinmon);
};
static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
[UNIPHIER_SOC_LD11] = {
+ .have_boot_swap = true,
.is_usb_boot = uniphier_ld11_is_usb_boot,
.get_boot_device = uniphier_ld11_get_boot_device,
},
[UNIPHIER_SOC_LD20] = {
+ .have_boot_swap = true,
.is_usb_boot = uniphier_ld20_is_usb_boot,
.get_boot_device = uniphier_ld11_get_boot_device,
},
[UNIPHIER_SOC_PXS3] = {
+ .have_boot_swap = true,
.is_usb_boot = uniphier_pxs3_is_usb_boot,
.get_boot_device = uniphier_pxs3_get_boot_device,
},
@@ -128,17 +140,24 @@
unsigned int uniphier_get_boot_device(unsigned int soc)
{
const struct uniphier_boot_device_info *info;
+ uintptr_t pinmon_base;
uint32_t pinmon;
assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
info = &uniphier_boot_device_info[soc];
- pinmon = mmio_read_32(UNIPHIER_PINMON0);
+ assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
+ pinmon_base = uniphier_pinmon_base[soc];
+
+ pinmon = mmio_read_32(pinmon_base + UNIPHIER_PINMON0);
- if (!(pinmon & BIT(29)))
+ if (info->have_boot_swap && !(pinmon & BIT(29)))
return UNIPHIER_BOOT_DEVICE_NOR;
- if (info->is_usb_boot(pinmon))
+ if (info->is_sd_boot && info->is_sd_boot(pinmon))
+ return UNIPHIER_BOOT_DEVICE_SD;
+
+ if (info->is_usb_boot && info->is_usb_boot(pinmon))
return UNIPHIER_BOOT_DEVICE_USB;
return info->get_boot_device(pinmon);
@@ -155,7 +174,12 @@
assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp));
if (uniphier_have_onchip_scp[soc]) {
- if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27))
+ uintptr_t pinmon_base;
+
+ assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
+ pinmon_base = uniphier_pinmon_base[soc];
+
+ if (mmio_read_32(pinmon_base + UNIPHIER_PINMON0) & BIT(27))
return UNIPHIER_BOOT_MASTER_THIS;
else
return UNIPHIER_BOOT_MASTER_SCP;
diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c
index 64ee797..1851e4d 100644
--- a/plat/socionext/uniphier/uniphier_console_setup.c
+++ b/plat/socionext/uniphier/uniphier_console_setup.c
@@ -1,9 +1,11 @@
/*
- * Copyright (c) 2019, Socionext Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Socionext Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
#include <drivers/console.h>
#include <errno.h>
#include <lib/mmio.h>
@@ -12,9 +14,8 @@
#include "uniphier.h"
#include "uniphier_console.h"
-#define UNIPHIER_UART_BASE 0x54006800
-#define UNIPHIER_UART_END 0x54006c00
#define UNIPHIER_UART_OFFSET 0x100
+#define UNIPHIER_UART_NR_PORTS 4
struct uniphier_console {
struct console console;
@@ -40,16 +41,26 @@
},
};
+static const uintptr_t uniphier_uart_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x54006800,
+ [UNIPHIER_SOC_LD20] = 0x54006800,
+ [UNIPHIER_SOC_PXS3] = 0x54006800,
+};
+
/*
* There are 4 UART ports available on this platform. By default, we want to
* use the same one as used in the previous firmware stage.
*/
-static uintptr_t uniphier_console_get_base(void)
+static uintptr_t uniphier_console_get_base(unsigned int soc)
{
- uintptr_t base = UNIPHIER_UART_BASE;
+ uintptr_t base, end;
uint32_t div;
- while (base < UNIPHIER_UART_END) {
+ assert(soc < ARRAY_SIZE(uniphier_uart_base));
+ base = uniphier_uart_base[soc];
+ end = base + UNIPHIER_UART_OFFSET * UNIPHIER_UART_NR_PORTS;
+
+ while (base < end) {
div = mmio_read_32(base + UNIPHIER_UART_DLR);
if (div)
return base;
@@ -66,11 +77,11 @@
UNIPHIER_UART_LCR_WLEN8 << 8);
}
-void uniphier_console_setup(void)
+void uniphier_console_setup(unsigned int soc)
{
uintptr_t base;
- base = uniphier_console_get_base();
+ base = uniphier_console_get_base(soc);
if (!base)
plat_error_handler(-EINVAL);
diff --git a/plat/socionext/uniphier/uniphier_emmc.c b/plat/socionext/uniphier/uniphier_emmc.c
index d666ba7..b3d23cb 100644
--- a/plat/socionext/uniphier/uniphier_emmc.c
+++ b/plat/socionext/uniphier/uniphier_emmc.c
@@ -87,7 +87,12 @@
unsigned int is_data;
};
-static int uniphier_emmc_block_addressing;
+struct uniphier_emmc_host {
+ uintptr_t base;
+ bool is_block_addressing;
+};
+
+static struct uniphier_emmc_host uniphier_emmc_host;
static int uniphier_emmc_send_cmd(uintptr_t host_base,
struct uniphier_mmc_cmd *cmd)
@@ -157,7 +162,8 @@
return uniphier_emmc_send_cmd(host_base, &cmd);
}
-static int uniphier_emmc_is_over_2gb(uintptr_t host_base)
+static int uniphier_emmc_check_device_size(uintptr_t host_base,
+ bool *is_block_addressing)
{
struct uniphier_mmc_cmd cmd = {0};
uint32_t csd40, csd72; /* CSD[71:40], CSD[103:72] */
@@ -174,7 +180,10 @@
csd40 = mmio_read_32(host_base + SDHCI_RESPONSE + 4);
csd72 = mmio_read_32(host_base + SDHCI_RESPONSE + 8);
- return !(~csd40 & 0xffc00380) && !(~csd72 & 0x3);
+ /* C_SIZE == 0xfff && C_SIZE_MULT == 0x7 ? */
+ *is_block_addressing = !(~csd40 & 0xffc00380) && !(~csd72 & 0x3);
+
+ return 0;
}
static int uniphier_emmc_load_image(uintptr_t host_base,
@@ -210,15 +219,15 @@
static size_t uniphier_emmc_read(int lba, uintptr_t buf, size_t size)
{
- uintptr_t host_base = 0x5a000200;
int ret;
inv_dcache_range(buf, size);
- if (!uniphier_emmc_block_addressing)
+ if (!uniphier_emmc_host.is_block_addressing)
lba *= 512;
- ret = uniphier_emmc_load_image(host_base, lba, buf, size / 512);
+ ret = uniphier_emmc_load_image(uniphier_emmc_host.base,
+ lba, buf, size / 512);
inv_dcache_range(buf, size);
@@ -232,10 +241,10 @@
.block_size = 512,
};
-static int uniphier_emmc_hw_init(void)
+static int uniphier_emmc_hw_init(struct uniphier_emmc_host *host)
{
- uintptr_t host_base = 0x5a000200;
struct uniphier_mmc_cmd cmd = {0};
+ uintptr_t host_base = uniphier_emmc_host.base;
int ret;
/*
@@ -253,12 +262,11 @@
while (mmio_read_8(host_base + SDHCI_SOFTWARE_RESET))
;
- ret = uniphier_emmc_is_over_2gb(host_base);
- if (ret < 0)
+ ret = uniphier_emmc_check_device_size(host_base,
+ &uniphier_emmc_host.is_block_addressing);
+ if (ret)
return ret;
- uniphier_emmc_block_addressing = ret;
-
cmd.cmdarg = UNIPHIER_EMMC_RCA << 16;
/* select card again */
@@ -274,11 +282,23 @@
return 0;
}
+static const uintptr_t uniphier_emmc_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x5a000200,
+ [UNIPHIER_SOC_LD20] = 0x5a000200,
+ [UNIPHIER_SOC_PXS3] = 0x5a000200,
+};
+
-int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec)
+int uniphier_emmc_init(unsigned int soc,
+ struct io_block_dev_spec **block_dev_spec)
{
int ret;
- ret = uniphier_emmc_hw_init();
+ assert(soc < ARRAY_SIZE(uniphier_emmc_base));
+ uniphier_emmc_host.base = uniphier_emmc_base[soc];
+ if (uniphier_emmc_host.base == 0UL)
+ return -ENOTSUP;
+
+ ret = uniphier_emmc_hw_init(&uniphier_emmc_host);
if (ret)
return ret;
diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c
index 89c8718..96180f1 100644
--- a/plat/socionext/uniphier/uniphier_io_storage.c
+++ b/plat/socionext/uniphier/uniphier_io_storage.c
@@ -249,24 +249,24 @@
return io_dev_open(uniphier_fip_dev_con, 0, &uniphier_fip_dev_handle);
}
-static int uniphier_io_emmc_setup(unsigned int soc_id, size_t buffer_offset)
+static int uniphier_io_emmc_setup(unsigned int soc, size_t buffer_offset)
{
struct io_block_dev_spec *block_dev_spec;
int ret;
- ret = uniphier_emmc_init(&block_dev_spec);
+ ret = uniphier_emmc_init(soc, &block_dev_spec);
if (ret)
return ret;
return uniphier_io_block_setup(0x20000, block_dev_spec, buffer_offset);
}
-static int uniphier_io_nand_setup(unsigned int soc_id, size_t buffer_offset)
+static int uniphier_io_nand_setup(unsigned int soc, size_t buffer_offset)
{
struct io_block_dev_spec *block_dev_spec;
int ret;
- ret = uniphier_nand_init(&block_dev_spec);
+ ret = uniphier_nand_init(soc, &block_dev_spec);
if (ret)
return ret;
diff --git a/plat/socionext/uniphier/uniphier_nand.c b/plat/socionext/uniphier/uniphier_nand.c
index 3925177..71cb96c 100644
--- a/plat/socionext/uniphier/uniphier_nand.c
+++ b/plat/socionext/uniphier/uniphier_nand.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <stdint.h>
#include <platform_def.h>
@@ -237,8 +238,7 @@
for (i = 0; i < ARRAY_SIZE(nand->bbt); i++)
nand->bbt[i] = UNIPHIER_NAND_BBT_UNKNOWN;
- nand->host_base = 0x68000000;
- nand->reg_base = 0x68100000;
+ nand->reg_base = nand->host_base + 0x100000;
nand->pages_per_block =
mmio_read_32(nand->reg_base + DENALI_PAGES_PER_BLOCK);
@@ -255,10 +255,22 @@
return 0;
}
-int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec)
+static const uintptr_t uniphier_nand_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x68000000,
+ [UNIPHIER_SOC_LD20] = 0x68000000,
+ [UNIPHIER_SOC_PXS3] = 0x68000000,
+};
+
+int uniphier_nand_init(unsigned int soc,
+ struct io_block_dev_spec **block_dev_spec)
{
int ret;
+ assert(soc < ARRAY_SIZE(uniphier_nand_base));
+ uniphier_nand.host_base = uniphier_nand_base[soc];
+ if (!uniphier_nand.host_base)
+ return -ENOTSUP;
+
ret = uniphier_nand_hw_init(&uniphier_nand);
if (ret)
return ret;
diff --git a/plat/socionext/uniphier/uniphier_psci.c b/plat/socionext/uniphier/uniphier_psci.c
index 2acc874..a371705 100644
--- a/plat/socionext/uniphier/uniphier_psci.c
+++ b/plat/socionext/uniphier/uniphier_psci.c
@@ -1,9 +1,11 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
#include <arch_helpers.h>
#include <common/debug.h>
#include <errno.h>
@@ -12,15 +14,18 @@
#include "uniphier.h"
-#define UNIPHIER_ROM_RSV0 0x59801200
+#define UNIPHIER_ROM_RSV0 0x0
-#define UNIPHIER_SLFRSTSEL 0x61843010
+#define UNIPHIER_SLFRSTSEL 0x10
#define UNIPHIER_SLFRSTSEL_MASK GENMASK(1, 0)
-#define UNIPHIER_SLFRSTCTL 0x61843014
+#define UNIPHIER_SLFRSTCTL 0x14
#define UNIPHIER_SLFRSTCTL_RST BIT(0)
#define MPIDR_AFFINITY_INVALID ((u_register_t)-1)
+static uintptr_t uniphier_rom_rsv_base;
+static uintptr_t uniphier_slfrst_base;
+
uintptr_t uniphier_sec_entrypoint;
void uniphier_warmboot_entrypoint(void);
@@ -34,7 +39,7 @@
flush_dcache_range((uint64_t)&uniphier_holding_pen_release,
sizeof(uniphier_holding_pen_release));
- mmio_write_64(UNIPHIER_ROM_RSV0,
+ mmio_write_64(uniphier_rom_rsv_base + UNIPHIER_ROM_RSV0,
(uint64_t)&uniphier_warmboot_entrypoint);
sev();
@@ -71,8 +76,10 @@
static void uniphier_self_system_reset(void)
{
- mmio_clrbits_32(UNIPHIER_SLFRSTSEL, UNIPHIER_SLFRSTSEL_MASK);
- mmio_setbits_32(UNIPHIER_SLFRSTCTL, UNIPHIER_SLFRSTCTL_RST);
+ mmio_clrbits_32(uniphier_slfrst_base + UNIPHIER_SLFRSTSEL,
+ UNIPHIER_SLFRSTSEL_MASK);
+ mmio_setbits_32(uniphier_slfrst_base + UNIPHIER_SLFRSTCTL,
+ UNIPHIER_SLFRSTCTL_RST);
}
static void __dead2 uniphier_psci_system_off(void)
@@ -114,13 +121,40 @@
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const struct plat_psci_ops **psci_ops)
{
- unsigned int soc;
+ uniphier_sec_entrypoint = sec_entrypoint;
+ flush_dcache_range((uint64_t)&uniphier_sec_entrypoint,
+ sizeof(uniphier_sec_entrypoint));
- soc = uniphier_get_soc_id();
- if (soc == UNIPHIER_SOC_UNKNOWN) {
- ERROR("unsupported SoC\n");
- return -ENOTSUP;
- }
+ *psci_ops = &uniphier_psci_ops;
+
+ return 0;
+}
+
+struct uniphier_psci_ctrl_base {
+ uintptr_t rom_rsv_base;
+ uintptr_t slfrst_base;
+};
+
+static const struct uniphier_psci_ctrl_base uniphier_psci_ctrl_base[] = {
+ [UNIPHIER_SOC_LD11] = {
+ .rom_rsv_base = 0x59801200,
+ .slfrst_base = 0x61843000,
+ },
+ [UNIPHIER_SOC_LD20] = {
+ .rom_rsv_base = 0x59801200,
+ .slfrst_base = 0x61843000,
+ },
+ [UNIPHIER_SOC_PXS3] = {
+ .rom_rsv_base = 0x59801200,
+ .slfrst_base = 0x61843000,
+ },
+};
+
+void uniphier_psci_init(unsigned int soc)
+{
+ assert(soc < ARRAY_SIZE(uniphier_psci_ctrl_base));
+ uniphier_rom_rsv_base = uniphier_psci_ctrl_base[soc].rom_rsv_base;
+ uniphier_slfrst_base = uniphier_psci_ctrl_base[soc].slfrst_base;
if (uniphier_get_boot_master(soc) == UNIPHIER_BOOT_MASTER_SCP) {
uniphier_psci_scp_mode = uniphier_scp_is_running();
@@ -130,12 +164,4 @@
if (uniphier_psci_scp_mode)
uniphier_scp_open_com();
}
-
- uniphier_sec_entrypoint = sec_entrypoint;
- flush_dcache_range((uint64_t)&uniphier_sec_entrypoint,
- sizeof(uniphier_sec_entrypoint));
-
- *psci_ops = &uniphier_psci_ops;
-
- return 0;
}
diff --git a/plat/socionext/uniphier/uniphier_xlat_setup.c b/plat/socionext/uniphier/uniphier_xlat_setup.c
index 18d2f9e..66c7834 100644
--- a/plat/socionext/uniphier/uniphier_xlat_setup.c
+++ b/plat/socionext/uniphier/uniphier_xlat_setup.c
@@ -4,15 +4,36 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
#include <platform_def.h>
#include <common/debug.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include "uniphier.h"
+
-#define UNIPHIER_REG_REGION_BASE 0x50000000ULL
-#define UNIPHIER_REG_REGION_SIZE 0x20000000ULL
+struct uniphier_reg_region {
+ uintptr_t base;
+ size_t size;
+};
-void uniphier_mmap_setup(void)
+static const struct uniphier_reg_region uniphier_reg_region[] = {
+ [UNIPHIER_SOC_LD11] = {
+ .base = 0x50000000UL,
+ .size = 0x20000000UL,
+ },
+ [UNIPHIER_SOC_LD20] = {
+ .base = 0x50000000UL,
+ .size = 0x20000000UL,
+ },
+ [UNIPHIER_SOC_PXS3] = {
+ .base = 0x50000000UL,
+ .size = 0x20000000UL,
+ },
+};
+
+void uniphier_mmap_setup(unsigned int soc)
{
VERBOSE("Trusted RAM seen by this BL image: %p - %p\n",
(void *)BL_CODE_BASE, (void *)BL_END);
@@ -35,8 +56,10 @@
MT_DEVICE | MT_RW | MT_SECURE);
/* register region */
- mmap_add_region(UNIPHIER_REG_REGION_BASE, UNIPHIER_REG_REGION_BASE,
- UNIPHIER_REG_REGION_SIZE,
+ assert(soc < ARRAY_SIZE(uniphier_reg_region));
+ mmap_add_region(uniphier_reg_region[soc].base,
+ uniphier_reg_region[soc].base,
+ uniphier_reg_region[soc].size,
MT_DEVICE | MT_RW | MT_SECURE);
init_xlat_tables();
diff --git a/services/spd/trusty/generic-arm64-smcall.c b/services/spd/trusty/generic-arm64-smcall.c
index dfc3e71..5c3a628 100644
--- a/services/spd/trusty/generic-arm64-smcall.c
+++ b/services/spd/trusty/generic-arm64-smcall.c
@@ -12,6 +12,22 @@
#include "generic-arm64-smcall.h"
+#ifndef PLAT_ARM_GICD_BASE
+#ifdef GICD_BASE
+#define PLAT_ARM_GICD_BASE GICD_BASE
+#define PLAT_ARM_GICC_BASE GICC_BASE
+#ifdef GICR_BASE
+#define PLAT_ARM_GICR_BASE GICR_BASE
+#endif
+#else
+#error PLAT_ARM_GICD_BASE or GICD_BASE must be defined
+#endif
+#endif
+
+#ifndef PLAT_ARM_GICR_BASE
+#define PLAT_ARM_GICR_BASE SMC_UNK
+#endif
+
int trusty_disable_serial_debug;
struct dputc_state {
@@ -48,12 +64,15 @@
static uint64_t trusty_get_reg_base(uint32_t reg)
{
switch (reg) {
- case 0:
+ case SMC_GET_GIC_BASE_GICD:
return PLAT_ARM_GICD_BASE;
- case 1:
+ case SMC_GET_GIC_BASE_GICC:
return PLAT_ARM_GICC_BASE;
+ case SMC_GET_GIC_BASE_GICR:
+ return PLAT_ARM_GICR_BASE;
+
default:
NOTICE("%s(0x%x) unknown reg\n", __func__, reg);
return SMC_UNK;
diff --git a/services/spd/trusty/generic-arm64-smcall.h b/services/spd/trusty/generic-arm64-smcall.h
index 06efc72..ac03469 100644
--- a/services/spd/trusty/generic-arm64-smcall.h
+++ b/services/spd/trusty/generic-arm64-smcall.h
@@ -23,5 +23,6 @@
*/
#define SMC_GET_GIC_BASE_GICD 0
#define SMC_GET_GIC_BASE_GICC 1
+#define SMC_GET_GIC_BASE_GICR 2
#define SMC_FC_GET_REG_BASE SMC_FASTCALL_NR(SMC_ENTITY_PLATFORM_MONITOR, 0x1)
#define SMC_FC64_GET_REG_BASE SMC_FASTCALL64_NR(SMC_ENTITY_PLATFORM_MONITOR, 0x1)
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index d6c092c..092ffa8 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -390,6 +390,10 @@
void plat_trusty_set_boot_args(aapcs64_params_t *args);
+#if !defined(TSP_SEC_MEM_SIZE) && defined(BL32_MEM_SIZE)
+#define TSP_SEC_MEM_SIZE BL32_MEM_SIZE
+#endif
+
#ifdef TSP_SEC_MEM_SIZE
#pragma weak plat_trusty_set_boot_args
void plat_trusty_set_boot_args(aapcs64_params_t *args)
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index f206724..b0cbf62 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -126,7 +126,7 @@
* interrupt handling.
*/
if (get_yield_smc_active_flag(tsp_ctx->state)) {
- tsp_ctx->saved_spsr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx,
+ tsp_ctx->saved_spsr_el3 = (uint32_t)SMC_GET_EL3(&tsp_ctx->cpu_ctx,
CTX_SPSR_EL3);
tsp_ctx->saved_elr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx,
CTX_ELR_EL3);
diff --git a/services/std_svc/spmd/aarch64/spmd_helpers.S b/services/std_svc/spmd/aarch64/spmd_helpers.S
new file mode 100644
index 0000000..d7bffca
--- /dev/null
+++ b/services/std_svc/spmd/aarch64/spmd_helpers.S
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include "../spmd_private.h"
+
+ .global spmd_spm_core_enter
+ .global spmd_spm_core_exit
+
+ /* ---------------------------------------------------------------------
+ * This function is called with SP_EL0 as stack. Here we stash our EL3
+ * callee-saved registers on to the stack as a part of saving the C
+ * runtime and enter the secure payload.
+ * 'x0' contains a pointer to the memory where the address of the C
+ * runtime context is to be saved.
+ * ---------------------------------------------------------------------
+ */
+func spmd_spm_core_enter
+ /* Make space for the registers that we're going to save */
+ mov x3, sp
+ str x3, [x0, #0]
+ sub sp, sp, #SPMD_C_RT_CTX_SIZE
+
+ /* Save callee-saved registers on to the stack */
+ stp x19, x20, [sp, #SPMD_C_RT_CTX_X19]
+ stp x21, x22, [sp, #SPMD_C_RT_CTX_X21]
+ stp x23, x24, [sp, #SPMD_C_RT_CTX_X23]
+ stp x25, x26, [sp, #SPMD_C_RT_CTX_X25]
+ stp x27, x28, [sp, #SPMD_C_RT_CTX_X27]
+ stp x29, x30, [sp, #SPMD_C_RT_CTX_X29]
+
+ /* ---------------------------------------------------------------------
+ * Everything is setup now. el3_exit() will use the secure context to
+ * restore to the general purpose and EL3 system registers to ERET
+ * into the secure payload.
+ * ---------------------------------------------------------------------
+ */
+ b el3_exit
+endfunc spmd_spm_core_enter
+
+ /* ---------------------------------------------------------------------
+ * This function is called with 'x0' pointing to a C runtime context.
+ * It restores the saved registers and jumps to that runtime with 'x0'
+ * as the new SP register. This destroys the C runtime context that had
+ * been built on the stack below the saved context by the caller. Later
+ * the second parameter 'x1' is passed as a return value to the caller.
+ * ---------------------------------------------------------------------
+ */
+func spmd_spm_core_exit
+ /* Restore the previous stack */
+ mov sp, x0
+
+ /* Restore callee-saved registers on to the stack */
+ ldp x19, x20, [x0, #(SPMD_C_RT_CTX_X19 - SPMD_C_RT_CTX_SIZE)]
+ ldp x21, x22, [x0, #(SPMD_C_RT_CTX_X21 - SPMD_C_RT_CTX_SIZE)]
+ ldp x23, x24, [x0, #(SPMD_C_RT_CTX_X23 - SPMD_C_RT_CTX_SIZE)]
+ ldp x25, x26, [x0, #(SPMD_C_RT_CTX_X25 - SPMD_C_RT_CTX_SIZE)]
+ ldp x27, x28, [x0, #(SPMD_C_RT_CTX_X27 - SPMD_C_RT_CTX_SIZE)]
+ ldp x29, x30, [x0, #(SPMD_C_RT_CTX_X29 - SPMD_C_RT_CTX_SIZE)]
+
+ /* ---------------------------------------------------------------------
+ * This should take us back to the instruction after the call to the
+ * last spm_secure_partition_enter().* Place the second parameter to x0
+ * so that the caller will see it as a return value from the original
+ * entry call.
+ * ---------------------------------------------------------------------
+ */
+ mov x0, x1
+ ret
+endfunc spmd_spm_core_exit
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
new file mode 100644
index 0000000..38d43f1
--- /dev/null
+++ b/services/std_svc/spmd/spmd.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch64)
+ $(error "Error: SPMD is only supported on aarch64.")
+endif
+
+SPMD_SOURCES += $(addprefix services/std_svc/spmd/, \
+ ${ARCH}/spmd_helpers.S \
+ spmd_main.c)
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32 := yes
+
+# Enable dynamic memory mapping
+# The SPMD component maps the SPMC DTB within BL31 virtual space.
+PLAT_XLAT_TABLES_DYNAMIC := 1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
new file mode 100644
index 0000000..677f639
--- /dev/null
+++ b/services/std_svc/spmd/spmd_main.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/spci_svc.h>
+#include <services/spmd_svc.h>
+#include <smccc_helpers.h>
+#include "spmd_private.h"
+
+/*******************************************************************************
+ * SPM Core context information.
+ ******************************************************************************/
+spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
+
+/*******************************************************************************
+ * SPM Core attribute information read from its manifest.
+ ******************************************************************************/
+spmc_manifest_sect_attribute_t spmc_attrs;
+
+/*******************************************************************************
+ * This function takes an SP context pointer and performs a synchronous entry
+ * into it.
+ ******************************************************************************/
+uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx)
+{
+ uint64_t rc;
+
+ assert(spmc_ctx != NULL);
+
+ cm_set_context(&(spmc_ctx->cpu_ctx), SECURE);
+
+ /* Restore the context assigned above */
+ cm_el1_sysregs_context_restore(SECURE);
+ cm_set_next_eret_context(SECURE);
+
+ /* Invalidate TLBs at EL1. */
+ tlbivmalle1();
+ dsbish();
+
+ /* Enter Secure Partition */
+ rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx);
+
+ /* Save secure state */
+ cm_el1_sysregs_context_save(SECURE);
+
+ return rc;
+}
+
+/*******************************************************************************
+ * This function returns to the place where spm_sp_synchronous_entry() was
+ * called originally.
+ ******************************************************************************/
+__dead2 void spmd_spm_core_sync_exit(uint64_t rc)
+{
+ spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+
+ /* Get context of the SP in use by this CPU. */
+ assert(cm_get_context(SECURE) == &(ctx->cpu_ctx));
+
+ /*
+ * The SPMD must have initiated the original request through a
+ * synchronous entry into SPMC. Jump back to the original C runtime
+ * context with the value of rc in x0;
+ */
+ spmd_spm_core_exit(ctx->c_rt_ctx, rc);
+
+ panic();
+}
+
+/*******************************************************************************
+ * Jump to the SPM core for the first time.
+ ******************************************************************************/
+static int32_t spmd_init(void)
+{
+ uint64_t rc = 0;
+ spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+
+ INFO("SPM Core init start.\n");
+ ctx->state = SPMC_STATE_RESET;
+
+ rc = spmd_spm_core_sync_entry(ctx);
+ if (rc) {
+ ERROR("SPMC initialisation failed 0x%llx\n", rc);
+ panic();
+ }
+
+ ctx->state = SPMC_STATE_IDLE;
+ INFO("SPM Core init end.\n");
+
+ return 1;
+}
+
+/*******************************************************************************
+ * Initialize context of SPM core.
+ ******************************************************************************/
+int32_t spmd_setup(void)
+{
+ int rc;
+ void *rd_base;
+ size_t rd_size;
+ entry_point_info_t *spmc_ep_info;
+ uintptr_t rd_base_align;
+ uintptr_t rd_size_align;
+ uint32_t ep_attr;
+
+ spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+ if (!spmc_ep_info) {
+ WARN("No SPM core image provided by BL2 boot loader, Booting "
+ "device without SP initialization. SMC`s destined for SPM "
+ "core will return SMC_UNK\n");
+ return 1;
+ }
+
+ /* Under no circumstances will this parameter be 0 */
+ assert(spmc_ep_info->pc != 0U);
+
+ /*
+ * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will
+ * be used as a manifest for the SPM core at the next lower EL/mode.
+ */
+ if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) {
+ ERROR("Invalid or absent SPM core manifest\n");
+ panic();
+ }
+
+ /* Obtain whereabouts of SPM core manifest */
+ rd_base = (void *) spmc_ep_info->args.arg0;
+ rd_size = spmc_ep_info->args.arg2;
+
+ rd_base_align = page_align((uintptr_t) rd_base, DOWN);
+ rd_size_align = page_align((uintptr_t) rd_size, UP);
+
+ /* Map the manifest in the SPMD translation regime first */
+ VERBOSE("SPM core manifest base : 0x%lx\n", rd_base_align);
+ VERBOSE("SPM core manifest size : 0x%lx\n", rd_size_align);
+ rc = mmap_add_dynamic_region((unsigned long long) rd_base_align,
+ (uintptr_t) rd_base_align,
+ rd_size_align,
+ MT_RO_DATA);
+ if (rc < 0) {
+ ERROR("Error while mapping SPM core manifest (%d).\n", rc);
+ panic();
+ }
+
+ /* Load the SPM core manifest */
+ rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size);
+ if (rc < 0) {
+ WARN("No or invalid SPM core manifest image provided by BL2 "
+ "boot loader. ");
+ goto error;
+ }
+
+ /*
+ * Ensure that the SPM core version is compatible with the SPM
+ * dispatcher version
+ */
+ if ((spmc_attrs.major_version != SPCI_VERSION_MAJOR) ||
+ (spmc_attrs.minor_version > SPCI_VERSION_MINOR)) {
+ WARN("Unsupported SPCI version (%x.%x) specified in SPM core "
+ "manifest image provided by BL2 boot loader.\n",
+ spmc_attrs.major_version, spmc_attrs.minor_version);
+ goto error;
+ }
+
+ INFO("SPCI version (%x.%x).\n", spmc_attrs.major_version,
+ spmc_attrs.minor_version);
+
+ /* Validate the SPM core runtime EL */
+ if ((spmc_attrs.runtime_el != MODE_EL1) &&
+ (spmc_attrs.runtime_el != MODE_EL2)) {
+ WARN("Unsupported SPM core run time EL%x specified in "
+ "manifest image provided by BL2 boot loader.\n",
+ spmc_attrs.runtime_el);
+ goto error;
+ }
+
+ INFO("SPM core run time EL%x.\n", spmc_attrs.runtime_el);
+
+ /* Validate the SPM core execution state */
+ if ((spmc_attrs.exec_state != MODE_RW_64) &&
+ (spmc_attrs.exec_state != MODE_RW_32)) {
+ WARN("Unsupported SPM core execution state %x specified in "
+ "manifest image provided by BL2 boot loader.\n",
+ spmc_attrs.exec_state);
+ goto error;
+ }
+
+ INFO("SPM core execution state %x.\n", spmc_attrs.exec_state);
+
+ /* Ensure manifest has not requested S-EL2 in AArch32 state */
+ if ((spmc_attrs.exec_state == MODE_RW_32) &&
+ (spmc_attrs.runtime_el == MODE_EL2)) {
+ WARN("Invalid combination of SPM core execution state (%x) "
+ "and run time EL (%x).\n", spmc_attrs.exec_state,
+ spmc_attrs.runtime_el);
+ goto error;
+ }
+
+ /*
+ * Check if S-EL2 is supported on this system if S-EL2
+ * is required for SPM
+ */
+ if (spmc_attrs.runtime_el == MODE_EL2) {
+ uint64_t sel2 = read_id_aa64pfr0_el1();
+
+ sel2 >>= ID_AA64PFR0_SEL2_SHIFT;
+ sel2 &= ID_AA64PFR0_SEL2_MASK;
+
+ if (!sel2) {
+ WARN("SPM core run time EL: S-EL%x is not supported "
+ "but specified in manifest image provided by "
+ "BL2 boot loader.\n", spmc_attrs.runtime_el);
+ goto error;
+ }
+ }
+
+ /* Initialise an entrypoint to set up the CPU context */
+ ep_attr = SECURE | EP_ST_ENABLE;
+ if (read_sctlr_el3() & SCTLR_EE_BIT)
+ ep_attr |= EP_EE_BIG;
+ SET_PARAM_HEAD(spmc_ep_info, PARAM_EP, VERSION_1, ep_attr);
+ assert(spmc_ep_info->pc == BL32_BASE);
+
+ /*
+ * Populate SPSR for SPM core based upon validated parameters from the
+ * manifest
+ */
+ if (spmc_attrs.exec_state == MODE_RW_32) {
+ spmc_ep_info->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+ SPSR_E_LITTLE,
+ DAIF_FIQ_BIT |
+ DAIF_IRQ_BIT |
+ DAIF_ABT_BIT);
+ } else {
+ spmc_ep_info->spsr = SPSR_64(spmc_attrs.runtime_el,
+ MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
+ }
+
+ /* Initialise SPM core context with this entry point information */
+ cm_setup_context(&(spm_core_context[plat_my_core_pos()].cpu_ctx),
+ spmc_ep_info);
+
+ INFO("SPM core setup done.\n");
+
+ /* Register init function for deferred init. */
+ bl31_register_bl32_init(&spmd_init);
+
+ return 0;
+
+error:
+ WARN("Booting device without SPM initialization. "
+ "SPCI SMCs destined for SPM core will return "
+ "ENOTSUPPORTED\n");
+
+ rc = mmap_remove_dynamic_region(rd_base_align, rd_size_align);
+ if (rc < 0) {
+ ERROR("Error while unmapping SPM core manifest (%d).\n",
+ rc);
+ panic();
+ }
+
+ return 1;
+}
+
+/*******************************************************************************
+ * This function handles all SMCs in the range reserved for SPCI. Each call is
+ * either forwarded to the other security state or handled by the SPM dispatcher
+ ******************************************************************************/
+uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
+ uint64_t x3, uint64_t x4, void *cookie, void *handle,
+ uint64_t flags)
+{
+ uint32_t in_sstate;
+ uint32_t out_sstate;
+ int32_t ret;
+ spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+
+ /* Determine which security state this SMC originated from */
+ if (is_caller_secure(flags)) {
+ in_sstate = SECURE;
+ out_sstate = NON_SECURE;
+ } else {
+ in_sstate = NON_SECURE;
+ out_sstate = SECURE;
+ }
+
+ INFO("SPM: 0x%x, 0x%llx, 0x%llx, 0x%llx, 0x%llx, "
+ "0x%llx, 0x%llx, 0x%llx\n",
+ smc_fid, x1, x2, x3, x4, SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+
+ switch (smc_fid) {
+ case SPCI_ERROR:
+ /*
+ * Check if this is the first invocation of this interface on
+ * this CPU. If so, then indicate that the SPM core initialised
+ * unsuccessfully.
+ */
+ if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET))
+ spmd_spm_core_sync_exit(x2);
+
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(in_sstate);
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(out_sstate);
+ cm_set_next_eret_context(out_sstate);
+
+ SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ break; /* not reached */
+
+ case SPCI_VERSION:
+ /*
+ * TODO: This is an optimization that the version information
+ * provided by the SPM core manifest is returned by the SPM
+ * dispatcher. It might be a better idea to simply forward this
+ * call to the SPM core and wash our hands completely.
+ */
+ ret = MAKE_SPCI_VERSION(spmc_attrs.major_version,
+ spmc_attrs.minor_version);
+ SMC_RET8(handle, SPCI_SUCCESS_SMC32, SPCI_TARGET_INFO_MBZ, ret,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ break; /* not reached */
+
+ case SPCI_FEATURES:
+ /*
+ * This is an optional interface. Do the minimal checks and
+ * forward to SPM core which will handle it if implemented.
+ */
+
+ /*
+ * Check if w1 holds a valid SPCI fid. This is an
+ * optimization.
+ */
+ if (!is_spci_fid(x1))
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+
+ /* Forward SMC from Normal world to the SPM core */
+ if (in_sstate == NON_SECURE) {
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(in_sstate);
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(out_sstate);
+ cm_set_next_eret_context(out_sstate);
+
+ SMC_RET8(cm_get_context(out_sstate), smc_fid,
+ x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ } else {
+ /*
+ * Return success if call was from secure world i.e. all
+ * SPCI functions are supported. This is essentially a
+ * nop.
+ */
+ SMC_RET8(handle, SPCI_SUCCESS_SMC32, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ }
+ break; /* not reached */
+
+ case SPCI_RX_RELEASE:
+ case SPCI_RXTX_MAP_SMC32:
+ case SPCI_RXTX_MAP_SMC64:
+ case SPCI_RXTX_UNMAP:
+ case SPCI_MSG_RUN:
+ /* This interface must be invoked only by the Normal world */
+ if (in_sstate == SECURE) {
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ }
+
+ /* Fall through to forward the call to the other world */
+
+ case SPCI_PARTITION_INFO_GET:
+ case SPCI_MSG_SEND:
+ case SPCI_MSG_SEND_DIRECT_REQ_SMC32:
+ case SPCI_MSG_SEND_DIRECT_REQ_SMC64:
+ case SPCI_MSG_SEND_DIRECT_RESP_SMC32:
+ case SPCI_MSG_SEND_DIRECT_RESP_SMC64:
+ case SPCI_MEM_DONATE_SMC32:
+ case SPCI_MEM_DONATE_SMC64:
+ case SPCI_MEM_LEND_SMC32:
+ case SPCI_MEM_LEND_SMC64:
+ case SPCI_MEM_SHARE_SMC32:
+ case SPCI_MEM_SHARE_SMC64:
+ case SPCI_MEM_RETRIEVE_REQ_SMC32:
+ case SPCI_MEM_RETRIEVE_REQ_SMC64:
+ case SPCI_MEM_RETRIEVE_RESP:
+ case SPCI_MEM_RELINQUISH:
+ case SPCI_MEM_RECLAIM:
+ case SPCI_SUCCESS_SMC32:
+ case SPCI_SUCCESS_SMC64:
+ /*
+ * TODO: Assume that no requests originate from EL3 at the
+ * moment. This will change if a SP service is required in
+ * response to secure interrupts targeted to EL3. Until then
+ * simply forward the call to the Normal world.
+ */
+
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(in_sstate);
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(out_sstate);
+ cm_set_next_eret_context(out_sstate);
+
+ SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ break; /* not reached */
+
+ case SPCI_MSG_WAIT:
+ /*
+ * Check if this is the first invocation of this interface on
+ * this CPU from the Secure world. If so, then indicate that the
+ * SPM core initialised successfully.
+ */
+ if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET)) {
+ spmd_spm_core_sync_exit(0);
+ }
+
+ /* Intentional fall-through */
+
+ case SPCI_MSG_YIELD:
+ /* This interface must be invoked only by the Secure world */
+ if (in_sstate == NON_SECURE) {
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ }
+
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(in_sstate);
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(out_sstate);
+ cm_set_next_eret_context(out_sstate);
+
+ SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ break; /* not reached */
+
+ default:
+ WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ }
+}
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
new file mode 100644
index 0000000..61b479a
--- /dev/null
+++ b/services/std_svc/spmd/spmd_private.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMD_PRIVATE_H
+#define SPMD_PRIVATE_H
+
+#include <context.h>
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve callee-saved registers of the
+ * C runtime context while performing a security state switch.
+ ******************************************************************************/
+#define SPMD_C_RT_CTX_X19 0x0
+#define SPMD_C_RT_CTX_X20 0x8
+#define SPMD_C_RT_CTX_X21 0x10
+#define SPMD_C_RT_CTX_X22 0x18
+#define SPMD_C_RT_CTX_X23 0x20
+#define SPMD_C_RT_CTX_X24 0x28
+#define SPMD_C_RT_CTX_X25 0x30
+#define SPMD_C_RT_CTX_X26 0x38
+#define SPMD_C_RT_CTX_X27 0x40
+#define SPMD_C_RT_CTX_X28 0x48
+#define SPMD_C_RT_CTX_X29 0x50
+#define SPMD_C_RT_CTX_X30 0x58
+
+#define SPMD_C_RT_CTX_SIZE 0x60
+#define SPMD_C_RT_CTX_ENTRIES (SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLER__
+#include <services/spci_svc.h>
+#include <stdint.h>
+
+/*
+ * Convert a function no. in a FID to a bit position. All function nos. are
+ * between 0 and 0x1f
+ */
+#define SPCI_FNO_TO_BIT_POS(_fid) (1 << ((_fid) & U(0x1f)))
+
+typedef enum spmc_state {
+ SPMC_STATE_RESET = 0,
+ SPMC_STATE_IDLE
+} spmc_state_t;
+
+/*
+ * Data structure used by the SPM dispatcher (SPMD) in EL3 to track context of
+ * the SPM core (SPMC) at the next lower EL.
+ */
+typedef struct spmd_spm_core_context {
+ uint64_t c_rt_ctx;
+ cpu_context_t cpu_ctx;
+ spmc_state_t state;
+} spmd_spm_core_context_t;
+
+/*
+ * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of
+ * SPCI calls from lower ELs.
+ *
+ * next_smc_bit_map: Per-cpu bit map of SMCs from each world that are expected
+ * next.
+ */
+typedef struct spmd_spci_context {
+ uint32_t next_smc_bit_map[2];
+} spmd_spci_context_t;
+
+/* Functions used to enter/exit a Secure Partition synchronously */
+uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx);
+__dead2 void spmd_spm_core_sync_exit(uint64_t rc);
+
+/* Assembly helpers */
+uint64_t spmd_spm_core_enter(uint64_t *c_rt_ctx);
+void __dead2 spmd_spm_core_exit(uint64_t c_rt_ctx, uint64_t ret);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPMD_PRIVATE_H */
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 7787a2f..895fd29 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,6 +15,7 @@
#include <lib/runtime_instr.h>
#include <services/sdei.h>
#include <services/spm_mm_svc.h>
+#include <services/spmd_svc.h>
#include <services/std_svc.h>
#include <smccc_helpers.h>
#include <tools_share/uuid.h>
@@ -51,6 +52,12 @@
}
#endif
+#if defined(SPD_spmd)
+ if (spmd_setup() != 0) {
+ ret = 1;
+ }
+#endif
+
#if SDEI_SUPPORT
/* SDEI initialisation */
sdei_init();
@@ -114,6 +121,17 @@
}
#endif
+#if defined(SPD_spmd)
+ /*
+ * Dispatch SPCI calls to the SPCI SMC handler implemented by the SPM
+ * dispatcher and return its return value
+ */
+ if (is_spci_fid(smc_fid)) {
+ return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
+ }
+#endif
+
#if SDEI_SUPPORT
if (is_sdei_fid(smc_fid)) {
return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,