summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2015-09-29 15:47:16 +0100
committerSoby Mathew <soby.mathew@arm.com>2015-10-20 14:11:04 +0100
commit785fb92b8a021369348da2316b99b7e143c2806f (patch)
tree38be87aed4b6fb7f1d4243d3a063eda65c582c60
parenta3a348993ad0a2b863f6277229423152fbed0af0 (diff)
Reorganise PSCI PM handler setup on ARM Standard platforms
This patch does the following reorganization to psci power management (PM) handler setup for ARM standard platform ports : 1. The mailbox programming required during `plat_setup_psci_ops()` is identical for all ARM platforms. Hence the implementation of this API is now moved to the common `arm_pm.c` file. Each ARM platform now must define the PLAT_ARM_TRUSTED_MAILBOX_BASE macro, which in current platforms is the same as ARM_SHARED_RAM_BASE. 2. The PSCI PM handler callback structure, `plat_psci_ops`, must now be exported via `plat_arm_psci_pm_ops`. This allows the common implementation of `plat_setup_psci_ops()` to return a platform specific `plat_psci_ops`. In the case of CSS platforms, a default weak implementation of the same is provided in `css_pm.c` which can be overridden by each CSS platform. 3. For CSS platforms, the PSCI PM handlers defined in `css_pm.c` are now made library functions and a new header file `css_pm.h` is added to export these generic PM handlers. This allows the platform to reuse the adequate CSS PM handlers and redefine others which need to be customized when overriding the default `plat_arm_psci_pm_ops` in `css_pm.c`. Change-Id: I277910f609e023ee5d5ff0129a80ecfce4356ede
-rw-r--r--include/plat/arm/css/common/css_def.h6
-rw-r--r--include/plat/arm/css/common/css_pm.h48
-rw-r--r--plat/arm/board/fvp/aarch64/fvp_helpers.S2
-rw-r--r--plat/arm/board/fvp/fvp_def.h8
-rw-r--r--plat/arm/board/fvp/fvp_pm.c29
-rw-r--r--plat/arm/board/fvp/include/platform_def.h4
-rw-r--r--plat/arm/common/arm_pm.c44
-rw-r--r--plat/arm/css/common/aarch64/css_helpers.S2
-rw-r--r--plat/arm/css/common/css_pm.c46
9 files changed, 116 insertions, 73 deletions
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 38ff9ddd..98b69cb3 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -39,8 +39,6 @@
*************************************************************************/
#define MHU_PAYLOAD_CACHED 0
-#define TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
-
#define NSROM_BASE 0x1f000000
#define NSROM_SIZE 0x00001000
@@ -116,4 +114,8 @@
/* System timer related constants */
#define PLAT_ARM_NSTIMER_FRAME_ID 1
+/* Trusted mailbox base address common to all CSS */
+#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
+
+
#endif /* __CSS_DEF_H__ */
diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h
new file mode 100644
index 00000000..c19df92b
--- /dev/null
+++ b/include/plat/arm/css/common/css_pm.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef __CSS_PM_H__
+#define __CSS_PM_H__
+
+#include <cdefs.h>
+#include <psci.h>
+#include <types.h>
+
+int css_pwr_domain_on(u_register_t mpidr);
+void css_pwr_domain_on_finish(const psci_power_state_t *target_state);
+void css_pwr_domain_off(const psci_power_state_t *target_state);
+void css_pwr_domain_suspend(const psci_power_state_t *target_state);
+void css_pwr_domain_suspend_finish(
+ const psci_power_state_t *target_state);
+void __dead2 css_system_off(void);
+void __dead2 css_system_reset(void);
+void css_cpu_standby(plat_local_state_t cpu_state);
+
+#endif /* __CSS_PM_H__ */
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 42e5b70c..865c615a 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -140,7 +140,7 @@ warm_reset:
* it here with SO attributes.
* ---------------------------------------------------------------------
*/
- mov_imm x0, MBOX_BASE
+ mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
ldr x0, [x0]
cbz x0, _panic
ret
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index 9a9eebfc..3af4db68 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -134,12 +134,4 @@
#define FVP_NSAID_HDLCD0 2
#define FVP_NSAID_CLCD 7
-/*******************************************************************************
- * Shared Data
- ******************************************************************************/
-
-/* Entrypoint mailboxes */
-#define MBOX_BASE ARM_SHARED_RAM_BASE
-
-
#endif /* __FVP_DEF_H__ */
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 9d6ab9ce..21ad14fa 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -66,17 +66,6 @@ const unsigned int arm_pm_idle_states[] = {
#endif
/*******************************************************************************
- * Private FVP function to program the mailbox for a cpu before it is released
- * from reset.
- ******************************************************************************/
-static void fvp_program_mailbox(uintptr_t address)
-{
- uintptr_t *mailbox = (void *) MBOX_BASE;
- *mailbox = address;
- flush_dcache_range((uintptr_t) mailbox, sizeof(*mailbox));
-}
-
-/*******************************************************************************
* Function which implements the common FVP specific operations to power down a
* cpu in response to a CPU_OFF or CPU_SUSPEND request.
******************************************************************************/
@@ -293,9 +282,10 @@ static void __dead2 fvp_system_reset(void)
}
/*******************************************************************************
- * Export the platform handlers to enable psci to invoke them
+ * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
+ * platform layer will take care of registering the handlers with PSCI.
******************************************************************************/
-static const plat_psci_ops_t fvp_plat_psci_ops = {
+const plat_psci_ops_t plat_arm_psci_pm_ops = {
.cpu_standby = fvp_cpu_standby,
.pwr_domain_on = fvp_pwr_domain_on,
.pwr_domain_off = fvp_pwr_domain_off,
@@ -307,16 +297,3 @@ static const plat_psci_ops_t fvp_plat_psci_ops = {
.validate_power_state = arm_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint
};
-
-/*******************************************************************************
- * Export the platform specific psci ops & initialize the fvp power controller
- ******************************************************************************/
-int plat_setup_psci_ops(uintptr_t sec_entrypoint,
- const plat_psci_ops_t **psci_ops)
-{
- *psci_ops = &fvp_plat_psci_ops;
-
- /* Program the jump address */
- fvp_program_mailbox(sec_entrypoint);
- return 0;
-}
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 155216a8..840676ce 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -88,6 +88,10 @@
/* System timer related constants */
#define PLAT_ARM_NSTIMER_FRAME_ID 1
+/* Mailbox base address */
+#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
+
+
/* TrustZone controller related constants
*
* Currently only filters 0 and 2 are connected on Base FVP.
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index b2251700..2497588f 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -33,13 +33,16 @@
#include <assert.h>
#include <errno.h>
#include <plat_arm.h>
+#include <platform_def.h>
#include <psci.h>
+/* Standard ARM platforms are expected to export plat_arm_psci_pm_ops */
+extern const plat_psci_ops_t plat_arm_psci_pm_ops;
+
#if ARM_RECOM_STATE_ID_ENC
extern unsigned int arm_pm_idle_states[];
#endif /* __ARM_RECOM_STATE_ID_ENC__ */
-
#if !ARM_RECOM_STATE_ID_ENC
/*******************************************************************************
* ARM standard platform handler called to check the validity of the power state
@@ -144,3 +147,42 @@ int arm_validate_ns_entrypoint(uintptr_t entrypoint)
return PSCI_E_INVALID_ADDRESS;
}
+
+/*******************************************************************************
+ * Private function to program the mailbox for a cpu before it is released
+ * from reset. This function assumes that the Trusted mail box base is within
+ * the ARM_SHARED_RAM region
+ ******************************************************************************/
+static void arm_program_trusted_mailbox(uintptr_t address)
+{
+ uintptr_t *mailbox = (void *) PLAT_ARM_TRUSTED_MAILBOX_BASE;
+
+ *mailbox = address;
+
+ /*
+ * Ensure that the PLAT_ARM_TRUSTED_MAILBOX_BASE is within
+ * ARM_SHARED_RAM region.
+ */
+ assert((PLAT_ARM_TRUSTED_MAILBOX_BASE >= ARM_SHARED_RAM_BASE) &&
+ ((PLAT_ARM_TRUSTED_MAILBOX_BASE + sizeof(*mailbox)) <= \
+ (ARM_SHARED_RAM_BASE + ARM_SHARED_RAM_SIZE)));
+
+ /* Flush data cache if the mail box shared RAM is cached */
+#if PLAT_ARM_SHARED_RAM_CACHED
+ flush_dcache_range((uintptr_t) mailbox, sizeof(*mailbox));
+#endif
+}
+
+/*******************************************************************************
+ * The ARM Standard platform definition of platform porting API
+ * `plat_setup_psci_ops`.
+ ******************************************************************************/
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ *psci_ops = &plat_arm_psci_pm_ops;
+
+ /* Setup mailbox with entry point. */
+ arm_program_trusted_mailbox(sec_entrypoint);
+ return 0;
+}
diff --git a/plat/arm/css/common/aarch64/css_helpers.S b/plat/arm/css/common/aarch64/css_helpers.S
index 05bd8647..1137a492 100644
--- a/plat/arm/css/common/aarch64/css_helpers.S
+++ b/plat/arm/css/common/aarch64/css_helpers.S
@@ -67,7 +67,7 @@ endfunc plat_secondary_cold_boot_setup
* ---------------------------------------------------------------------
*/
func plat_get_my_entrypoint
- mov_imm x0, TRUSTED_MAILBOX_BASE
+ mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
ldr x0, [x0]
ret
endfunc plat_get_my_entrypoint
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index cc64bf8b..c0c615b9 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -28,19 +28,20 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <assert.h>
#include <arch_helpers.h>
+#include <assert.h>
#include <arm_gic.h>
#include <cci.h>
-#include <css_def.h>
+#include <css_pm.h>
#include <debug.h>
#include <errno.h>
#include <plat_arm.h>
#include <platform.h>
#include <platform_def.h>
-#include <psci.h>
#include "css_scpi.h"
+/* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
+#pragma weak plat_arm_psci_pm_ops
#if ARM_RECOM_STATE_ID_ENC
/*
@@ -64,17 +65,6 @@ const unsigned int arm_pm_idle_states[] = {
#endif
/*******************************************************************************
- * Private function to program the mailbox for a cpu before it is released
- * from reset.
- ******************************************************************************/
-static void css_program_mailbox(uintptr_t address)
-{
- uintptr_t *mailbox = (void *) TRUSTED_MAILBOX_BASE;
- *mailbox = address;
- flush_dcache_range((uintptr_t) mailbox, sizeof(*mailbox));
-}
-
-/*******************************************************************************
* Handler called when a power domain is about to be turned on. The
* level and mpidr determine the affinity instance.
******************************************************************************/
@@ -149,7 +139,7 @@ static void css_power_down_common(const psci_power_state_t *target_state)
* Handler called when a power domain is about to be turned off. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-static void css_pwr_domain_off(const psci_power_state_t *target_state)
+void css_pwr_domain_off(const psci_power_state_t *target_state)
{
assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
ARM_LOCAL_STATE_OFF);
@@ -161,7 +151,7 @@ static void css_pwr_domain_off(const psci_power_state_t *target_state)
* Handler called when a power domain is about to be suspended. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-static void css_pwr_domain_suspend(const psci_power_state_t *target_state)
+void css_pwr_domain_suspend(const psci_power_state_t *target_state)
{
/*
* Juno has retention only at cpu level. Just return
@@ -184,7 +174,7 @@ static void css_pwr_domain_suspend(const psci_power_state_t *target_state)
* TODO: At the moment we reuse the on finisher and reinitialize the secure
* context. Need to implement a separate suspend finisher.
******************************************************************************/
-static void css_pwr_domain_suspend_finish(
+void css_pwr_domain_suspend_finish(
const psci_power_state_t *target_state)
{
/*
@@ -200,7 +190,7 @@ static void css_pwr_domain_suspend_finish(
/*******************************************************************************
* Handlers to shutdown/reboot the system
******************************************************************************/
-static void __dead2 css_system_off(void)
+void __dead2 css_system_off(void)
{
uint32_t response;
@@ -216,7 +206,7 @@ static void __dead2 css_system_off(void)
panic();
}
-static void __dead2 css_system_reset(void)
+void __dead2 css_system_reset(void)
{
uint32_t response;
@@ -256,9 +246,10 @@ void css_cpu_standby(plat_local_state_t cpu_state)
}
/*******************************************************************************
- * Export the platform handlers to enable psci to invoke them
+ * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
+ * platform will take care of registering the handlers with PSCI.
******************************************************************************/
-static const plat_psci_ops_t css_ops = {
+const 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,
@@ -270,16 +261,3 @@ static const plat_psci_ops_t css_ops = {
.validate_power_state = arm_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint
};
-
-/*******************************************************************************
- * Export the platform specific psci ops.
- ******************************************************************************/
-int plat_setup_psci_ops(uintptr_t sec_entrypoint,
- const plat_psci_ops_t **psci_ops)
-{
- *psci_ops = &css_ops;
-
- /* Setup mailbox with entry point. */
- css_program_mailbox(sec_entrypoint);
- return 0;
-}