aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAchin Gupta <achin.gupta@arm.com>2013-12-05 14:21:04 +0000
committerDan Handley <dan.handley@arm.com>2014-01-20 18:45:04 +0000
commita59caa4cbd03c394e7a5bf098ddd9db457b35aae (patch)
treea6ee2402c1c446a352974b8ff68a67a611187344
parent03cb8fbb5d769affd508c97a5327544e487eb1a9 (diff)
downloadarm-trusted-firmware-a59caa4cbd03c394e7a5bf098ddd9db457b35aae.tar.gz
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
-rw-r--r--common/psci/psci_afflvl_suspend.c40
-rw-r--r--common/psci/psci_common.c4
-rw-r--r--common/psci/psci_private.h31
-rw-r--r--include/aarch64/arch.h17
4 files changed, 52 insertions, 40 deletions
diff --git a/common/psci/psci_afflvl_suspend.c b/common/psci/psci_afflvl_suspend.c
index d91b921..6fb60f4 100644
--- a/common/psci/psci_afflvl_suspend.c
+++ b/common/psci/psci_afflvl_suspend.c
@@ -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
diff --git a/common/psci/psci_common.c b/common/psci/psci_common.c
index 969d33c..705c5d7 100644
--- a/common/psci/psci_common.c
+++ b/common/psci/psci_common.c
@@ -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;
diff --git a/common/psci/psci_private.h b/common/psci/psci_private.h
index 7545167..8016ad2 100644
--- a/common/psci/psci_private.h
+++ b/common/psci/psci_private.h
@@ -31,6 +31,7 @@
#ifndef __PSCI_PRIVATE_H__
#define __PSCI_PRIVATE_H__
+#include <arch.h>
#include <bakery_lock.h>
#ifndef __ASSEMBLY__
@@ -51,23 +52,6 @@ typedef struct {
} 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];
diff --git a/include/aarch64/arch.h b/include/aarch64/arch.h
index bcde243..10d2adb 100644
--- a/include/aarch64/arch.h
+++ b/include/aarch64/arch.h
@@ -314,6 +314,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
******************************************************************************/