summaryrefslogtreecommitdiff
path: root/plat/arm
diff options
context:
space:
mode:
authorScott Branden <sbranden@users.noreply.github.com>2017-04-29 08:36:12 -0700
committerGitHub <noreply@github.com>2017-04-29 08:36:12 -0700
commit0f22bef31d402e24fab77eb2a3c643d042b7e79c (patch)
tree6595ed7f87249ccbd4a953ba5cdc00963a130d18 /plat/arm
parent53d9c9c85bc49845c4c40315e1ab29d627a1f8c3 (diff)
parentdd454b40dfe42dbf77e2f04a3965295380b4f78d (diff)
Merge branch 'integration' into tf_issue_461
Diffstat (limited to 'plat/arm')
-rw-r--r--plat/arm/board/common/board_css_common.c3
-rw-r--r--plat/arm/board/juno/aarch32/juno_helpers.S216
-rw-r--r--plat/arm/board/juno/aarch64/juno_helpers.S94
-rw-r--r--plat/arm/board/juno/include/platform_def.h4
-rw-r--r--plat/arm/board/juno/juno_bl1_setup.c18
-rw-r--r--plat/arm/board/juno/juno_bl2_setup.c56
-rw-r--r--plat/arm/board/juno/juno_pm.c93
-rw-r--r--plat/arm/board/juno/platform.mk11
-rw-r--r--plat/arm/board/juno/sp_min/sp_min-juno.mk47
-rw-r--r--plat/arm/common/aarch32/arm_helpers.S20
-rw-r--r--plat/arm/common/aarch64/arm_helpers.S16
-rw-r--r--plat/arm/common/arm_bl1_setup.c3
-rw-r--r--plat/arm/common/arm_bl2_setup.c15
-rw-r--r--plat/arm/common/arm_common.c2
-rw-r--r--plat/arm/common/arm_common.mk27
-rw-r--r--plat/arm/css/common/aarch32/css_helpers.S106
-rw-r--r--plat/arm/css/common/css_common.mk4
-rw-r--r--plat/arm/css/common/css_pm.c50
-rw-r--r--plat/arm/css/drivers/scp/css_pm_scpi.c13
19 files changed, 678 insertions, 120 deletions
diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c
index 3fcc6ee0..6593d2a0 100644
--- a/plat/arm/board/common/board_css_common.c
+++ b/plat/arm/board/common/board_css_common.c
@@ -79,6 +79,9 @@ const mmap_region_t plat_arm_mmap[] = {
#endif
#ifdef IMAGE_BL32
const mmap_region_t plat_arm_mmap[] = {
+#ifdef AARCH32
+ ARM_MAP_SHARED_RAM,
+#endif
V2M_MAP_IOFPGA,
CSS_MAP_DEVICE,
SOC_CSS_MAP_DEVICE,
diff --git a/plat/arm/board/juno/aarch32/juno_helpers.S b/plat/arm/board/juno/aarch32/juno_helpers.S
new file mode 100644
index 00000000..86eeb2c4
--- /dev/null
+++ b/plat/arm/board/juno/aarch32/juno_helpers.S
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a72.h>
+#include <v2m_def.h>
+#include "../juno_def.h"
+
+
+ .globl plat_reset_handler
+ .globl plat_arm_calc_core_pos
+
+#define JUNO_REVISION(rev) REV_JUNO_R##rev
+#define JUNO_HANDLER(rev) plat_reset_handler_juno_r##rev
+#define JUMP_TO_HANDLER_IF_JUNO_R(revision) \
+ jump_to_handler JUNO_REVISION(revision), JUNO_HANDLER(revision)
+
+ /* --------------------------------------------------------------------
+ * Helper macro to jump to the given handler if the board revision
+ * matches.
+ * Expects the Juno board revision in x0.
+ * --------------------------------------------------------------------
+ */
+ .macro jump_to_handler _revision, _handler
+ cmp r0, #\_revision
+ beq \_handler
+ .endm
+
+ /* --------------------------------------------------------------------
+ * Helper macro that reads the part number of the current CPU and jumps
+ * to the given label if it matches the CPU MIDR provided.
+ *
+ * Clobbers r0.
+ * --------------------------------------------------------------------
+ */
+ .macro jump_if_cpu_midr _cpu_midr, _label
+ ldcopr r0, MIDR
+ ubfx r0, r0, #MIDR_PN_SHIFT, #12
+ ldr r1, =((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+ cmp r0, r1
+ beq \_label
+ .endm
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R0.
+ *
+ * Juno R0 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A57 processor cluster.
+ *
+ * This handler does the following:
+ * - Implement workaround for defect id 831273 by enabling an event
+ * stream every 65536 cycles.
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(0)
+ /* --------------------------------------------------------------------
+ * Enable the event stream every 65536 cycles
+ * --------------------------------------------------------------------
+ */
+ mov r0, #(0xf << EVNTI_SHIFT)
+ orr r0, r0, #EVNTEN_BIT
+ stcopr r0, CNTKCTL
+
+ /* --------------------------------------------------------------------
+ * Nothing else to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A53_MIDR, 1f
+
+ /* --------------------------------------------------------------------
+ * Cortex-A57 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov r0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (L2_TAG_RAM_LATENCY_3_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ stcopr r0, L2CTLR
+1:
+ isb
+ bx lr
+endfunc JUNO_HANDLER(0)
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R1.
+ *
+ * Juno R1 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A57 processor cluster.
+ *
+ * This handler does the following:
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ *
+ * Note that:
+ * - The default value for the L2 Tag RAM latency for Cortex-A57 is
+ * suitable.
+ * - Defect #831273 doesn't affect Juno R1.
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(1)
+ /* --------------------------------------------------------------------
+ * Nothing to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A57_MIDR, A57
+ bx lr
+
+A57:
+ /* --------------------------------------------------------------------
+ * Cortex-A57 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov r0, #(L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT)
+ stcopr r0, L2CTLR
+ isb
+ bx lr
+endfunc JUNO_HANDLER(1)
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R2.
+ *
+ * Juno R2 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A72 processor cluster.
+ *
+ * This handler does the following:
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A72
+ * - Set the L2 Tag RAM latency to 1 (i.e. 2 cycles) for Cortex-A72
+ *
+ * Note that:
+ * - Defect #831273 doesn't affect Juno R2.
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(2)
+ /* --------------------------------------------------------------------
+ * Nothing to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A72_MIDR, A72
+ bx lr
+
+A72:
+ /* --------------------------------------------------------------------
+ * Cortex-A72 specific settings
+ * --------------------------------------------------------------------
+ */
+ mov r0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (L2_TAG_RAM_LATENCY_2_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ stcopr r0, L2CTLR
+ isb
+ bx lr
+endfunc JUNO_HANDLER(2)
+
+ /* --------------------------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the Juno board revision and call the appropriate reset
+ * handler.
+ * --------------------------------------------------------------------
+ */
+func plat_reset_handler
+ /* Read the V2M SYS_ID register */
+ ldr r0, =(V2M_SYSREGS_BASE + V2M_SYS_ID)
+ ldr r1, [r0]
+ /* Extract board revision from the SYS_ID */
+ ubfx r0, r1, #V2M_SYS_ID_REV_SHIFT, #4
+
+ JUMP_TO_HANDLER_IF_JUNO_R(0)
+ JUMP_TO_HANDLER_IF_JUNO_R(1)
+ JUMP_TO_HANDLER_IF_JUNO_R(2)
+
+ /* Board revision is not supported */
+ no_ret plat_panic_handler
+
+endfunc plat_reset_handler
+
+ /* -----------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ * Helper function to calculate the core position.
+ * -----------------------------------------------------
+ */
+func plat_arm_calc_core_pos
+ b css_calc_core_pos_swap_cluster
+endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/juno/aarch64/juno_helpers.S b/plat/arm/board/juno/aarch64/juno_helpers.S
index ac54ac9b..49fef16f 100644
--- a/plat/arm/board/juno/aarch64/juno_helpers.S
+++ b/plat/arm/board/juno/aarch64/juno_helpers.S
@@ -34,12 +34,18 @@
#include <cortex_a53.h>
#include <cortex_a57.h>
#include <cortex_a72.h>
+#include <cpu_macros.S>
+#include <css_def.h>
#include <v2m_def.h>
#include "../juno_def.h"
.globl plat_reset_handler
.globl plat_arm_calc_core_pos
+#if JUNO_AARCH32_EL3_RUNTIME
+ .globl plat_get_my_entrypoint
+ .globl juno_reset_to_aarch32_state
+#endif
#define JUNO_REVISION(rev) REV_JUNO_R##rev
#define JUNO_HANDLER(rev) plat_reset_handler_juno_r##rev
@@ -206,6 +212,20 @@ func plat_reset_handler
endfunc plat_reset_handler
/* -----------------------------------------------------
+ * void juno_do_reset_to_aarch32_state(void);
+ *
+ * Request warm reset to AArch32 mode.
+ * -----------------------------------------------------
+ */
+func juno_do_reset_to_aarch32_state
+ mov x0, #RMR_EL3_RR_BIT
+ dsb sy
+ msr rmr_el3, x0
+ isb
+ wfi
+endfunc juno_do_reset_to_aarch32_state
+
+ /* -----------------------------------------------------
* unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
* Helper function to calculate the core position.
* -----------------------------------------------------
@@ -213,3 +233,77 @@ endfunc plat_reset_handler
func plat_arm_calc_core_pos
b css_calc_core_pos_swap_cluster
endfunc plat_arm_calc_core_pos
+
+#if JUNO_AARCH32_EL3_RUNTIME
+ /* ---------------------------------------------------------------------
+ * uintptr_t plat_get_my_entrypoint (void);
+ *
+ * Main job of this routine is to distinguish between a cold and a warm
+ * boot. On JUNO platform, this distinction is based on the contents of
+ * the Trusted Mailbox. It is initialised to zero by the SCP before the
+ * AP cores are released from reset. Therefore, a zero mailbox means
+ * it's a cold reset. If it is a warm boot then a request to reset to
+ * AArch32 state is issued. This is the only way to reset to AArch32
+ * in EL3 on Juno. A trampoline located at the high vector address
+ * has already been prepared by BL1.
+ *
+ * This functions returns the contents of the mailbox, i.e.:
+ * - 0 for a cold boot;
+ * - request warm reset in AArch32 state for warm boot case;
+ * ---------------------------------------------------------------------
+ */
+func plat_get_my_entrypoint
+ mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
+ ldr x0, [x0]
+ cbz x0, return
+ b juno_do_reset_to_aarch32_state
+1:
+ b 1b
+return:
+ ret
+endfunc plat_get_my_entrypoint
+
+/*
+ * Emit a "movw r0, #imm16" which moves the lower
+ * 16 bits of `_val` into r0.
+ */
+.macro emit_movw _reg_d, _val
+ mov_imm \_reg_d, (0xe3000000 | \
+ ((\_val & 0xfff) | \
+ ((\_val & 0xf000) << 4)))
+.endm
+
+/*
+ * Emit a "movt r0, #imm16" which moves the upper
+ * 16 bits of `_val` into r0.
+ */
+.macro emit_movt _reg_d, _val
+ mov_imm \_reg_d, (0xe3400000 | \
+ (((\_val & 0x0fff0000) >> 16) | \
+ ((\_val & 0xf0000000) >> 12)))
+.endm
+
+/*
+ * This function writes the trampoline code at HI-VEC (0xFFFF0000)
+ * address which loads r0 with the entrypoint address for
+ * BL32 (a.k.a SP_MIN) when EL3 is in AArch32 mode. A warm reset
+ * to AArch32 mode is then requested by writing into RMR_EL3.
+ */
+func juno_reset_to_aarch32_state
+ emit_movw w0, BL32_BASE
+ emit_movt w1, BL32_BASE
+ /* opcode "bx r0" to branch using r0 in AArch32 mode */
+ mov_imm w2, 0xe12fff10
+
+ /* Write the above opcodes at HI-VECTOR location */
+ mov_imm x3, HI_VECTOR_BASE
+ str w0, [x3], #4
+ str w1, [x3], #4
+ str w2, [x3]
+
+ bl juno_do_reset_to_aarch32_state
+1:
+ b 1b
+endfunc juno_reset_to_aarch32_state
+
+#endif /* JUNO_AARCH32_EL3_RUNTIME */
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index f89f7b46..4da8ab06 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -103,8 +103,8 @@
#endif
#ifdef IMAGE_BL32
-# define PLAT_ARM_MMAP_ENTRIES 4
-# define MAX_XLAT_TABLES 3
+# define PLAT_ARM_MMAP_ENTRIES 5
+# define MAX_XLAT_TABLES 4
#endif
/*
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index e805c9a3..93ca1c31 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, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -32,11 +32,15 @@
#include <errno.h>
#include <platform.h>
#include <plat_arm.h>
+#include <sp805.h>
#include <tbbr_img_def.h>
#include <v2m_def.h>
#define RESET_REASON_WDOG_RESET (0x2)
+void juno_reset_to_aarch32_state(void);
+
+
/*******************************************************************************
* The following function checks if Firmware update is needed,
* by checking if TOC in FIP image is valid or watchdog reset happened.
@@ -85,3 +89,15 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
while (1)
wfi();
}
+
+#if JUNO_AARCH32_EL3_RUNTIME
+void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
+{
+#if !ARM_DISABLE_TRUSTED_WDOG
+ /* Disable watchdog before leaving BL1 */
+ sp805_stop(ARM_SP805_TWDG_BASE);
+#endif
+
+ juno_reset_to_aarch32_state();
+}
+#endif /* JUNO_AARCH32_EL3_RUNTIME */
diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c
new file mode 100644
index 00000000..ffb6387e
--- /dev/null
+++ b/plat/arm/board/juno/juno_bl2_setup.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include <plat_arm.h>
+
+#if JUNO_AARCH32_EL3_RUNTIME
+/*******************************************************************************
+ * This function changes the spsr for BL32 image to bypass
+ * the check in BL1 AArch64 exception handler. This is needed in the aarch32
+ * boot flow as the core comes up in aarch64 and to enter the BL32 image a warm
+ * reset in aarch32 state is required.
+ ******************************************************************************/
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ int err = arm_bl2_handle_post_image_load(image_id);
+
+ if (!err && (image_id == BL32_IMAGE_ID)) {
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+ assert(bl_mem_params);
+ bl_mem_params->ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
+ }
+
+ return err;
+}
+#endif /* JUNO_AARCH32_EL3_RUNTIME */
diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c
deleted file mode 100644
index c0fa628e..00000000
--- a/plat/arm/board/juno/juno_pm.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of ARM nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#include <css_pm.h>
-#include <plat_arm.h>
-
-/*
- * Custom `validate_power_state` handler for Juno. According to PSCI
- * Specification, interrupts targeted to cores in PSCI CPU SUSPEND should
- * be able to resume it. On Juno, when the system power domain is suspended,
- * the GIC is also powered down. The SCP resumes the final core to be suspend
- * when an external wake-up event is received. But the other cores cannot be
- * woken up by a targeted interrupt, because GIC doesn't forward these
- * interrupts to the SCP. Due to this hardware limitation, we down-grade PSCI
- * CPU SUSPEND requests targeted to the system power domain level
- * to cluster power domain level.
- *
- * The system power domain suspend on Juno is only supported only via
- * PSCI SYSTEM SUSPEND API.
- */
-static int juno_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 Juno. Unlike in the
- * `juno_validate_power_state`, we do not down-grade 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 juno_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 will take care of registering the handlers with PSCI.
- ******************************************************************************/
-plat_psci_ops_t plat_arm_psci_pm_ops = {
- .pwr_domain_on = css_pwr_domain_on,
- .pwr_domain_on_finish = css_pwr_domain_on_finish,
- .pwr_domain_off = css_pwr_domain_off,
- .cpu_standby = css_cpu_standby,
- .pwr_domain_suspend = css_pwr_domain_suspend,
- .pwr_domain_suspend_finish = css_pwr_domain_suspend_finish,
- .system_off = css_system_off,
- .system_reset = css_system_reset,
- .validate_power_state = juno_validate_power_state,
- .validate_ns_entrypoint = arm_validate_ns_entrypoint,
- .get_sys_suspend_power_state = css_get_sys_suspend_power_state,
- .translate_power_state_by_mpidr = juno_translate_power_state_by_mpidr,
- .get_node_hw_state = css_node_hw_state
-};
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 39977240..e29f8c86 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -48,8 +48,14 @@ endif
PLAT_INCLUDES := -Iplat/arm/board/juno/include
-PLAT_BL_COMMON_SOURCES := plat/arm/board/juno/aarch64/juno_helpers.S
+PLAT_BL_COMMON_SOURCES := plat/arm/board/juno/${ARCH}/juno_helpers.S
+# Flag to enable support for AArch32 state on JUNO
+JUNO_AARCH32_EL3_RUNTIME := 0
+$(eval $(call assert_boolean,JUNO_AARCH32_EL3_RUNTIME))
+$(eval $(call add_define,JUNO_AARCH32_EL3_RUNTIME))
+
+ifeq (${ARCH},aarch64)
BL1_SOURCES += lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
lib/cpus/aarch64/cortex_a72.S \
@@ -59,6 +65,7 @@ BL1_SOURCES += lib/cpus/aarch64/cortex_a53.S \
${JUNO_SECURITY_SOURCES}
BL2_SOURCES += plat/arm/board/juno/juno_err.c \
+ plat/arm/board/juno/juno_bl2_setup.c \
${JUNO_SECURITY_SOURCES}
BL2U_SOURCES += ${JUNO_SECURITY_SOURCES}
@@ -66,11 +73,11 @@ BL2U_SOURCES += ${JUNO_SECURITY_SOURCES}
BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
lib/cpus/aarch64/cortex_a72.S \
- plat/arm/board/juno/juno_pm.c \
plat/arm/board/juno/juno_topology.c \
${JUNO_GIC_SOURCES} \
${JUNO_INTERCONNECT_SOURCES} \
${JUNO_SECURITY_SOURCES}
+endif
# Enable workarounds for selected Cortex-A53 and A57 errata.
ERRATA_A53_855873 := 1
diff --git a/plat/arm/board/juno/sp_min/sp_min-juno.mk b/plat/arm/board/juno/sp_min/sp_min-juno.mk
new file mode 100644
index 00000000..fb3c55e7
--- /dev/null
+++ b/plat/arm/board/juno/sp_min/sp_min-juno.mk
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# SP_MIN source files specific to JUNO platform
+BL32_SOURCES += lib/cpus/aarch32/cortex_a53.S \
+ lib/cpus/aarch32/cortex_a57.S \
+ lib/cpus/aarch32/cortex_a72.S \
+ plat/arm/board/juno/juno_pm.c \
+ plat/arm/board/juno/juno_topology.c \
+ plat/arm/css/common/css_pm.c \
+ plat/arm/css/common/css_topology.c \
+ plat/arm/soc/common/soc_css_security.c \
+ plat/arm/css/drivers/scp/css_pm_scpi.c \
+ plat/arm/css/drivers/scpi/css_mhu.c \
+ plat/arm/css/drivers/scpi/css_scpi.c \
+ ${JUNO_GIC_SOURCES} \
+ ${JUNO_INTERCONNECT_SOURCES} \
+ ${JUNO_SECURITY_SOURCES}
+
+include plat/arm/common/sp_min/arm_sp_min.mk
diff --git a/plat/arm/common/aarch32/arm_helpers.S b/plat/arm/common/aarch32/arm_helpers.S
index 5d238ecb..51e5ee9a 100644
--- a/plat/arm/common/aarch32/arm_helpers.S
+++ b/plat/arm/common/aarch32/arm_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -31,9 +31,10 @@
#include <platform_def.h>
.weak plat_arm_calc_core_pos
- .weak plat_crash_console_init
- .weak plat_crash_console_putc
.weak plat_my_core_pos
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
/* -----------------------------------------------------
* unsigned int plat_my_core_pos(void)
@@ -85,3 +86,16 @@ func plat_crash_console_putc
ldr r1, =PLAT_ARM_CRASH_UART_BASE
b console_core_putc
endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0 - r1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ ldr r1, =PLAT_ARM_CRASH_UART_BASE
+ b console_core_flush
+endfunc plat_crash_console_flush
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index d782020a..60ff834a 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -34,6 +34,7 @@
.weak plat_my_core_pos
.globl plat_crash_console_init
.globl plat_crash_console_putc
+ .globl plat_crash_console_flush
.globl platform_mem_init
@@ -88,6 +89,19 @@ func plat_crash_console_putc
b console_core_putc
endfunc plat_crash_console_putc
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0 - r1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x1, PLAT_ARM_CRASH_UART_BASE
+ b console_core_flush
+endfunc plat_crash_console_flush
+
/* ---------------------------------------------------------------------
* We don't need to carry out any memory initialization on ARM
* platforms. The Secure RAM is accessible straight away.
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 8c1fde43..c588f965 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -30,13 +30,13 @@
#include <arch.h>
#include <arm_def.h>
+#include <arm_xlat_tables.h>
#include <bl_common.h>
#include <console.h>
#include <platform_def.h>
#include <plat_arm.h>
#include <sp805.h>
#include <utils.h>
-#include <xlat_tables_v2.h>
#include "../../../bl1/bl1_private.h"
/* Weak definitions may be overridden in specific ARM standard platform */
@@ -44,6 +44,7 @@
#pragma weak bl1_plat_arch_setup
#pragma weak bl1_platform_setup
#pragma weak bl1_plat_sec_mem_layout
+#pragma weak bl1_plat_prepare_exit
/* Data structure which holds the extents of the trusted SRAM for BL1*/
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 007108d1..66e350aa 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -249,11 +249,7 @@ void bl2_plat_arch_setup(void)
}
#if LOAD_IMAGE_V2
-/*******************************************************************************
- * This function can be used by the platforms to update/use image
- * information for given `image_id`.
- ******************************************************************************/
-int bl2_plat_handle_post_image_load(unsigned int image_id)
+int arm_bl2_handle_post_image_load(unsigned int image_id)
{
int err = 0;
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
@@ -286,6 +282,15 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
return err;
}
+/*******************************************************************************
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ ******************************************************************************/
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ return arm_bl2_handle_post_image_load(image_id);
+}
+
#else /* LOAD_IMAGE_V2 */
/*******************************************************************************
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index aade2212..3d67ef76 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -29,12 +29,12 @@
*/
#include <arch.h>
#include <arch_helpers.h>
+#include <arm_xlat_tables.h>
#include <assert.h>
#include <debug.h>
#include <mmio.h>
#include <plat_arm.h>
#include <platform_def.h>
-#include <xlat_tables_v2.h>
extern const mmap_region_t plat_arm_mmap[];
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 891e2fbd..9cf2b7e0 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -95,6 +95,11 @@ ARM_PLAT_MT := 0
$(eval $(call assert_boolean,ARM_PLAT_MT))
$(eval $(call add_define,ARM_PLAT_MT))
+# Use translation tables library v2 by default
+ARM_XLAT_TABLES_LIB_V1 := 0
+$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
+$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
+
# Enable PSCI_STAT_COUNT/RESIDENCY APIs on ARM platforms
ENABLE_PSCI_STAT := 1
ENABLE_PMF := 1
@@ -113,11 +118,17 @@ ifeq (${ARCH}, aarch64)
PLAT_INCLUDES += -Iinclude/plat/arm/common/aarch64
endif
+PLAT_BL_COMMON_SOURCES += plat/arm/common/${ARCH}/arm_helpers.S \
+ plat/arm/common/arm_common.c
+
+ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
+PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
+ lib/xlat_tables/${ARCH}/xlat_tables.c
+else
include lib/xlat_tables_v2/xlat_tables.mk
-PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \
- plat/arm/common/${ARCH}/arm_helpers.S \
- plat/arm/common/arm_common.c
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+endif
BL1_SOURCES += drivers/arm/sp805/sp805.c \
drivers/io/io_fip.c \
@@ -137,8 +148,14 @@ BL2_SOURCES += drivers/io/io_fip.c \
plat/arm/common/arm_bl2_setup.c \
plat/arm/common/arm_io_storage.c
ifeq (${LOAD_IMAGE_V2},1)
-BL2_SOURCES += plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c\
- plat/arm/common/arm_image_load.c \
+# Because BL1/BL2 execute in AArch64 mode but BL32 in AArch32 we need to use
+# the AArch32 descriptors.
+ifeq (${JUNO_AARCH32_EL3_RUNTIME},1)
+BL2_SOURCES += plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
+else
+BL2_SOURCES += plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c
+endif
+BL2_SOURCES += plat/arm/common/arm_image_load.c \
common/desc_image_load.c
endif
diff --git a/plat/arm/css/common/aarch32/css_helpers.S b/plat/arm/css/common/aarch32/css_helpers.S
new file mode 100644
index 00000000..b7075bd7
--- /dev/null
+++ b/plat/arm/css/common/aarch32/css_helpers.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+#include <css_def.h>
+
+ .weak plat_secondary_cold_boot_setup
+ .weak plat_get_my_entrypoint
+ .globl css_calc_core_pos_swap_cluster
+ .weak plat_is_my_cpu_primary
+
+ /* ---------------------------------------------------------------------
+ * void plat_secondary_cold_boot_setup(void);
+ * In the normal boot flow, cold-booting secondary
+ * CPUs is not yet implemented and they panic.
+ * ---------------------------------------------------------------------
+ */
+func plat_secondary_cold_boot_setup
+ /* TODO: Implement secondary CPU cold boot setup on CSS platforms */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+ /* ---------------------------------------------------------------------
+ * uintptr_t plat_get_my_entrypoint (void);
+ *
+ * Main job of this routine is to distinguish between a cold and a warm
+ * boot. On CSS platforms, this distinction is based on the contents of
+ * the Trusted Mailbox. It is initialised to zero by the SCP before the
+ * AP cores are released from reset. Therefore, a zero mailbox means
+ * it's a cold reset.
+ *
+ * This functions returns the contents of the mailbox, i.e.:
+ * - 0 for a cold boot;
+ * - the warm boot entrypoint for a warm boot.
+ * ---------------------------------------------------------------------
+ */
+func plat_get_my_entrypoint
+ ldr r0, =PLAT_ARM_TRUSTED_MAILBOX_BASE
+ ldr r0, [r0]
+ bx lr
+endfunc plat_get_my_entrypoint
+
+ /* -----------------------------------------------------------
+ * unsigned int css_calc_core_pos_swap_cluster(u_register_t mpidr)
+ * Utility function to calculate the core position by
+ * swapping the cluster order. This is necessary in order to
+ * match the format of the boot information passed by the SCP
+ * and read in plat_is_my_cpu_primary below.
+ * -----------------------------------------------------------
+ */
+func css_calc_core_pos_swap_cluster
+ and r1, r0, #MPIDR_CPU_MASK
+ and r0, r0, #MPIDR_CLUSTER_MASK
+ eor r0, r0, #(1 << MPIDR_AFFINITY_BITS) // swap cluster order
+ add r0, r1, r0, LSR #6
+ bx lr
+endfunc css_calc_core_pos_swap_cluster
+
+ /* -----------------------------------------------------
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu (applicable ony after a cold boot)
+ * -----------------------------------------------------
+ */
+func plat_is_my_cpu_primary
+ mov r10, lr
+ bl plat_my_core_pos
+ ldr r1, =SCP_BOOT_CFG_ADDR
+ ldr r1, [r1]
+ ubfx r1, r1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \
+ #PLAT_CSS_PRIMARY_CPU_BIT_WIDTH
+ cmp r0, r1
+ moveq r0, #1
+ movne r0, #0
+ bx r10
+endfunc plat_is_my_cpu_primary
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index 86ba6df5..24215a5d 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -36,7 +36,7 @@ PLAT_INCLUDES += -Iinclude/plat/arm/css/common \
-Iinclude/plat/arm/css/common/aarch64
-PLAT_BL_COMMON_SOURCES += plat/arm/css/common/aarch64/css_helpers.S
+PLAT_BL_COMMON_SOURCES += plat/arm/css/common/${ARCH}/css_helpers.S
BL1_SOURCES += plat/arm/css/common/css_bl1_setup.c
@@ -64,7 +64,7 @@ $(eval $(call assert_boolean,CSS_LOAD_SCP_IMAGES))
$(eval $(call add_define,CSS_LOAD_SCP_IMAGES))
ifeq (${CSS_LOAD_SCP_IMAGES},1)
- $(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw))
+ NEED_SCP_BL2 := yes
ifneq (${TRUSTED_BOARD_BOOT},0)
$(eval $(call FWU_FIP_ADD_IMG,SCP_BL2U,--scp-fwu-cfg))
endif
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index d4dd0af7..21ce8655 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -75,6 +75,13 @@ const unsigned int arm_pm_idle_states[] = {
CASSERT(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL1,
assert_max_pwr_lvl_supported_mismatch);
+/*
+ * Ensure that the PLAT_MAX_PWR_LVL is not greater than CSS_SYSTEM_PWR_DMN_LVL
+ * assumed by the CSS layer.
+ */
+CASSERT(PLAT_MAX_PWR_LVL <= CSS_SYSTEM_PWR_DMN_LVL,
+ assert_max_pwr_lvl_higher_than_css_sys_lvl);
+
/*******************************************************************************
* Handler called when a power domain is about to be turned on. The
* level and mpidr determine the affinity instance.
@@ -243,7 +250,7 @@ void css_get_sys_suspend_power_state(psci_power_state_t *req_state)
* System Suspend is supported only if the system power domain node
* is implemented.
*/
- assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
+ assert(PLAT_MAX_PWR_LVL == CSS_SYSTEM_PWR_DMN_LVL);
for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++)
req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF;
@@ -257,6 +264,39 @@ int css_node_hw_state(u_register_t mpidr, unsigned int power_level)
return css_scp_get_power_state(mpidr, power_level);
}
+/*
+ * 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 css_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[CSS_SYSTEM_PWR_DMN_LVL] = ARM_LOCAL_STATE_RUN;
+ return rc;
+}
+
+/*
+ * Custom `translate_power_state_by_mpidr` handler for CSS. Unlike in the
+ * `css_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 css_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 will take care of registering the handlers with PSCI.
@@ -270,7 +310,9 @@ plat_psci_ops_t plat_arm_psci_pm_ops = {
.pwr_domain_suspend_finish = css_pwr_domain_suspend_finish,
.system_off = css_system_off,
.system_reset = css_system_reset,
- .validate_power_state = arm_validate_power_state,
+ .validate_power_state = css_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint,
- .get_node_hw_state = css_node_hw_state
+ .translate_power_state_by_mpidr = css_translate_power_state_by_mpidr,
+ .get_node_hw_state = css_node_hw_state,
+ .get_sys_suspend_power_state = css_get_sys_suspend_power_state
};
diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/plat/arm/css/drivers/scp/css_pm_scpi.c
index e22504d1..3b643e66 100644
--- a/plat/arm/css/drivers/scp/css_pm_scpi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scpi.c
@@ -32,6 +32,7 @@
#include <assert.h>
#include <css_pm.h>
#include <debug.h>
+#include <plat_arm.h>
#include "../scpi/css_scpi.h"
#include "css_scp.h"
@@ -134,6 +135,12 @@ void __dead2 css_scp_sys_shutdown(void)
{
uint32_t response;
+ /*
+ * Disable GIC CPU interface to prevent pending interrupt
+ * from waking up the AP from WFI.
+ */
+ plat_arm_gic_cpuif_disable();
+
/* Send the power down request to the SCP */
response = scpi_sys_power_state(scpi_system_shutdown);
@@ -153,6 +160,12 @@ void __dead2 css_scp_sys_reboot(void)
{
uint32_t response;
+ /*
+ * Disable GIC CPU interface to prevent pending interrupt
+ * from waking up the AP from WFI.
+ */
+ plat_arm_gic_cpuif_disable();
+
/* Send the system reset request to the SCP */
response = scpi_sys_power_state(scpi_system_reboot);