Commit 785fb92b authored by Soby Mathew's avatar Soby Mathew
Browse files

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
parent a3a34899
......@@ -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__ */
/*
* 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:
* 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
......
......@@ -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__ */
......@@ -65,17 +65,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;
}
......@@ -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.
......
......@@ -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;
}
......@@ -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
......
......@@ -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
/*
......@@ -63,17 +64,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;
}
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