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 @@ * 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 @@ * 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 #include #ifndef __ASSEMBLY__ @@ -51,23 +52,6 @@ } 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 @@ 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 @@ /******************************************************************************* * 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 ******************************************************************************/