Merge pull request #1154 from soby-mathew/sm/fix_psci_stat
Fix PSCI STAT time stamp collection
diff --git a/Makefile b/Makefile
index b32b417..a648d8c 100644
--- a/Makefile
+++ b/Makefile
@@ -260,6 +260,8 @@
include ${PLAT_MAKEFILE_FULL}
+$(eval $(call MAKE_PREREQ_DIR,${BUILD_PLAT}))
+
# Platform compatibility is not supported in AArch32
ifneq (${ARCH},aarch32)
# If the platform has not defined ENABLE_PLAT_COMPAT, then enable it by default
diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S
index d794d12..4478d0d 100644
--- a/common/aarch64/debug.S
+++ b/common/aarch64/debug.S
@@ -6,6 +6,7 @@
#include <arch.h>
#include <asm_macros.S>
+#include <debug.h>
.globl asm_print_str
.globl asm_print_hex
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index c0c3a19..bd787ce 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -141,17 +141,17 @@
#define set_cpu_data(_m, _v) _cpu_data()->_m = _v
#define get_cpu_data_by_index(_ix, _m) _cpu_data_by_index(_ix)->_m
#define set_cpu_data_by_index(_ix, _m, _v) _cpu_data_by_index(_ix)->_m = _v
-
+/* ((cpu_data_t *)0)->_m is a dummy to get the sizeof the struct member _m */
#define flush_cpu_data(_m) flush_dcache_range((uintptr_t) \
- &(_cpu_data()->_m), \
- sizeof(_cpu_data()->_m))
+ &(_cpu_data()->_m), \
+ sizeof(((cpu_data_t *)0)->_m))
#define inv_cpu_data(_m) inv_dcache_range((uintptr_t) \
- &(_cpu_data()->_m), \
- sizeof(_cpu_data()->_m))
+ &(_cpu_data()->_m), \
+ sizeof(((cpu_data_t *)0)->_m))
#define flush_cpu_data_by_index(_ix, _m) \
flush_dcache_range((uintptr_t) \
&(_cpu_data_by_index(_ix)->_m), \
- sizeof(_cpu_data_by_index(_ix)->_m))
+ sizeof(((cpu_data_t *)0)->_m))
#endif /* __ASSEMBLY__ */
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index 28228c4..96dee1a 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -168,7 +168,7 @@
* This IMAGE_EL macro must not to be used outside the library, and it is only
* used in AArch64.
*/
-#if IMAGE_BL1 || IMAGE_BL31
+#if defined(IMAGE_BL1) || defined(IMAGE_BL31)
# define IMAGE_EL 3
# define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME
#else
diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h
index 93828c9..7a4594c 100644
--- a/include/plat/arm/board/common/board_arm_def.h
+++ b/include/plat/arm/board/common/board_arm_def.h
@@ -53,7 +53,7 @@
* enable dynamic memory mapping.
*/
#if defined(IMAGE_BL31) || defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES 6
+# define PLAT_ARM_MMAP_ENTRIES 7
# define MAX_XLAT_TABLES 5
#else
# define PLAT_ARM_MMAP_ENTRIES 11
diff --git a/include/plat/arm/common/arm_common.ld.S b/include/plat/arm/common/arm_common.ld.S
new file mode 100644
index 0000000..478b08c
--- /dev/null
+++ b/include/plat/arm/common/arm_common.ld.S
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __ARM_COMMON_LD_S__
+#define __ARM_COMMON_LD_S__
+
+MEMORY {
+ EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE
+}
+
+SECTIONS
+{
+ . = ARM_EL3_TZC_DRAM1_BASE;
+ ASSERT(. == ALIGN(4096),
+ "ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
+ el3_tzc_dram (NOLOAD) : ALIGN(4096) {
+ __EL3_SEC_DRAM_START__ = .;
+ *(arm_el3_tzc_dram)
+ __EL3_SEC_DRAM_UNALIGNED_END__ = .;
+
+ . = NEXT(4096);
+ __EL3_SEC_DRAM_END__ = .;
+ } >EL3_SEC_DRAM
+}
+
+#endif /* __ARM_COMMON_LD_S__ */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index c84fabd..6cab91f 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -77,11 +77,23 @@
#define ARM_SCP_TZC_DRAM1_END (ARM_SCP_TZC_DRAM1_BASE + \
ARM_SCP_TZC_DRAM1_SIZE - 1)
+/*
+ * Define a 2MB region within the TZC secured DRAM for use by EL3 runtime
+ * firmware. This region is meant to be NOLOAD and will not be zero
+ * initialized. Data sections with the attribute `arm_el3_tzc_dram` will be
+ * placed here.
+ */
+#define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - ARM_EL3_TZC_DRAM1_SIZE)
+#define ARM_EL3_TZC_DRAM1_SIZE ULL(0x00200000) /* 2 MB */
+#define ARM_EL3_TZC_DRAM1_END (ARM_EL3_TZC_DRAM1_BASE + \
+ ARM_EL3_TZC_DRAM1_SIZE - 1)
+
#define ARM_AP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - \
ARM_TZC_DRAM1_SIZE)
#define ARM_AP_TZC_DRAM1_SIZE (ARM_TZC_DRAM1_SIZE - \
- ARM_SCP_TZC_DRAM1_SIZE)
+ (ARM_SCP_TZC_DRAM1_SIZE + \
+ ARM_EL3_TZC_DRAM1_SIZE))
#define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \
ARM_AP_TZC_DRAM1_SIZE - 1)
@@ -224,6 +236,11 @@
MT_MEMORY | MT_RW | MT_SECURE)
#endif
+#define ARM_MAP_EL3_TZC_DRAM MAP_REGION_FLAT( \
+ ARM_EL3_TZC_DRAM1_BASE, \
+ ARM_EL3_TZC_DRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
/*
* The number of regions like RO(code), coherent and data required by
* different BL stages which need to be mapped in the MMU.
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 4e589c0..33d951c 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -120,6 +120,7 @@
int arm_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state);
int arm_validate_ns_entrypoint(uintptr_t entrypoint);
+void arm_system_pwr_domain_save(void);
void arm_system_pwr_domain_resume(void);
void arm_program_trusted_mailbox(uintptr_t address);
int arm_psci_read_mem_protect(int *val);
@@ -183,6 +184,8 @@
void plat_arm_gic_redistif_on(void);
void plat_arm_gic_redistif_off(void);
void plat_arm_gic_pcpu_init(void);
+void plat_arm_gic_save(void);
+void plat_arm_gic_resume(void);
void plat_arm_security_setup(void);
void plat_arm_pwrc_setup(void);
void plat_arm_interconnect_init(void);
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index e59a64b..7531f6d 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -291,7 +291,7 @@
# Create generators for object directory structure
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},))
+$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 7015ac0..57cc3d5 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -109,6 +109,7 @@
#ifdef IMAGE_BL31
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
+ ARM_MAP_EL3_TZC_DRAM,
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index dad3a79..faeb1b7 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -9,6 +9,7 @@
#include <assert.h>
#include <debug.h>
#include <errno.h>
+#include <gicv3.h>
#include <mmio.h>
#include <plat_arm.h>
#include <platform.h>
@@ -36,6 +37,9 @@
/* State-id - 0x22 */
arm_make_pwrstate_lvl1(ARM_LOCAL_STATE_OFF, ARM_LOCAL_STATE_OFF,
ARM_PWR_LVL1, PSTATE_TYPE_POWERDOWN),
+ /* State-id - 0x222 */
+ arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_OFF, ARM_LOCAL_STATE_OFF,
+ ARM_LOCAL_STATE_OFF, ARM_PWR_LVL2, PSTATE_TYPE_POWERDOWN),
0,
};
#endif
@@ -63,6 +67,18 @@
fvp_pwrc_write_pcoffr(mpidr);
}
+/*
+ * Empty implementation of these hooks avoid setting the GICR_WAKER.Sleep bit
+ * on ARM GICv3 implementations on FVP. This is required, because FVP does not
+ * support SYSTEM_SUSPEND and it is `faked` in firmware. Hence, for wake up
+ * from `fake` system suspend the GIC must not be powered off.
+ */
+void arm_gicv3_distif_pre_save(unsigned int proc_num)
+{}
+
+void arm_gicv3_distif_post_restore(unsigned int proc_num)
+{}
+
static void fvp_power_domain_on_finish_common(const psci_power_state_t *target_state)
{
unsigned long mpidr;
@@ -90,6 +106,10 @@
/* Enable coherency if this cluster was off */
fvp_interconnect_enable();
}
+ /* Perform the common system specific operations */
+ if (target_state->pwr_domain_state[ARM_PWR_LVL2] ==
+ ARM_LOCAL_STATE_OFF)
+ arm_system_pwr_domain_resume();
/*
* Clear PWKUPR.WEN bit to ensure interrupts do not interfere
@@ -201,13 +221,18 @@
* register context.
*/
- /* Program the power controller to power off this cpu. */
- fvp_pwrc_write_ppoffr(read_mpidr_el1());
-
/* Perform the common cluster specific operations */
if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
ARM_LOCAL_STATE_OFF)
fvp_cluster_pwrdwn_common();
+
+ /* Perform the common system specific operations */
+ if (target_state->pwr_domain_state[ARM_PWR_LVL2] ==
+ ARM_LOCAL_STATE_OFF)
+ arm_system_pwr_domain_save();
+
+ /* Program the power controller to power off this cpu. */
+ fvp_pwrc_write_ppoffr(read_mpidr_el1());
}
/*******************************************************************************
@@ -309,7 +334,57 @@
return ret;
}
+/*
+ * The FVP doesn't truly support power management at SYSTEM power domain. The
+ * SYSTEM_SUSPEND will be down-graded to the cluster level within the platform
+ * layer. The `fake` SYSTEM_SUSPEND allows us to validate some of the driver
+ * save and restore sequences on FVP.
+ */
+void fvp_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ unsigned int i;
+
+ for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++)
+ req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF;
+}
+
/*******************************************************************************
+ * Handler to filter PSCI requests.
+ ******************************************************************************/
+/*
+ * The system power domain suspend is only supported only via
+ * PSCI SYSTEM_SUSPEND API. PSCI CPU_SUSPEND request to system power domain
+ * will be downgraded to the lower level.
+ */
+static int fvp_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ int rc;
+ rc = arm_validate_power_state(power_state, req_state);
+
+ /*
+ * Ensure that the system power domain level is never suspended
+ * via PSCI CPU SUSPEND API. Currently system suspend is only
+ * supported via PSCI SYSTEM SUSPEND API.
+ */
+ req_state->pwr_domain_state[ARM_PWR_LVL2] = ARM_LOCAL_STATE_RUN;
+ return rc;
+}
+
+/*
+ * Custom `translate_power_state_by_mpidr` handler for FVP. Unlike in the
+ * `fvp_validate_power_state`, we do not downgrade the system power
+ * domain level request in `power_state` as it will be used to query the
+ * PSCI_STAT_COUNT/RESIDENCY at the system power domain level.
+ */
+static int fvp_translate_power_state_by_mpidr(u_register_t mpidr,
+ unsigned int power_state,
+ psci_power_state_t *output_state)
+{
+ return arm_validate_power_state(power_state, output_state);
+}
+
+/*******************************************************************************
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
* platform layer will take care of registering the handlers with PSCI.
******************************************************************************/
@@ -322,9 +397,11 @@
.pwr_domain_suspend_finish = fvp_pwr_domain_suspend_finish,
.system_off = fvp_system_off,
.system_reset = fvp_system_reset,
- .validate_power_state = arm_validate_power_state,
+ .validate_power_state = fvp_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint,
+ .translate_power_state_by_mpidr = fvp_translate_power_state_by_mpidr,
.get_node_hw_state = fvp_node_hw_state,
+ .get_sys_suspend_power_state = fvp_get_sys_suspend_power_state,
/*
* mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
* as that would require mapping in all of NS DRAM into BL31 or BL32.
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index cf1492b..4a007f4 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -12,7 +12,7 @@
#include "drivers/pwrc/fvp_pwrc.h"
/* The FVP power domain tree descriptor */
-unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 1];
+unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2];
CASSERT(FVP_CLUSTER_COUNT && FVP_CLUSTER_COUNT <= 256, assert_invalid_fvp_cluster_count);
@@ -23,18 +23,18 @@
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
- int i;
+ unsigned int i;
/*
- * The FVP power domain tree does not have a single system level power domain
- * i.e. a single root node. The first entry in the power domain descriptor
- * specifies the number of power domains at the highest power level. For the FVP
- * this is the number of cluster power domains.
+ * The highest level is the system level. The next level is constituted
+ * by clusters and then cores in clusters.
*/
- fvp_power_domain_tree_desc[0] = FVP_CLUSTER_COUNT;
+ fvp_power_domain_tree_desc[0] = 1;
+ fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT;
for (i = 0; i < FVP_CLUSTER_COUNT; i++)
- fvp_power_domain_tree_desc[i + 1] = FVP_MAX_CPUS_PER_CLUSTER;
+ fvp_power_domain_tree_desc[i + 2] = FVP_MAX_CPUS_PER_CLUSTER;
+
return fvp_power_domain_tree_desc;
}
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
new file mode 100644
index 0000000..24c3deb
--- /dev/null
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __PLAT_LD_S__
+#define __PLAT_LD_S__
+
+#include <arm_common.ld.S>
+
+#endif /* __PLAT_LD_S__ */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index e953580..310db7b 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -20,9 +20,9 @@
(FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU)
#define PLAT_NUM_PWR_DOMAINS (FVP_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT)
+ PLATFORM_CORE_COUNT) + 1
-#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
/*
* Other platform porting definitions are provided by included headers
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 29da12e..1b50296 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -155,5 +155,8 @@
NEED_BL32 := yes
endif
+# Add support for platform supplied linker script for BL31 build
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
include plat/arm/board/common/board_common.mk
include plat/arm/common/arm_common.mk
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index e1484d7..44eb43f 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -26,14 +26,17 @@
endif
# Process flags
- $(eval $(call add_define,ARM_TSP_RAM_LOCATION_ID))
-
# Process ARM_BL31_IN_DRAM flag
ARM_BL31_IN_DRAM := 0
$(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
$(eval $(call add_define,ARM_BL31_IN_DRAM))
+else
+ ARM_TSP_RAM_LOCATION_ID = ARM_TRUSTED_SRAM_ID
endif
+$(eval $(call add_define,ARM_TSP_RAM_LOCATION_ID))
+
+
# For the original power-state parameter format, the State-ID can be encoded
# according to the recommended encoding or zero. This flag determines which
# State-ID encoding to be parsed.
diff --git a/plat/arm/common/arm_gicv2.c b/plat/arm/common/arm_gicv2.c
index aac0248..b081fa8 100644
--- a/plat/arm/common/arm_gicv2.c
+++ b/plat/arm/common/arm_gicv2.c
@@ -92,3 +92,21 @@
{
return;
}
+
+
+/******************************************************************************
+ * ARM common helper to save & restore the GICv3 on resume from system suspend.
+ * The normal world currently takes care of saving and restoring the GICv2
+ * registers due to legacy reasons. Hence we just initialize the Distributor
+ * on resume from system suspend.
+ *****************************************************************************/
+void plat_arm_gic_save(void)
+{
+ return;
+}
+
+void plat_arm_gic_resume(void)
+{
+ gicv2_distif_init();
+ gicv2_pcpu_distif_init();
+}
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index cec6a9d..e273b77 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -32,6 +32,13 @@
};
/*
+ * We save and restore the GICv3 context on system suspend. Allocate the
+ * data in the designated EL3 Secure carve-out memory
+ */
+gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
+gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
+
+/*
* MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
* to core position.
*
@@ -121,3 +128,58 @@
{
gicv3_rdistif_off(plat_my_core_pos());
}
+
+/******************************************************************************
+ * ARM common helper to save & restore the GICv3 on resume from system suspend
+ *****************************************************************************/
+void plat_arm_gic_save(void)
+{
+
+ /*
+ * If an ITS is available, save its context before
+ * the Redistributor using:
+ * gicv3_its_save_disable(gits_base, &its_ctx[i])
+ * Additionnaly, an implementation-defined sequence may
+ * be required to save the whole ITS state.
+ */
+
+ /*
+ * Save the GIC Redistributors and ITS contexts before the
+ * Distributor context. As we only handle SYSTEM SUSPEND API,
+ * we only need to save the context of the CPU that is issuing
+ * the SYSTEM SUSPEND call, i.e. the current CPU.
+ */
+ gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
+
+ /* Save the GIC Distributor context */
+ gicv3_distif_save(&dist_ctx);
+
+ /*
+ * From here, all the components of the GIC can be safely powered down
+ * as long as there is an alternate way to handle wakeup interrupt
+ * sources.
+ */
+}
+
+void plat_arm_gic_resume(void)
+{
+ /* Restore the GIC Distributor context */
+ gicv3_distif_init_restore(&dist_ctx);
+
+ /*
+ * Restore the GIC Redistributor and ITS contexts after the
+ * Distributor context. As we only handle SYSTEM SUSPEND API,
+ * we only need to restore the context of the CPU that issued
+ * the SYSTEM SUSPEND call.
+ */
+ gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
+
+ /*
+ * If an ITS is available, restore its context after
+ * the Redistributor using:
+ * gicv3_its_restore(gits_base, &its_ctx[i])
+ * An implementation-defined sequence may be required to
+ * restore the whole ITS state. The ITS must also be
+ * re-enabled after this sequence has been executed.
+ */
+}
diff --git a/plat/arm/common/arm_gicv3_legacy.c b/plat/arm/common/arm_gicv3_legacy.c
index a014a8e..e19799a 100644
--- a/plat/arm/common/arm_gicv3_legacy.c
+++ b/plat/arm/common/arm_gicv3_legacy.c
@@ -84,3 +84,16 @@
{
return;
}
+
+/******************************************************************************
+ * ARM common helper to save & restore the GICv3 on resume from system suspend.
+ *****************************************************************************/
+void plat_arm_gic_save(void)
+{
+ return;
+}
+
+void plat_arm_gic_resume(void)
+{
+ arm_gic_setup();
+}
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index cc131a9..5e7e047 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -11,6 +11,7 @@
#include <console.h>
#include <errno.h>
#include <plat_arm.h>
+#include <platform.h>
#include <platform_def.h>
#include <psci.h>
@@ -140,6 +141,24 @@
}
/******************************************************************************
+ * Helper function to save the platform state before a system suspend. Save the
+ * state of the system components which are not in the Always ON power domain.
+ *****************************************************************************/
+void arm_system_pwr_domain_save(void)
+{
+ /* Assert system power domain is available on the platform */
+ assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
+
+ plat_arm_gic_save();
+
+ /*
+ * All the other peripheral which are configured by ARM TF are
+ * re-initialized on resume from system suspend. Hence we
+ * don't save their state here.
+ */
+}
+
+/******************************************************************************
* Helper function to resume the platform from system suspend. Reinitialize
* the system components which are not in the Always ON power domain.
* TODO: Unify the platform setup when waking up from cold boot and system
@@ -153,12 +172,8 @@
/* Assert system power domain is available on the platform */
assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
- /*
- * TODO: On GICv3 systems, figure out whether the core that wakes up
- * first from system suspend need to initialize the re-distributor
- * interface of all the other suspended cores.
- */
- plat_arm_gic_init();
+ plat_arm_gic_resume();
+
plat_arm_security_setup();
arm_configure_sys_timer();
}
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 1d61c57..e19ca67 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -40,7 +40,7 @@
/* Region 1 set to cover Secure part of DRAM */
tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 1,
- ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END,
+ ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,
TZC_REGION_S_RDWR,
0);
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index 21ca4e8..8e41391 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -33,7 +33,7 @@
/* Region 1 set to cover Secure part of DRAM */
tzc_dmc500_configure_region(1, ARM_AP_TZC_DRAM1_BASE,
- ARM_AP_TZC_DRAM1_END,
+ ARM_EL3_TZC_DRAM1_END,
TZC_REGION_S_RDWR,
0);
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 39c02af..4104dd7 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -74,6 +74,9 @@
{
assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
+ /* Enable the gic cpu interface */
+ plat_arm_gic_cpuif_enable();
+
/*
* Perform the common cluster specific operations i.e enable coherency
* if this cluster was off.
@@ -95,13 +98,10 @@
/* Assert that the system power domain need not be initialized */
assert(CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_RUN);
- css_pwr_domain_on_finisher_common(target_state);
-
/* Program the gic per-cpu distributor or re-distributor interface */
plat_arm_gic_pcpu_init();
- /* Enable the gic cpu interface */
- plat_arm_gic_cpuif_enable();
+ css_pwr_domain_on_finisher_common(target_state);
}
/*******************************************************************************
@@ -144,8 +144,18 @@
if (CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_RET)
return;
+
assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
css_power_down_common(target_state);
+
+ /* Perform system domain state saving if issuing system suspend */
+ if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
+ arm_system_pwr_domain_save();
+
+ /* Power off the Redistributor after having saved its context */
+ plat_arm_gic_redistif_off();
+ }
+
css_scp_suspend(target_state);
}
@@ -165,10 +175,12 @@
/* Perform system domain restore if woken up from system suspend */
if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+ /*
+ * At this point, the Distributor must be powered on to be ready
+ * to have its state restored. The Redistributor will be powered
+ * on as part of gicv3_rdistif_init_restore.
+ */
arm_system_pwr_domain_resume();
- else
- /* Enable the gic cpu interface */
- plat_arm_gic_cpuif_enable();
css_pwr_domain_on_finisher_common(target_state);
}
diff --git a/plat/hisilicon/hikey/aarch64/hikey_common.c b/plat/hisilicon/hikey/aarch64/hikey_common.c
index 02a00ac..d5b63cc 100644
--- a/plat/hisilicon/hikey/aarch64/hikey_common.c
+++ b/plat/hisilicon/hikey/aarch64/hikey_common.c
@@ -59,7 +59,7 @@
* This doesn't include Trusted RAM as the 'mem_layout' argument passed to
* hikey_init_mmu_elx() will give the available subset of that,
*/
-#if IMAGE_BL1
+#ifdef IMAGE_BL1
static const mmap_region_t hikey_mmap[] = {
MAP_DEVICE,
MAP_ROM_PARAM,
@@ -68,7 +68,7 @@
};
#endif
-#if IMAGE_BL2
+#ifdef IMAGE_BL2
static const mmap_region_t hikey_mmap[] = {
MAP_DDR,
MAP_DEVICE,
@@ -82,7 +82,7 @@
};
#endif
-#if IMAGE_BL31
+#ifdef IMAGE_BL31
static const mmap_region_t hikey_mmap[] = {
MAP_DEVICE,
MAP_SRAM,
@@ -91,7 +91,7 @@
};
#endif
-#if IMAGE_BL32
+#ifdef IMAGE_BL32
static const mmap_region_t hikey_mmap[] = {
MAP_DEVICE,
MAP_DDR,
diff --git a/plat/hisilicon/hikey/hikey_io_storage.c b/plat/hisilicon/hikey/hikey_io_storage.c
index 60ec42b..57c66d5 100644
--- a/plat/hisilicon/hikey/hikey_io_storage.c
+++ b/plat/hisilicon/hikey/hikey_io_storage.c
@@ -47,7 +47,7 @@
static const io_block_dev_spec_t emmc_dev_spec = {
/* It's used as temp buffer in block driver. */
-#if IMAGE_BL1
+#ifdef IMAGE_BL1
.buffer = {
.offset = HIKEY_BL1_MMC_DATA_BASE,
.length = HIKEY_BL1_MMC_DATA_SIZE,
diff --git a/plat/hisilicon/hikey/include/platform_def.h b/plat/hisilicon/hikey/include/platform_def.h
index 0180654..f4a3fd4 100644
--- a/plat/hisilicon/hikey/include/platform_def.h
+++ b/plat/hisilicon/hikey/include/platform_def.h
@@ -151,15 +151,15 @@
*/
#define ADDR_SPACE_SIZE (1ull << 32)
-#if IMAGE_BL1 || IMAGE_BL32
+#if defined(IMAGE_BL1) || defined(IMAGE_BL32)
#define MAX_XLAT_TABLES 3
#endif
-#if IMAGE_BL31
+#ifdef IMAGE_BL31
#define MAX_XLAT_TABLES 4
#endif
-#if IMAGE_BL2
+#ifdef IMAGE_BL2
#if LOAD_IMAGE_V2
#ifdef SPD_opteed
#define MAX_XLAT_TABLES 4
diff --git a/plat/hisilicon/hikey960/aarch64/hikey960_common.c b/plat/hisilicon/hikey960/aarch64/hikey960_common.c
index bce0c96..b1020a6 100644
--- a/plat/hisilicon/hikey960/aarch64/hikey960_common.c
+++ b/plat/hisilicon/hikey960/aarch64/hikey960_common.c
@@ -55,7 +55,7 @@
* This doesn't include Trusted RAM as the 'mem_layout' argument passed to
* hikey960_init_mmu_elx() will give the available subset of that,
*/
-#if IMAGE_BL1
+#ifdef IMAGE_BL1
static const mmap_region_t hikey960_mmap[] = {
MAP_UFS_DATA,
MAP_BL1_RW,
@@ -65,7 +65,7 @@
};
#endif
-#if IMAGE_BL2
+#ifdef IMAGE_BL2
static const mmap_region_t hikey960_mmap[] = {
MAP_DDR,
MAP_DEVICE,
@@ -79,7 +79,7 @@
};
#endif
-#if IMAGE_BL31
+#ifdef IMAGE_BL31
static const mmap_region_t hikey960_mmap[] = {
MAP_DEVICE,
MAP_TSP_MEM,
@@ -87,7 +87,7 @@
};
#endif
-#if IMAGE_BL32
+#ifdef IMAGE_BL32
static const mmap_region_t hikey960_mmap[] = {
MAP_DEVICE,
MAP_DDR,
diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h
index 202952c..cb76090 100644
--- a/plat/hisilicon/hikey960/include/platform_def.h
+++ b/plat/hisilicon/hikey960/include/platform_def.h
@@ -116,11 +116,11 @@
*/
#define ADDR_SPACE_SIZE (1ull << 32)
-#if IMAGE_BL1 || IMAGE_BL31 || IMAGE_BL32
+#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || defined(IMAGE_BL32)
#define MAX_XLAT_TABLES 3
#endif
-#if IMAGE_BL2
+#ifdef IMAGE_BL2
#if LOAD_IMAGE_V2
#ifdef SPD_opteed
#define MAX_XLAT_TABLES 4
diff --git a/plat/qemu/qemu_bl31_setup.c b/plat/qemu/qemu_bl31_setup.c
index 5bf4589..f79a885 100644
--- a/plat/qemu/qemu_bl31_setup.c
+++ b/plat/qemu/qemu_bl31_setup.c
@@ -7,6 +7,7 @@
#include <assert.h>
#include <bl_common.h>
#include <console.h>
+#include <gic_common.h>
#include <gicv2.h>
#include <platform_def.h>
#include "qemu_private.h"
@@ -112,22 +113,40 @@
BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
}
-static const unsigned int irq_sec_array[] = {
- QEMU_IRQ_SEC_SGI_0,
- QEMU_IRQ_SEC_SGI_1,
- QEMU_IRQ_SEC_SGI_2,
- QEMU_IRQ_SEC_SGI_3,
- QEMU_IRQ_SEC_SGI_4,
- QEMU_IRQ_SEC_SGI_5,
- QEMU_IRQ_SEC_SGI_6,
- QEMU_IRQ_SEC_SGI_7,
+/******************************************************************************
+ * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
+ * interrupts.
+ *****************************************************************************/
+#define PLATFORM_G1S_PROPS(grp) \
+ INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE)
+
+#define PLATFORM_G0_PROPS(grp)
+
+static const interrupt_prop_t qemu_interrupt_props[] = {
+ PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0),
+ PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
};
static const struct gicv2_driver_data plat_gicv2_driver_data = {
.gicd_base = GICD_BASE,
.gicc_base = GICC_BASE,
- .g0_interrupt_num = ARRAY_SIZE(irq_sec_array),
- .g0_interrupt_array = irq_sec_array,
+ .interrupt_props = qemu_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(qemu_interrupt_props),
};
void bl31_platform_setup(void)
diff --git a/plat/rockchip/rk3328/include/platform_def.h b/plat/rockchip/rk3328/include/platform_def.h
index 7304dcf..39d3c21 100644
--- a/plat/rockchip/rk3328/include/platform_def.h
+++ b/plat/rockchip/rk3328/include/platform_def.h
@@ -26,13 +26,13 @@
/* Size of cacheable stacks */
#if DEBUG_XLAT_TABLE
#define PLATFORM_STACK_SIZE 0x800
-#elif IMAGE_BL1
+#elif defined(IMAGE_BL1)
#define PLATFORM_STACK_SIZE 0x440
-#elif IMAGE_BL2
+#elif defined(IMAGE_BL2)
#define PLATFORM_STACK_SIZE 0x400
-#elif IMAGE_BL31
+#elif defined(IMAGE_BL31)
#define PLATFORM_STACK_SIZE 0x800
-#elif IMAGE_BL32
+#elif defined(IMAGE_BL32)
#define PLATFORM_STACK_SIZE 0x440
#endif
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index 85cca1b..6cd5b24 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -88,7 +88,7 @@
${BUILD_PLAT}/bl31/cdn_dp.o: CCACHE_EXTRAFILES=$(HDCPFW)
${RK_PLAT_SOC}/drivers/dp/cdn_dp.c: $(HDCPFW)
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},))
+$(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},${BUILD_PLAT}))
.PHONY: $(RK3399M0FW)
$(RK3399M0FW): | ${BUILD_M0}
$(MAKE) -C ${RK_PLAT_SOC}/drivers/m0 BUILD=$(abspath ${BUILD_PLAT}/m0)
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index e6f510e..c91abb6 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -101,7 +101,7 @@
$(BUILD_PLAT)/bl2/uniphier_rotpk.o: $(ROTPK_HASH)
certificates: $(ROT_KEY)
-$(ROT_KEY):
+$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
$(Q)openssl genrsa 2048 > $@ 2>/dev/null