psci: replace secure context with suspend context

The secure context saved and restored across a cpu_suspend operation
can be more than just the state of the secure system registers e.g. we
also need to save the affinity level till which the cpu is being
powered down. This patch creates a suspend_context data structure
which includes the system register context. This will allow other bits
to be saved and restored as well in subsequent patches.

Change-Id: I1c1f7d25497388b54b7d6ee4fab77e8c6a9992c4
This commit is contained in:
Achin Gupta 2013-12-05 14:21:04 +00:00 committed by Dan Handley
parent 03cb8fbb5d
commit a59caa4cbd
4 changed files with 52 additions and 40 deletions

View File

@ -73,16 +73,16 @@ static int psci_afflvl0_suspend(unsigned long mpidr,
* Arch. management: Save the secure context, flush the
* L1 caches and exit intra-cluster coherency et al
*/
psci_secure_context[index].sctlr = read_sctlr();
psci_secure_context[index].scr = read_scr();
psci_secure_context[index].cptr = read_cptr();
psci_secure_context[index].cpacr = read_cpacr();
psci_secure_context[index].cntfrq = read_cntfrq_el0();
psci_secure_context[index].mair = read_mair();
psci_secure_context[index].tcr = read_tcr();
psci_secure_context[index].ttbr = read_ttbr0();
psci_secure_context[index].vbar = read_vbar();
psci_secure_context[index].pstate =
psci_suspend_context[index].sec_sysregs.sctlr = read_sctlr();
psci_suspend_context[index].sec_sysregs.scr = read_scr();
psci_suspend_context[index].sec_sysregs.cptr = read_cptr();
psci_suspend_context[index].sec_sysregs.cpacr = read_cpacr();
psci_suspend_context[index].sec_sysregs.cntfrq = read_cntfrq_el0();
psci_suspend_context[index].sec_sysregs.mair = read_mair();
psci_suspend_context[index].sec_sysregs.tcr = read_tcr();
psci_suspend_context[index].sec_sysregs.ttbr = read_ttbr0();
psci_suspend_context[index].sec_sysregs.vbar = read_vbar();
psci_suspend_context[index].sec_sysregs.pstate =
read_daif() & (DAIF_ABT_BIT | DAIF_DBG_BIT);
/* Set the secure world (EL3) re-entry point after BL1 */
@ -411,18 +411,18 @@ static unsigned int psci_afflvl0_suspend_finish(unsigned long mpidr,
* Arch. management: Restore the stashed secure architectural
* context in the right order.
*/
write_vbar(psci_secure_context[index].vbar);
write_daif(read_daif() | psci_secure_context[index].pstate);
write_mair(psci_secure_context[index].mair);
write_tcr(psci_secure_context[index].tcr);
write_ttbr0(psci_secure_context[index].ttbr);
write_sctlr(psci_secure_context[index].sctlr);
write_vbar(psci_suspend_context[index].sec_sysregs.vbar);
write_daif(read_daif() | psci_suspend_context[index].sec_sysregs.pstate);
write_mair(psci_suspend_context[index].sec_sysregs.mair);
write_tcr(psci_suspend_context[index].sec_sysregs.tcr);
write_ttbr0(psci_suspend_context[index].sec_sysregs.ttbr);
write_sctlr(psci_suspend_context[index].sec_sysregs.sctlr);
/* MMU and coherency should be enabled by now */
write_scr(psci_secure_context[index].scr);
write_cptr(psci_secure_context[index].cptr);
write_cpacr(psci_secure_context[index].cpacr);
write_cntfrq_el0(psci_secure_context[index].cntfrq);
write_scr(psci_suspend_context[index].sec_sysregs.scr);
write_cptr(psci_suspend_context[index].sec_sysregs.cptr);
write_cpacr(psci_suspend_context[index].sec_sysregs.cpacr);
write_cntfrq_el0(psci_suspend_context[index].sec_sysregs.cntfrq);
/*
* Generic management: Now we just need to retrieve the

View File

@ -41,10 +41,10 @@
/*******************************************************************************
* Arrays that contains information needs to resume a cpu's execution when woken
* out of suspend or off states. 'psci_ns_einfo_idx' keeps track of the next
* free index in the 'psci_ns_entry_info' & 'psci_secure_context' arrays. Each
* free index in the 'psci_ns_entry_info' & 'psci_suspend_context' arrays. Each
* cpu is allocated a single entry in each array during startup.
******************************************************************************/
secure_context psci_secure_context[PSCI_NUM_AFFS];
suspend_context psci_suspend_context[PSCI_NUM_AFFS];
ns_entry_info psci_ns_entry_info[PSCI_NUM_AFFS];
unsigned int psci_ns_einfo_idx;

View File

@ -31,6 +31,7 @@
#ifndef __PSCI_PRIVATE_H__
#define __PSCI_PRIVATE_H__
#include <arch.h>
#include <bakery_lock.h>
#ifndef __ASSEMBLY__
@ -50,23 +51,6 @@ typedef struct {
unsigned int sctlr;
} ns_entry_info;
/*******************************************************************************
*
*
******************************************************************************/
typedef struct {
unsigned long sctlr;
unsigned long scr;
unsigned long cptr;
unsigned long cpacr;
unsigned long cntfrq;
unsigned long mair;
unsigned long tcr;
unsigned long ttbr;
unsigned long vbar;
unsigned long pstate;
} secure_context;
/*******************************************************************************
* The following two data structures hold the topology tree which in turn tracks
* the state of the all the affinity instances supported by the platform.
@ -84,6 +68,17 @@ typedef struct {
int max;
} aff_limits_node;
/*******************************************************************************
* This data structure holds secure world context that needs to be preserved
* across cpu_suspend calls which enter the power down state.
******************************************************************************/
typedef struct {
/* Align the suspend level to allow per-cpu lockless access */
int suspend_level
__attribute__((__aligned__(CACHE_WRITEBACK_GRANULE)));
sysregs_context sec_sysregs;
} suspend_context;
typedef aff_map_node *mpidr_aff_map_nodes[MPIDR_MAX_AFFLVL];
typedef unsigned int (*afflvl_power_on_finisher)(unsigned long,
aff_map_node *);
@ -91,7 +86,7 @@ typedef unsigned int (*afflvl_power_on_finisher)(unsigned long,
/*******************************************************************************
* Data prototypes
******************************************************************************/
extern secure_context psci_secure_context[PSCI_NUM_AFFS];
extern suspend_context psci_suspend_context[PSCI_NUM_AFFS];
extern ns_entry_info psci_ns_entry_info[PSCI_NUM_AFFS];
extern unsigned int psci_ns_einfo_idx;
extern aff_limits_node psci_aff_limits[MPIDR_MAX_AFFLVL + 1];

View File

@ -313,6 +313,23 @@
#ifndef __ASSEMBLY__
/*******************************************************************************
* The following data structure holds the system register context across cpu
* save/restore operations
******************************************************************************/
typedef struct {
unsigned long sctlr;
unsigned long scr;
unsigned long cptr;
unsigned long cpacr;
unsigned long cntfrq;
unsigned long mair;
unsigned long tcr;
unsigned long ttbr;
unsigned long vbar;
unsigned long pstate;
} sysregs_context;
/*******************************************************************************
* Function prototypes
******************************************************************************/