Commit 84ab33e1 authored by danh-arm's avatar danh-arm
Browse files

Merge pull request #410 from soby-mathew/sm/psci_handler_reorg

Reorganise PSCI PM handler setup on ARM Standard platforms
parents 7b66a026 785fb92b
...@@ -39,8 +39,6 @@ ...@@ -39,8 +39,6 @@
*************************************************************************/ *************************************************************************/
#define MHU_PAYLOAD_CACHED 0 #define MHU_PAYLOAD_CACHED 0
#define TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
#define NSROM_BASE 0x1f000000 #define NSROM_BASE 0x1f000000
#define NSROM_SIZE 0x00001000 #define NSROM_SIZE 0x00001000
...@@ -116,4 +114,8 @@ ...@@ -116,4 +114,8 @@
/* System timer related constants */ /* System timer related constants */
#define PLAT_ARM_NSTIMER_FRAME_ID 1 #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__ */ #endif /* __CSS_DEF_H__ */
/*
* 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__ */
...@@ -140,7 +140,7 @@ warm_reset: ...@@ -140,7 +140,7 @@ warm_reset:
* it here with SO attributes. * it here with SO attributes.
* --------------------------------------------------------------------- * ---------------------------------------------------------------------
*/ */
mov_imm x0, MBOX_BASE mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
ldr x0, [x0] ldr x0, [x0]
cbz x0, _panic cbz x0, _panic
ret ret
......
...@@ -134,12 +134,4 @@ ...@@ -134,12 +134,4 @@
#define FVP_NSAID_HDLCD0 2 #define FVP_NSAID_HDLCD0 2
#define FVP_NSAID_CLCD 7 #define FVP_NSAID_CLCD 7
/*******************************************************************************
* Shared Data
******************************************************************************/
/* Entrypoint mailboxes */
#define MBOX_BASE ARM_SHARED_RAM_BASE
#endif /* __FVP_DEF_H__ */ #endif /* __FVP_DEF_H__ */
...@@ -65,17 +65,6 @@ const unsigned int arm_pm_idle_states[] = { ...@@ -65,17 +65,6 @@ const unsigned int arm_pm_idle_states[] = {
}; };
#endif #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 * Function which implements the common FVP specific operations to power down a
* cpu in response to a CPU_OFF or CPU_SUSPEND request. * cpu in response to a CPU_OFF or CPU_SUSPEND request.
...@@ -293,9 +282,10 @@ static void __dead2 fvp_system_reset(void) ...@@ -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, .cpu_standby = fvp_cpu_standby,
.pwr_domain_on = fvp_pwr_domain_on, .pwr_domain_on = fvp_pwr_domain_on,
.pwr_domain_off = fvp_pwr_domain_off, .pwr_domain_off = fvp_pwr_domain_off,
...@@ -307,16 +297,3 @@ static const plat_psci_ops_t fvp_plat_psci_ops = { ...@@ -307,16 +297,3 @@ static const plat_psci_ops_t fvp_plat_psci_ops = {
.validate_power_state = arm_validate_power_state, .validate_power_state = arm_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint .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;
}
...@@ -88,6 +88,10 @@ ...@@ -88,6 +88,10 @@
/* System timer related constants */ /* System timer related constants */
#define PLAT_ARM_NSTIMER_FRAME_ID 1 #define PLAT_ARM_NSTIMER_FRAME_ID 1
/* Mailbox base address */
#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
/* TrustZone controller related constants /* TrustZone controller related constants
* *
* Currently only filters 0 and 2 are connected on Base FVP. * Currently only filters 0 and 2 are connected on Base FVP.
......
...@@ -33,13 +33,16 @@ ...@@ -33,13 +33,16 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <plat_arm.h> #include <plat_arm.h>
#include <platform_def.h>
#include <psci.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 #if ARM_RECOM_STATE_ID_ENC
extern unsigned int arm_pm_idle_states[]; extern unsigned int arm_pm_idle_states[];
#endif /* __ARM_RECOM_STATE_ID_ENC__ */ #endif /* __ARM_RECOM_STATE_ID_ENC__ */
#if !ARM_RECOM_STATE_ID_ENC #if !ARM_RECOM_STATE_ID_ENC
/******************************************************************************* /*******************************************************************************
* ARM standard platform handler called to check the validity of the power state * 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) ...@@ -144,3 +147,42 @@ int arm_validate_ns_entrypoint(uintptr_t entrypoint)
return PSCI_E_INVALID_ADDRESS; 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;
}
...@@ -67,7 +67,7 @@ endfunc plat_secondary_cold_boot_setup ...@@ -67,7 +67,7 @@ endfunc plat_secondary_cold_boot_setup
* --------------------------------------------------------------------- * ---------------------------------------------------------------------
*/ */
func plat_get_my_entrypoint func plat_get_my_entrypoint
mov_imm x0, TRUSTED_MAILBOX_BASE mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
ldr x0, [x0] ldr x0, [x0]
ret ret
endfunc plat_get_my_entrypoint endfunc plat_get_my_entrypoint
......
...@@ -28,19 +28,20 @@ ...@@ -28,19 +28,20 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <assert.h>
#include <arch_helpers.h> #include <arch_helpers.h>
#include <assert.h>
#include <arm_gic.h> #include <arm_gic.h>
#include <cci.h> #include <cci.h>
#include <css_def.h> #include <css_pm.h>
#include <debug.h> #include <debug.h>
#include <errno.h> #include <errno.h>
#include <plat_arm.h> #include <plat_arm.h>
#include <platform.h> #include <platform.h>
#include <platform_def.h> #include <platform_def.h>
#include <psci.h>
#include "css_scpi.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 #if ARM_RECOM_STATE_ID_ENC
/* /*
...@@ -63,17 +64,6 @@ const unsigned int arm_pm_idle_states[] = { ...@@ -63,17 +64,6 @@ const unsigned int arm_pm_idle_states[] = {
}; };
#endif #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 * Handler called when a power domain is about to be turned on. The
* level and mpidr determine the affinity instance. * level and mpidr determine the affinity instance.
...@@ -149,7 +139,7 @@ static void css_power_down_common(const psci_power_state_t *target_state) ...@@ -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 * 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. * 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] == assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
ARM_LOCAL_STATE_OFF); ARM_LOCAL_STATE_OFF);
...@@ -161,7 +151,7 @@ static void css_pwr_domain_off(const psci_power_state_t *target_state) ...@@ -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 * Handler called when a power domain is about to be suspended. The
* target_state encodes the power state that each level should transition to. * 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 * 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) ...@@ -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 * TODO: At the moment we reuse the on finisher and reinitialize the secure
* context. Need to implement a separate suspend finisher. * 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) const psci_power_state_t *target_state)
{ {
/* /*
...@@ -200,7 +190,7 @@ static void css_pwr_domain_suspend_finish( ...@@ -200,7 +190,7 @@ static void css_pwr_domain_suspend_finish(
/******************************************************************************* /*******************************************************************************
* Handlers to shutdown/reboot the system * Handlers to shutdown/reboot the system
******************************************************************************/ ******************************************************************************/
static void __dead2 css_system_off(void) void __dead2 css_system_off(void)
{ {
uint32_t response; uint32_t response;
...@@ -216,7 +206,7 @@ static void __dead2 css_system_off(void) ...@@ -216,7 +206,7 @@ static void __dead2 css_system_off(void)
panic(); panic();
} }
static void __dead2 css_system_reset(void) void __dead2 css_system_reset(void)
{ {
uint32_t response; uint32_t response;
...@@ -256,9 +246,10 @@ void css_cpu_standby(plat_local_state_t cpu_state) ...@@ -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 = css_pwr_domain_on,
.pwr_domain_on_finish = css_pwr_domain_on_finish, .pwr_domain_on_finish = css_pwr_domain_on_finish,
.pwr_domain_off = css_pwr_domain_off, .pwr_domain_off = css_pwr_domain_off,
...@@ -270,16 +261,3 @@ static const plat_psci_ops_t css_ops = { ...@@ -270,16 +261,3 @@ static const plat_psci_ops_t css_ops = {
.validate_power_state = arm_validate_power_state, .validate_power_state = arm_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint .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;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment