diff options
Diffstat (limited to 'src/arch/arm64/include/arch/psci.h')
-rw-r--r-- | src/arch/arm64/include/arch/psci.h | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/arch/arm64/include/arch/psci.h b/src/arch/arm64/include/arch/psci.h index c39f13a088..afa4c4209c 100644 --- a/src/arch/arm64/include/arch/psci.h +++ b/src/arch/arm64/include/arch/psci.h @@ -20,6 +20,8 @@ #ifndef __ARCH_PSCI_H__ #define __ARCH_PSCI_H__ +#include <stdint.h> +#include <arch/cpu.h> #include <arch/smc.h> /* Return Values */ @@ -35,6 +37,85 @@ enum { PSCI_RET_DISABLED = -8, }; +/* Generic PSCI state. */ +enum { + PSCI_STATE_OFF = 0, + PSCI_STATE_ON_PENDING, + PSCI_STATE_ON, +}; + +/* Affinity level support. */ +enum { + PSCI_AFFINITY_LEVEL_0, + PSCI_AFFINITY_LEVEL_1, + PSCI_AFFINITY_LEVEL_2, + PSCI_AFFINITY_LEVEL_3, + PSCI_AFFINITY_ROOT, + PSCI_AFFINITY_LEVEL_HIGHEST = PSCI_AFFINITY_ROOT, +}; + +static inline int psci_level_below(int level) +{ + return level - 1; +} + +struct psci_node; + +struct psci_cpu_state { + struct cpu_info *ci; + void *entry; + void *arg; + /* Ancestor of target to update state in CPU_ON case. */ + struct psci_node *ancestor; +}; + +struct psci_node_group { + size_t num; + struct psci_node *nodes; +}; + +struct psci_node { + uint64_t mpidr; + /* Affinity level of node. */ + int level; + /* Generic power state of this entity. */ + int state; + /* The SoC can stash its own state accounting in here. */ + int soc_state; + /* Parent of curernt entity. */ + struct psci_node *parent; + /* + * CPUs are leaves in the tree. They don't have children. The + * CPU-specific bits of storage can be shared with the children + * storage. + */ + union { + struct psci_node_group children; + struct psci_cpu_state cpu_state; + }; +}; + +static inline struct psci_node *psci_node_parent(const struct psci_node *n) +{ + return n->parent; +} + +static inline int psci_root_node(const struct psci_node *n) +{ + return psci_node_parent(n) == NULL; +} + +struct psci_soc_ops { + /* + * Return number of entities one level below given parent affinitly + * level and mpidr. + */ + size_t (*children_at_level)(int parent_level, uint64_t mpidr); +}; + +/* Each SoC needs to provide the functions in the psci_soc_ops structure. */ +extern struct psci_soc_ops soc_psci_ops; + /* PSCI Functions. */ enum { /* 32-bit System level functions. */ @@ -111,5 +192,6 @@ void psci_init(void); /* Turn on the current CPU within the PSCI subsystem. */ void psci_turn_on_self(void *entry, void *arg); +int psci_turn_off_self(void); #endif /* __ARCH_PSCI_H__ */ |