aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
******************************************************************************/