Browse Source

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
pull/410/head
Soby Mathew 9 years ago
parent
commit
785fb92b8a
  1. 6
      include/plat/arm/css/common/css_def.h
  2. 48
      include/plat/arm/css/common/css_pm.h
  3. 2
      plat/arm/board/fvp/aarch64/fvp_helpers.S
  4. 8
      plat/arm/board/fvp/fvp_def.h
  5. 29
      plat/arm/board/fvp/fvp_pm.c
  6. 4
      plat/arm/board/fvp/include/platform_def.h
  7. 44
      plat/arm/common/arm_pm.c
  8. 2
      plat/arm/css/common/aarch64/css_helpers.S
  9. 46
      plat/arm/css/common/css_pm.c

6
include/plat/arm/css/common/css_def.h

@ -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 @@
/* 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__ */

48
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__ */

2
plat/arm/board/fvp/aarch64/fvp_helpers.S

@ -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

8
plat/arm/board/fvp/fvp_def.h

@ -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__ */

29
plat/arm/board/fvp/fvp_pm.c

@ -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)
} }
/******************************************************************************* /*******************************************************************************
* 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 = {
.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;
}

4
plat/arm/board/fvp/include/platform_def.h

@ -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.

44
plat/arm/common/arm_pm.c

@ -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)
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;
}

2
plat/arm/css/common/aarch64/css_helpers.S

@ -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

46
plat/arm/css/common/css_pm.c

@ -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[] = {
}; };
#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)
* 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)
* 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)
* 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(
/******************************************************************************* /*******************************************************************************
* 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)
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)
} }
/******************************************************************************* /*******************************************************************************
* 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 = {
.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;
}

Loading…
Cancel
Save