aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/getting_started/docs-build.rst29
-rw-r--r--docs/getting_started/porting-guide.rst13
-rw-r--r--drivers/arm/tzc/tzc_dmc620.c35
-rw-r--r--include/drivers/arm/tzc_dmc620.h10
-rw-r--r--include/plat/common/platform.h5
-rw-r--r--plat/arm/board/arm_fpga/aarch64/fpga_helpers.S63
-rw-r--r--plat/arm/board/arm_fpga/fpga_bl31_setup.c51
-rw-r--r--plat/arm/board/arm_fpga/fpga_def.h1
-rw-r--r--plat/arm/board/arm_fpga/fpga_private.h15
-rw-r--r--plat/arm/board/arm_fpga/fpga_topology.c70
-rw-r--r--plat/arm/board/arm_fpga/include/platform_def.h9
-rw-r--r--plat/arm/common/arm_bl31_setup.c20
-rw-r--r--plat/arm/common/arm_common.c19
-rw-r--r--plat/common/plat_bl_common.c7
-rw-r--r--plat/nvidia/tegra/common/tegra_platform.c22
-rw-r--r--services/arm_arch_svc/arm_arch_svc_setup.c3
16 files changed, 292 insertions, 80 deletions
diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst
index 91b1b3a397..87c677fcde 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -67,7 +67,7 @@ Output from the build process will be placed in:
::
- docs/build/html/
+ docs/build/html
We also support building documentation in other formats. From the ``docs``
directory of the project, run the following command to see the supported
@@ -79,6 +79,31 @@ top-level Makefile for |TF-A| itself.
make help
+Building rendered documentation from a container
+------------------------------------------------
+
+There may be cases where you can not either install or upgrade required
+dependencies to generate the documents, so in this case, one way to
+create the documentation is through a docker container. The first step is
+to check if `docker`_ is installed in your host, otherwise check main docker
+page for installation instructions. Once installed, run the following script
+from project root directory
+
+.. code:: shell
+
+ docker run --rm -v $PWD:/TF sphinxdoc/sphinx \
+ bash -c 'cd /TF && \
+ pip3 install plantuml -r ./docs/requirements.txt && make doc'
+
+The above command fetches the ``sphinxdoc/sphinx`` container from `docker
+hub`_, launches the container, installs documentation requirements and finally
+creates the documentation. Once done, exit the container and output from the
+build process will be placed in:
+
+::
+
+ docs/build/html
+
--------------
*Copyright (c) 2019, Arm Limited. All rights reserved.*
@@ -86,3 +111,5 @@ top-level Makefile for |TF-A| itself.
.. _Sphinx: http://www.sphinx-doc.org/en/master/
.. _pip homepage: https://pip.pypa.io/en/stable/
.. _Dia: https://wiki.gnome.org/Apps/Dia
+.. _docker: https://www.docker.com/
+.. _docker hub: https://hub.docker.com/repository/docker/sphinxdoc/sphinx
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index c98f3cc041..7aaeae2f4e 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -1130,6 +1130,7 @@ This function returns soc version which mainly consist of below fields
soc_version[30:24] = JEP-106 continuation code for the SiP
soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
+ soc_version[15:0] = Implementation defined SoC ID
Function : plat_get_soc_revision()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1145,6 +1146,18 @@ This function returns soc revision in below format
soc_revision[0:30] = SOC revision of specific SOC
+Function : plat_is_smccc_feature_available()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : u_register_t
+ Return : int32_t
+
+This function returns SMC_ARCH_CALL_SUCCESS if the platform supports
+the SMCCC function specified in the argument; otherwise returns
+SMC_ARCH_CALL_NOT_SUPPORTED.
+
Modifications specific to a Boot Loader stage
---------------------------------------------
diff --git a/drivers/arm/tzc/tzc_dmc620.c b/drivers/arm/tzc/tzc_dmc620.c
index 64ec5abee7..7e307ee504 100644
--- a/drivers/arm/tzc/tzc_dmc620.c
+++ b/drivers/arm/tzc/tzc_dmc620.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,7 +17,7 @@
/* Helper macro for getting dmc_base addr of a dmc_inst */
#define DMC_BASE(plat_data, dmc_inst) \
- ((uintptr_t)(plat_data->dmc_base[dmc_inst]))
+ ((uintptr_t)((plat_data)->dmc_base[(dmc_inst)]))
/* Pointer to the tzc_dmc620_config_data structure populated by the platform */
static const tzc_dmc620_config_data_t *g_plat_config_data;
@@ -31,8 +31,7 @@ static const tzc_dmc620_config_data_t *g_plat_config_data;
static void tzc_dmc620_validate_plat_driver_data(
const tzc_dmc620_driver_data_t *plat_driver_data)
{
- uint8_t dmc_inst, dmc_count;
- unsigned int dmc_id;
+ unsigned int dmc_inst, dmc_count, dmc_id;
uintptr_t base;
assert(plat_driver_data != NULL);
@@ -59,7 +58,7 @@ static void tzc_dmc620_configure_region(int region_no,
{
uint32_t min_31_00, min_47_32;
uint32_t max_31_00, max_47_32;
- uint8_t dmc_inst, dmc_count;
+ unsigned int dmc_inst, dmc_count;
uintptr_t base;
const tzc_dmc620_driver_data_t *plat_driver_data;
@@ -67,19 +66,19 @@ static void tzc_dmc620_configure_region(int region_no,
assert(plat_driver_data != NULL);
/* Do range checks on regions. */
- assert((region_no >= 0U) && (region_no <= DMC620_ACC_ADDR_COUNT));
+ assert((region_no >= 0) && (region_no <= DMC620_ACC_ADDR_COUNT));
/* region_base and (region_top + 1) must be 4KB aligned */
assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U);
dmc_count = plat_driver_data->dmc_count;
for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
- min_31_00 = (region_base & MASK_31_16) | sec_attr;
- min_47_32 = (region_base & MASK_47_32)
- >> DMC620_ACC_ADDR_WIDTH;
- max_31_00 = (region_top & MASK_31_16);
- max_47_32 = (region_top & MASK_47_32)
- >> DMC620_ACC_ADDR_WIDTH;
+ min_31_00 = (uint32_t)((region_base & MASK_31_16) | sec_attr);
+ min_47_32 = (uint32_t)((region_base & MASK_47_32)
+ >> DMC620_ACC_ADDR_WIDTH);
+ max_31_00 = (uint32_t)(region_top & MASK_31_16);
+ max_47_32 = (uint32_t)((region_top & MASK_47_32)
+ >> DMC620_ACC_ADDR_WIDTH);
/* Extract the base address of the DMC-620 instance */
base = DMC_BASE(plat_driver_data, dmc_inst);
@@ -100,7 +99,7 @@ static void tzc_dmc620_configure_region(int region_no,
*/
static void tzc_dmc620_set_action(void)
{
- uint8_t dmc_inst, dmc_count;
+ unsigned int dmc_inst, dmc_count;
uintptr_t base;
const tzc_dmc620_driver_data_t *plat_driver_data;
@@ -123,7 +122,7 @@ static void tzc_dmc620_set_action(void)
*/
static void tzc_dmc620_verify_complete(void)
{
- uint8_t dmc_inst, dmc_count;
+ unsigned int dmc_inst, dmc_count;
uintptr_t base;
const tzc_dmc620_driver_data_t *plat_driver_data;
@@ -133,8 +132,9 @@ static void tzc_dmc620_verify_complete(void)
/* Extract the base address of the DMC-620 instance */
base = DMC_BASE(plat_driver_data, dmc_inst);
while ((mmio_read_32(base + DMC620_MEMC_STATUS) &
- DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO)
+ DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO) {
continue;
+ }
}
}
@@ -145,7 +145,7 @@ static void tzc_dmc620_verify_complete(void)
*/
void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data)
{
- int i;
+ uint8_t i;
/* Check if valid pointer is passed */
assert(plat_config_data != NULL);
@@ -164,11 +164,12 @@ void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data)
g_plat_config_data = plat_config_data;
INFO("Configuring DMC-620 TZC settings\n");
- for (i = 0U; i < g_plat_config_data->acc_addr_count; i++)
+ for (i = 0U; i < g_plat_config_data->acc_addr_count; i++) {
tzc_dmc620_configure_region(i,
g_plat_config_data->plat_acc_addr_data[i].region_base,
g_plat_config_data->plat_acc_addr_data[i].region_top,
g_plat_config_data->plat_acc_addr_data[i].sec_attr);
+ }
tzc_dmc620_set_action();
tzc_dmc620_verify_complete();
diff --git a/include/drivers/arm/tzc_dmc620.h b/include/drivers/arm/tzc_dmc620.h
index e0e6760b28..26c444d101 100644
--- a/include/drivers/arm/tzc_dmc620.h
+++ b/include/drivers/arm/tzc_dmc620.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
*/
@@ -32,16 +32,16 @@
/* Address offsets of access address next registers */
#define DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no) \
(DMC620_ACC_ADDR_MIN_31_00_NEXT_BASE + \
- (region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+ ((region_no) * DMC620_ACC_ADDR_NEXT_SIZE))
#define DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no) \
(DMC620_ACC_ADDR_MIN_47_32_NEXT_BASE + \
- (region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+ ((region_no) * DMC620_ACC_ADDR_NEXT_SIZE))
#define DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no) \
(DMC620_ACC_ADDR_MAX_31_00_NEXT_BASE + \
- (region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+ ((region_no) * DMC620_ACC_ADDR_NEXT_SIZE))
#define DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no) \
(DMC620_ACC_ADDR_MAX_47_32_NEXT_BASE + \
- (region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+ ((region_no) * DMC620_ACC_ADDR_NEXT_SIZE))
/* Number of TZC address regions in DMC-620 */
#define DMC620_ACC_ADDR_COUNT U(8)
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 658b423801..2c1a180c83 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -341,4 +341,9 @@ int32_t plat_get_soc_version(void);
*/
int32_t plat_get_soc_revision(void);
+/*
+ * Optional function to check for SMCCC function availability for platform
+ */
+int32_t plat_is_smccc_feature_available(u_register_t fid);
+
#endif /* PLATFORM_H */
diff --git a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S
index aeed3108ed..20120c9c3c 100644
--- a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S
+++ b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S
@@ -7,6 +7,8 @@
#include <arch.h>
#include <asm_macros.S>
#include <common/bl_common.h>
+#include "../fpga_private.h"
+
#include <platform_def.h>
.globl plat_get_my_entrypoint
@@ -14,10 +16,10 @@
.globl plat_is_my_cpu_primary
.globl platform_mem_init
.globl plat_my_core_pos
- .globl plat_fpga_calc_core_pos
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl plat_crash_console_flush
+ .globl plat_fpga_calc_core_pos
/* -----------------------------------------------------------------------
* Indicate a cold boot for every CPU - warm boot is unsupported for the
@@ -34,23 +36,59 @@ endfunc plat_get_my_entrypoint
* -----------------------------------------------------------------------
*/
func plat_secondary_cold_boot_setup
+
+ /*
+ * Wait for the primary processor to initialise the .BSS segment
+ * to avoid a race condition that would erase fpga_valid_mpids
+ * if it is populated before the C runtime is ready.
+ *
+ * We cannot use the current spin-lock implementation until the
+ * runtime is up and we should not rely on sevl/wfe instructions as
+ * it is optional whether they are implemented or not, so we use
+ * a global variable as lock and wait for the primary processor to
+ * finish the C runtime bring-up.
+ */
+
+ ldr w0, =C_RUNTIME_READY_KEY
+ adrp x1, secondary_core_spinlock
+ add x1, x1, :lo12:secondary_core_spinlock
+1:
+ wfe
+ ldr w2, [x1]
+ cmp w2, w0
+ b.ne 1b
+ /* Prevent reordering of the store into fpga_valid_mpids below */
+ dmb ish
+
+ mov x10, x30
+ bl plat_my_core_pos
+ mov x30, x10
+
+ adrp x4, fpga_valid_mpids
+ add x4, x4, :lo12:fpga_valid_mpids
+ mov x5, #VALID_MPID
+ strb w5, [x4, x0]
+
/*
* Poll the CPU's hold entry until it indicates to jump
* to the entrypoint address.
*/
- bl plat_my_core_pos
- lsl x0, x0, #PLAT_FPGA_HOLD_ENTRY_SHIFT
- ldr x1, =hold_base
- ldr x2, =fpga_sec_entrypoint
+
+ adrp x1, hold_base
+ add x1, x1, :lo12:hold_base
poll_hold_entry:
- ldr x3, [x1, x0]
+ ldr x3, [x1, x0, LSL #PLAT_FPGA_HOLD_ENTRY_SHIFT]
cmp x3, #PLAT_FPGA_HOLD_STATE_GO
b.ne 1f
+
+ adrp x2, fpga_sec_entrypoint
+ add x2, x2, :lo12:fpga_sec_entrypoint
ldr x3, [x2]
br x3
1:
wfe
b poll_hold_entry
+
endfunc plat_secondary_cold_boot_setup
/* -----------------------------------------------------------------------
@@ -73,12 +111,16 @@ func platform_mem_init
endfunc platform_mem_init
func plat_my_core_pos
+ ldr x1, =(MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT))
mrs x0, mpidr_el1
+ and x0, x0, x1
b plat_fpga_calc_core_pos
+
endfunc plat_my_core_pos
/* -----------------------------------------------------------------------
- * unsigned int plat_fpga_calc_core_pos(u_register_t mpidr)
+ * unsigned int plat_fpga_calc_core_pos (uint32_t mpid)
+ * Clobber registers: x0 to x5
* -----------------------------------------------------------------------
*/
func plat_fpga_calc_core_pos
@@ -88,6 +130,7 @@ func plat_fpga_calc_core_pos
*
* If not set, shift MPIDR to left to make it look as if in a
* multi-threaded implementation.
+ *
*/
tst x0, #MPIDR_MT_MASK
lsl x3, x0, #MPIDR_AFFINITY_BITS
@@ -98,11 +141,13 @@ func plat_fpga_calc_core_pos
ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
- /* Compute linear position */
mov x4, #FPGA_MAX_CPUS_PER_CLUSTER
- madd x1, x2, x4, x1
mov x5, #FPGA_MAX_PE_PER_CPU
+
+ /* Compute linear position */
+ madd x1, x2, x4, x1
madd x0, x1, x5, x0
+
ret
endfunc plat_fpga_calc_core_pos
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index e4b9767d40..6eeff451cc 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -7,23 +7,23 @@
#include <assert.h>
#include <common/fdt_wrappers.h>
+#include <drivers/delay_timer.h>
#include <drivers/generic_delay_timer.h>
-#include <lib/mmio.h>
#include <libfdt.h>
+#include "fpga_private.h"
#include <plat/common/platform.h>
#include <platform_def.h>
-#include "fpga_private.h"
-
static entry_point_info_t bl33_image_ep_info;
+volatile uint32_t secondary_core_spinlock;
uintptr_t plat_get_ns_image_entrypoint(void)
{
#ifdef PRELOADED_BL33_BASE
return PRELOADED_BL33_BASE;
#else
- return 0;
+ return 0ULL;
#endif
}
@@ -35,6 +35,17 @@ uint32_t fpga_get_spsr_for_bl33_entry(void)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
+ /* Add this core to the VALID mpids list */
+ fpga_valid_mpids[plat_my_core_pos()] = VALID_MPID;
+
+ /*
+ * Notify the secondary CPUs that the C runtime is ready
+ * so they can announce themselves.
+ */
+ secondary_core_spinlock = C_RUNTIME_READY_KEY;
+ dsbish();
+ sev();
+
fpga_console_init();
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
@@ -54,11 +65,37 @@ void bl31_plat_arch_setup(void)
void bl31_platform_setup(void)
{
- /* Initialize the GIC driver, cpu and distributor interfaces */
- plat_fpga_gic_init();
-
/* Write frequency to CNTCRL and initialize timer */
generic_delay_timer_init();
+
+ /*
+ * Before doing anything else, wait for some time to ensure that
+ * the secondary CPUs have populated the fpga_valid_mpids array.
+ * As the number of secondary cores is unknown and can even be 0,
+ * it is not possible to rely on any signal from them, so use a
+ * delay instead.
+ */
+ mdelay(5);
+
+ /*
+ * On the event of a cold reset issued by, for instance, a reset pin
+ * assertion, we cannot guarantee memory to be initialized to zero.
+ * In such scenario, if the secondary cores reached
+ * plat_secondary_cold_boot_setup before the primary one initialized
+ * .BSS, we could end up having a race condition if the spinlock
+ * was not cleared before.
+ *
+ * Similarly, if there were a reset before the spinlock had been
+ * cleared, the secondary cores would find the lock opened before
+ * .BSS is cleared, causing another race condition.
+ *
+ * So clean the spinlock as soon as we think it is safe to reduce the
+ * chances of any race condition on a reset.
+ */
+ secondary_core_spinlock = 0UL;
+
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ plat_fpga_gic_init();
}
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h
index 5f1951f792..2884ea6d4f 100644
--- a/plat/arm/board/arm_fpga/fpga_def.h
+++ b/plat/arm/board/arm_fpga/fpga_def.h
@@ -18,6 +18,7 @@
* that are present will still be indexed appropriately regardless of any empty
* entries in the array used to represent the topology.
*/
+
#define FPGA_MAX_CLUSTER_COUNT 4
#define FPGA_MAX_CPUS_PER_CLUSTER 8
#define FPGA_MAX_PE_PER_CPU 4
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
index 7545bd17eb..46287adea7 100644
--- a/plat/arm/board/arm_fpga/fpga_private.h
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -7,12 +7,23 @@
#ifndef FPGA_PRIVATE_H
#define FPGA_PRIVATE_H
-unsigned int plat_fpga_calc_core_pos(u_register_t mpidr);
+#include "../fpga_def.h"
+#include <platform_def.h>
+
+#define C_RUNTIME_READY_KEY (0xaa55aa55)
+#define VALID_MPID (1U)
+
+#ifndef __ASSEMBLER__
+
+extern unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT];
void fpga_console_init(void);
void plat_fpga_gic_init(void);
void fpga_pwr_gic_on_finish(void);
void fpga_pwr_gic_off(void);
+unsigned int plat_fpga_calc_core_pos(uint32_t mpid);
+
+#endif /* __ASSEMBLER__ */
-#endif
+#endif /* FPGA_PRIVATE_H */
diff --git a/plat/arm/board/arm_fpga/fpga_topology.c b/plat/arm/board/arm_fpga/fpga_topology.c
index a2908d7278..7fead869b5 100644
--- a/plat/arm/board/arm_fpga/fpga_topology.c
+++ b/plat/arm/board/arm_fpga/fpga_topology.c
@@ -5,15 +5,20 @@
*/
#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/spinlock.h>
#include "fpga_private.h"
+#include <plat/common/platform.h>
#include <platform_def.h>
-static unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2];
+unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2];
+unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT];
const unsigned char *plat_get_power_domain_tree_desc(void)
{
- int i;
+ unsigned int i;
+
/*
* The highest level is the system level. The next level is constituted
* by clusters and then cores in clusters.
@@ -21,12 +26,26 @@ const unsigned char *plat_get_power_domain_tree_desc(void)
* This description of the power domain topology is aligned with the CPU
* indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos()
* APIs.
+ *
+ * A description of the topology tree can be found at
+ * https://trustedfirmware-a.readthedocs.io/en/latest/design/psci-pd-tree.html#design
*/
- fpga_power_domain_tree_desc[0] = 1;
- fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT;
- for (i = 0; i < FPGA_MAX_CLUSTER_COUNT; i++) {
- fpga_power_domain_tree_desc[i + 2] = FPGA_MAX_CPUS_PER_CLUSTER * FPGA_MAX_PE_PER_CPU;
+ if (fpga_power_domain_tree_desc[0] == 0U) {
+ /*
+ * As fpga_power_domain_tree_desc[0] == 0, assume that the
+ * Power Domain Topology Tree has not been initialized, so
+ * perform the initialization here.
+ */
+
+ fpga_power_domain_tree_desc[0] = 1U;
+ fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT;
+
+ for (i = 0U; i < FPGA_MAX_CLUSTER_COUNT; i++) {
+ fpga_power_domain_tree_desc[2 + i] =
+ (FPGA_MAX_CPUS_PER_CLUSTER *
+ FPGA_MAX_PE_PER_CPU);
+ }
}
return fpga_power_domain_tree_desc;
@@ -34,40 +53,25 @@ const unsigned char *plat_get_power_domain_tree_desc(void)
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
- unsigned int cluster_id, cpu_id, thread_id;
+ unsigned int core_pos;
- /*
- * The image running on the FPGA may or may not implement
- * multithreading, and it shouldn't be assumed this is consistent
- * across all CPUs.
- * This ensures that any passed mpidr values reflect the status of the
- * primary CPU's MT bit.
- */
+ mpidr &= (MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT));
mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
- mpidr &= MPID_MASK;
- if (mpidr & MPIDR_MT_MASK) {
- thread_id = MPIDR_AFFLVL0_VAL(mpidr);
- cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
- cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
- } else {
- thread_id = 0;
- cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
- cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+ if ((MPIDR_AFFLVL2_VAL(mpidr) >= FPGA_MAX_CLUSTER_COUNT) ||
+ (MPIDR_AFFLVL1_VAL(mpidr) >= FPGA_MAX_CPUS_PER_CLUSTER) ||
+ (MPIDR_AFFLVL0_VAL(mpidr) >= FPGA_MAX_PE_PER_CPU)) {
+ ERROR ("Invalid mpidr: 0x%08x\n", (uint32_t)mpidr);
+ panic();
}
- if (cluster_id >= FPGA_MAX_CLUSTER_COUNT) {
- return -1;
- }
-
- if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) {
- return -1;
- }
+ /* Calculate the core position, based on the maximum topology. */
+ core_pos = plat_fpga_calc_core_pos(mpidr);
- if (thread_id >= FPGA_MAX_PE_PER_CPU) {
+ /* Check whether this core is actually present. */
+ if (fpga_valid_mpids[core_pos] != VALID_MPID) {
return -1;
}
- /* Calculate the correct core, catering for multi-threaded images */
- return (int) plat_fpga_calc_core_pos(mpidr);
+ return core_pos;
}
diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h
index 31fc9870cc..411b936da1 100644
--- a/plat/arm/board/arm_fpga/include/platform_def.h
+++ b/plat/arm/board/arm_fpga/include/platform_def.h
@@ -21,11 +21,12 @@
#define CACHE_WRITEBACK_SHIFT U(6)
#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT)
-#define PLATFORM_CORE_COUNT \
- (FPGA_MAX_CLUSTER_COUNT * FPGA_MAX_CPUS_PER_CLUSTER * FPGA_MAX_PE_PER_CPU)
+#define PLATFORM_CORE_COUNT \
+ (FPGA_MAX_CLUSTER_COUNT * \
+ FPGA_MAX_CPUS_PER_CLUSTER * \
+ FPGA_MAX_PE_PER_CPU)
-#define PLAT_NUM_PWR_DOMAINS (FPGA_MAX_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT) + 1
+#define PLAT_NUM_PWR_DOMAINS (FPGA_MAX_CLUSTER_COUNT + PLATFORM_CORE_COUNT + 1)
#if !ENABLE_PIE
#define BL31_BASE UL(0x80000000)
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index ded8f895eb..58ccf0e511 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -114,6 +114,18 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
bl32_image_ep_info.pc = BL32_BASE;
bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
+
+#if defined(SPD_spmd)
+ /* SPM (hafnium in secure world) expects SPM Core manifest base address
+ * in x0, which in !RESET_TO_BL31 case loaded after base of non shared
+ * SRAM(after 4KB offset of SRAM). But in RESET_TO_BL31 case all non
+ * shared SRAM is allocated to BL31, so to avoid overwriting of manifest
+ * keep it in the last page.
+ */
+ bl32_image_ep_info.args.arg0 = ARM_TRUSTED_SRAM_BASE +
+ PLAT_ARM_TRUSTED_SRAM_SIZE - PAGE_SIZE;
+#endif
+
# endif /* BL32_BASE */
/* Populate entry point information for BL33 */
@@ -130,6 +142,14 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+#if defined(SPD_spmd) && !(ARM_LINUX_KERNEL_AS_BL33)
+ /*
+ * Hafnium in normal world expects its manifest address in x0, which
+ * is loaded at base of DRAM.
+ */
+ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE;
+#endif
+
# if ARM_LINUX_KERNEL_AS_BL33
/*
* According to the file ``Documentation/arm64/booting.txt`` of the
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 60c777ed83..e2b99a3d6d 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -13,7 +13,9 @@
#include <common/debug.h>
#include <common/romlib.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <services/arm_arch_svc.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -235,6 +237,23 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
}
#endif
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ * feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED
+ * otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
+
/*
* Weak function to get ARM platform SOC-ID, Always return SOC-ID=0
* ToDo: Get proper SOC-ID for every ARM platform and define this
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index d38fc6f75b..89b77ba6ce 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -11,6 +11,7 @@
#include <common/debug.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
#include <smccc_helpers.h>
#include <tools_share/firmware_encrypted.h>
@@ -25,6 +26,7 @@
#pragma weak bl2_plat_handle_post_image_load
#pragma weak plat_try_next_boot_source
#pragma weak plat_get_enc_key_info
+#pragma weak plat_is_smccc_feature_available
#pragma weak plat_get_soc_version
#pragma weak plat_get_soc_revision
@@ -38,6 +40,11 @@ int32_t plat_get_soc_revision(void)
return SMC_ARCH_CALL_NOT_SUPPORTED;
}
+int32_t plat_is_smccc_feature_available(u_register_t fid __unused)
+{
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
+
void bl2_el3_plat_prepare_exit(void)
{
}
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index e4338b9638..080413575a 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -8,6 +8,8 @@
#include <arch_helpers.h>
#include <assert.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <services/arm_arch_svc.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
@@ -286,3 +288,21 @@ int32_t plat_get_soc_revision(void)
{
return (int32_t)((tegra_get_chipid_major() << 8) | tegra_get_chipid_minor());
}
+
+/*****************************************************************************
+ * plat_smccc_feature_available() - This function checks whether SMCCC feature
+ * is availabile for the platform or not.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
+ * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
+ *****************************************************************************/
+int32_t plat_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 588656d57f..37bfc62e2b 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -24,8 +24,9 @@ static int32_t smccc_arch_features(u_register_t arg1)
switch (arg1) {
case SMCCC_VERSION:
case SMCCC_ARCH_FEATURES:
+ return SMC_ARCH_CALL_SUCCESS;
case SMCCC_ARCH_SOC_ID:
- return SMC_OK;
+ return plat_is_smccc_feature_available(arg1);
#if WORKAROUND_CVE_2017_5715
case SMCCC_ARCH_WORKAROUND_1:
if (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES)