| Guide to migrate to new Platform porting interface |
| ================================================== |
| |
| Contents |
| -------- |
| |
| 1. [Introduction](#1--introduction) |
| 2. [Platform API modification due to PSCI framework changes](#2--platform-api-modification-due-to-psci-framework-changes) |
| * [Power domain topology framework platform API modifications](#21-power-domain-topology-framework-platform-api-modifications) |
| * [Composite power state framework platform API modifications](#22-composite-power-state-framework-platform-api-modifications) |
| * [Miscellaneous modifications](#23-miscellaneous-modifications) |
| 3. [Compatibility layer](#3--compatibility-layer) |
| 4. [Deprecated Platform API](#4--deprecated-platform-api) |
| |
| - - - - - - - - - - - - - - - - - - |
| |
| |
| 1. Introduction |
| ---------------- |
| |
| The PSCI implementation in Trusted Firmware has undergone a redesign because of |
| three requirements that the PSCI 1.0 specification introduced : |
| |
| * Removing the framework assumption about the structure of the MPIDR, and |
| its relation to the power topology enables support for deeper and more |
| complex hierarchies. |
| |
| * Reworking the power state coordination implementation in the framework |
| to support the more detailed PSCI 1.0 requirements and reduce platform |
| port complexity |
| |
| * Enable the use of the extended power_state parameter and the larger StateID |
| field |
| |
| The PSCI 1.0 implementation introduces new frameworks to fulfill the above |
| requirements. These framework changes mean that the platform porting API must |
| also be modified. This document is a guide to assist migration of the existing |
| platform ports to the new platform API. |
| |
| This document describes the new platform API and compares it with the |
| deprecated API. It also describes the compatibility layer that enables the |
| existing platform ports to work with the PSCI 1.0 implementation. The |
| deprecated platform API is documented for reference. |
| |
| |
| 2. Platform API modification due to PSCI framework changes |
| ----------------------------------------------------------- |
| |
| This section describes changes to the platform APIs. |
| |
| |
| 2.1 Power domain topology framework platform API modifications |
| -------------------------------------------------------------- |
| |
| This removes the assumption in the PSCI implementation that MPIDR |
| based affinity instances map directly to power domains. A power domain, as |
| described in section 4.2 of [PSCI], could contain a core or a logical group |
| of cores (a cluster) which share some state on which power management |
| operations can be performed. The existing affinity instance based APIs |
| `plat_get_aff_count()` and `plat_get_aff_state()` are deprecated. The new |
| platform interfaces that are introduced for this framework are: |
| |
| * `plat_core_pos_by_mpidr()` |
| * `plat_my_core_pos()` |
| * `plat_get_power_domain_tree_desc()` |
| |
| `plat_my_core_pos()` and `plat_core_pos_by_mpidr()` are mandatory |
| and are meant to replace the existing `platform_get_core_pos()` API. |
| The description of these APIs can be found in the [Porting Guide][my_core_pos]. |
| These are used by the power domain topology framework such that: |
| |
| 1. The generic PSCI code does not generate MPIDRs or use them to query the |
| platform about the number of power domains at a particular power level. The |
| `plat_get_power_domain_tree_desc()` provides a description of the power |
| domain tree on the SoC through a pointer to the byte array containing the |
| power domain topology tree description data structure. |
| |
| 2. The linear indices returned by `plat_core_pos_by_mpidr()` and |
| `plat_my_core_pos()` are used to retrieve core power domain nodes from |
| the power domain tree. These core indices are unique for a core and it is a |
| number between `0` and `PLATFORM_CORE_COUNT - 1`. The platform can choose |
| to implement a static mapping between `MPIDR` and core index or implement |
| a dynamic mapping, choosing to skip the unavailable/unused cores to compact |
| the core indices. |
| |
| In addition, the platforms must define the macros `PLAT_NUM_PWR_DOMAINS` and |
| `PLAT_MAX_PWR_LVL` which replace the macros `PLAT_NUM_AFFS` and |
| `PLATFORM_MAX_AFFLVL` respectively. On platforms where the affinity instances |
| correspond to power domains, the values of new macros remain the same as the |
| old ones. |
| |
| More details on the power domain topology description and its platform |
| interface can be found in [psci pd tree]. |
| |
| |
| 2.2 Composite power state framework platform API modifications |
| -------------------------------------------------------------- |
| |
| The state-ID field in the power-state parameter of a CPU_SUSPEND call can be |
| used to describe the composite power states specific to a platform. The existing |
| PSCI state coordination had the limitation that it operates on a run/off |
| granularity of power states and it did not interpret the state-ID field. This |
| was acceptable as the specification requirement in PSCI 0.2 and the framework's |
| approach to coordination only required maintaining a reference |
| count of the number of cores that have requested the cluster to remain powered. |
| |
| In the PSCI 1.0 specification, this approach is non optimal. If composite |
| power states are used, the PSCI implementation cannot make global |
| decisions about state coordination required because it does not understand the |
| platform specific states. |
| |
| The PSCI 1.0 implementation now defines a generic representation of the |
| power-state parameter : |
| |
| typedef struct psci_power_state { |
| plat_local_state_t pwr_domain_state[PLAT_MAX_PWR_LVL + 1]; |
| } psci_power_state_t; |
| |
| |
| `pwr_domain_state` is an array where each index corresponds to a power level. |
| Each entry in the array contains the local power state the power domain at |
| that power level could enter. The meaning of the local power state value is |
| platform defined, and can vary between levels in a single platform. The PSCI |
| implementation constraints the values only so that it can classify the state |
| as RUN, RETENTION or OFF as required by the specification: |
| |
| 1. Zero means RUN |
| |
| 2. All OFF state values at all levels must be higher than all |
| RETENTION state values at all levels |
| |
| The platform is required to define the macros `PLAT_MAX_RET_STATE` and |
| `PLAT_MAX_OFF_STATE` to the framework. The requirement for these macros can |
| be found in the [Porting Guide]. |
| |
| The PSCI 1.0 implementation adds support to involve the platform in state |
| coordination. This enables the platform to decide the final target state. |
| During a request to place a power domain in a low power state, the platform |
| is passed an array of requested `plat_local_state_t` for that power domain by |
| each core within it through the `plat_get_target_pwr_state()` API. This API |
| coordinates amongst these requested states to determine a target |
| `plat_local_state_t` for that power domain. A default weak implementation of |
| this API is provided in the platform layer which returns the minimum of the |
| requested local states back to the PSCI state coordination. More details |
| of `plat_get_target_pwr_state()` API can be found in the |
| [Porting Guide][get_target_pwr_state]. |
| |
| The PSCI Generic implementation expects platform ports to populate the handlers |
| for the `plat_psci_ops` structure which is declared as : |
| |
| typedef struct plat_psci_ops { |
| void (*cpu_standby)(plat_local_state_t cpu_state); |
| int (*pwr_domain_on)(u_register_t mpidr); |
| void (*pwr_domain_off)(const psci_power_state_t *target_state); |
| void (*pwr_domain_suspend)(const psci_power_state_t *target_state); |
| void (*pwr_domain_on_finish)(const psci_power_state_t *target_state); |
| void (*pwr_domain_suspend_finish)( |
| const psci_power_state_t *target_state); |
| void (*system_off)(void) __dead2; |
| void (*system_reset)(void) __dead2; |
| int (*validate_power_state)(unsigned int power_state, |
| psci_power_state_t *req_state); |
| int (*validate_ns_entrypoint)(unsigned long ns_entrypoint); |
| void (*get_sys_suspend_power_state)( |
| psci_power_state_t *req_state); |
| } plat_psci_ops_t; |
| |
| The description of these handlers can be found in the [Porting Guide][psci_ops]. |
| The previous `plat_pm_ops` structure is deprecated. Compared with the previous |
| handlers, the major differences are: |
| |
| * Difference in parameters |
| |
| The PSCI 1.0 implementation depends on the `validate_power_state` handler to |
| convert the power-state parameter (possibly encoding a composite power state) |
| passed in a PSCI `CPU_SUSPEND` to the `psci_power_state` format. This handler |
| is now mandatory for PSCI `CPU_SUSPEND` support. |
| |
| The `plat_psci_ops` handlers, `pwr_domain_off` and `pwr_domain_suspend`, are |
| passed the target local state for each affected power domain. The platform |
| must execute operations specific to these target states. Similarly, |
| `pwr_domain_on_finish` and `pwr_domain_suspend_finish` are passed the local |
| states of the affected power domains before wakeup. The platform |
| must execute actions to restore these power domains from these specific |
| local states. |
| |
| * Difference in invocation |
| |
| Whereas the power management handlers in `plat_pm_ops` used to be invoked |
| for each affinity level till the target affinity level, the new handlers |
| are only invoked once. The `target_state` encodes the target low power |
| state or the low power state woken up from for each affected power domain. |
| |
| * Difference in semantics |
| |
| Although the previous `suspend` handlers could be used for power down as well |
| as retention at different affinity levels, the new handlers make this support |
| explicit. The `pwr_domain_suspend` can be used to specify powerdown and |
| retention at various power domain levels subject to the conditions mentioned |
| in section 4.2.1 of [PSCI] |
| |
| Unlike the previous `standby` handler, the `cpu_standby()` handler is only used |
| as a fast path for placing a core power domain into a standby or retention |
| state. |
| |
| The below diagram shows the sequence of a PSCI SUSPEND call and the interaction |
| with the platform layer depicting the exchange of data between PSCI Generic |
| layer and the platform layer. |
| |
| ![Image 1](diagrams/psci-suspend-sequence.png?raw=true) |
| |
| Refer [plat/arm/board/fvp/fvp_pm.c] for the implementation details of |
| these handlers for the FVP. The commit 38dce70f51fb83b27958ba3e2ad15f5635cb1061 |
| demonstrates the migration of ARM reference platforms to the new platform API. |
| |
| |
| 2.3 Miscellaneous modifications |
| ------------------------------- |
| |
| In addition to the framework changes, unification of warm reset entry points on |
| wakeup from low power modes has led to a change in the platform API. In the |
| earlier implementation, the warm reset entry used to be programmed into the |
| mailboxes by the 'ON' and 'SUSPEND' power management hooks. In the PSCI 1.0 |
| implementation, this information is not required, because it can figure that |
| out by querying affinity info state whether to execute the 'suspend_finisher` |
| or 'on_finisher'. |
| |
| As a result, the warm reset entry point must be programmed only once. The |
| `plat_setup_psci_ops()` API takes the secure entry point as an |
| additional parameter to enable the platforms to configure their mailbox. The |
| plat_psci_ops handlers `pwr_domain_on` and `pwr_domain_suspend` no longer take |
| the warm reset entry point as a parameter. |
| |
| Also, some platform APIs which took `MPIDR` as an argument were only ever |
| invoked to perform actions specific to the caller core which makes the argument |
| redundant. Therefore the platform APIs `plat_get_my_entrypoint()`, |
| `plat_is_my_cpu_primary()`, `plat_set_my_stack()` and |
| `plat_get_my_stack()` are defined which are meant to be invoked only for |
| operations on the current caller core instead of `platform_get_entrypoint()`, |
| `platform_is_primary_cpu()`, `platform_set_stack()` and `platform_get_stack()`. |
| |
| |
| 3. Compatibility layer |
| ---------------------- |
| |
| To ease the migration of the platform ports to the new porting interface, |
| a compatibility layer is introduced that essentially implements a glue layer |
| between the old platform API and the new API. The build flag |
| `ENABLE_PLAT_COMPAT` (enabled by default), specifies whether to enable this |
| layer or not. A platform port which has migrated to the new API can disable |
| this flag within the platform specific makefile. |
| |
| The compatibility layer works on the assumption that the onus of |
| state coordination, in case multiple low power states are supported, |
| is with the platform. The generic PSCI implementation only takes into |
| account whether the suspend request is power down or not. This corresponds |
| with the behavior of the PSCI implementation before the introduction of |
| new frameworks. Also, it assumes that the affinity levels of the platform |
| correspond directly to the power domain levels. |
| |
| The compatibility layer dynamically constructs the new topology |
| description array by querying the platform using `plat_get_aff_count()` |
| and `plat_get_aff_state()` APIs. The linear index returned by |
| `platform_get_core_pos()` is used as the core index for the cores. The |
| higher level (non-core) power domain nodes must know the cores contained |
| within its domain. It does so by storing the core index of first core |
| within it and number of core indexes following it. This means that core |
| indices returned by `platform_get_core_pos()` for cores within a particular |
| power domain must be consecutive. We expect that this is the case for most |
| platform ports including ARM reference platforms. |
| |
| The old PSCI helpers like `psci_get_suspend_powerstate()`, |
| `psci_get_suspend_stateid()`, `psci_get_suspend_stateid_by_mpidr()`, |
| `psci_get_max_phys_off_afflvl()` and `psci_get_suspend_afflvl()` are also |
| implemented for the compatibility layer. This allows the existing |
| platform ports to work with the new PSCI frameworks without significant |
| rework. |
| |
| |
| 4. Deprecated Platform API |
| --------------------------- |
| |
| This section documents the deprecated platform porting API. |
| |
| ## Common mandatory modifications |
| |
| The mandatory macros to be defined by the platform port in `platform_def.h` |
| |
| * **#define : PLATFORM_NUM_AFFS** |
| |
| Defines the total number of nodes in the affinity hierarchy at all affinity |
| levels used by the platform. |
| |
| * **#define : PLATFORM_MAX_AFFLVL** |
| |
| Defines the maximum affinity level that the power management operations |
| should apply to. ARMv8-A has support for four affinity levels. It is likely |
| that hardware will implement fewer affinity levels. This macro allows the |
| PSCI implementation to consider only those affinity levels in the system |
| that the platform implements. For example, the Base AEM FVP implements two |
| clusters with a configurable number of cores. It reports the maximum |
| affinity level as 1, resulting in PSCI power control up to the cluster |
| level. |
| |
| The following functions must be implemented by the platform port to enable |
| the reset vector code to perform the required tasks. |
| |
| ### Function : platform_get_entrypoint() [mandatory] |
| |
| Argument : unsigned long |
| Return : unsigned long |
| |
| This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The core |
| is identified by its `MPIDR`, which is passed as the argument. The function is |
| responsible for distinguishing between a warm and cold reset using platform- |
| specific means. If it is a warm reset, it returns the entrypoint into the |
| BL31 image that the core must jump to. If it is a cold reset, this function |
| must return zero. |
| |
| This function is also responsible for implementing a platform-specific mechanism |
| to handle the condition where the core has been warm reset but there is no |
| entrypoint to jump to. |
| |
| This function does not follow the Procedure Call Standard used by the |
| Application Binary Interface for the ARM 64-bit architecture. The caller should |
| not assume that callee saved registers are preserved across a call to this |
| function. |
| |
| ### Function : platform_is_primary_cpu() [mandatory] |
| |
| Argument : unsigned long |
| Return : unsigned int |
| |
| This function identifies a core by its `MPIDR`, which is passed as the argument, |
| to determine whether this core is the primary core or a secondary core. A return |
| value of zero indicates that the core is not the primary core, while a non-zero |
| return value indicates that the core is the primary core. |
| |
| ## Common optional modifications |
| |
| ### Function : platform_get_core_pos() |
| |
| Argument : unsigned long |
| Return : int |
| |
| A platform may need to convert the `MPIDR` of a core to an absolute number, which |
| can be used as a core-specific linear index into blocks of memory (for example |
| while allocating per-core stacks). This routine contains a simple mechanism |
| to perform this conversion, using the assumption that each cluster contains a |
| maximum of four cores: |
| |
| linear index = cpu_id + (cluster_id * 4) |
| |
| cpu_id = 8-bit value in MPIDR at affinity level 0 |
| cluster_id = 8-bit value in MPIDR at affinity level 1 |
| |
| |
| ### Function : platform_set_stack() |
| |
| Argument : unsigned long |
| Return : void |
| |
| This function sets the current stack pointer to the normal memory stack that |
| has been allocated for the core specified by MPIDR. For BL images that only |
| require a stack for the primary core the parameter is ignored. The size of |
| the stack allocated to each core is specified by the platform defined constant |
| `PLATFORM_STACK_SIZE`. |
| |
| Common implementations of this function for the UP and MP BL images are |
| provided in [plat/common/aarch64/platform_up_stack.S] and |
| [plat/common/aarch64/platform_mp_stack.S] |
| |
| |
| ### Function : platform_get_stack() |
| |
| Argument : unsigned long |
| Return : unsigned long |
| |
| This function returns the base address of the normal memory stack that |
| has been allocated for the core specificed by MPIDR. For BL images that only |
| require a stack for the primary core the parameter is ignored. The size of |
| the stack allocated to each core is specified by the platform defined constant |
| `PLATFORM_STACK_SIZE`. |
| |
| Common implementations of this function for the UP and MP BL images are |
| provided in [plat/common/aarch64/platform_up_stack.S] and |
| [plat/common/aarch64/platform_mp_stack.S] |
| |
| |
| ## Modifications for Power State Coordination Interface (in BL31) |
| |
| The following functions must be implemented to initialize PSCI functionality in |
| the ARM Trusted Firmware. |
| |
| |
| ### Function : plat_get_aff_count() [mandatory] |
| |
| Argument : unsigned int, unsigned long |
| Return : unsigned int |
| |
| This function may execute with the MMU and data caches enabled if the platform |
| port does the necessary initializations in `bl31_plat_arch_setup()`. It is only |
| called by the primary core. |
| |
| This function is called by the PSCI initialization code to detect the system |
| topology. Its purpose is to return the number of affinity instances implemented |
| at a given `affinity level` (specified by the first argument) and a given |
| `MPIDR` (specified by the second argument). For example, on a dual-cluster |
| system where first cluster implements two cores and the second cluster |
| implements four cores, a call to this function with an `MPIDR` corresponding |
| to the first cluster (`0x0`) and affinity level 0, would return 2. A call |
| to this function with an `MPIDR` corresponding to the second cluster (`0x100`) |
| and affinity level 0, would return 4. |
| |
| |
| ### Function : plat_get_aff_state() [mandatory] |
| |
| Argument : unsigned int, unsigned long |
| Return : unsigned int |
| |
| This function may execute with the MMU and data caches enabled if the platform |
| port does the necessary initializations in `bl31_plat_arch_setup()`. It is only |
| called by the primary core. |
| |
| This function is called by the PSCI initialization code. Its purpose is to |
| return the state of an affinity instance. The affinity instance is determined by |
| the affinity ID at a given `affinity level` (specified by the first argument) |
| and an `MPIDR` (specified by the second argument). The state can be one of |
| `PSCI_AFF_PRESENT` or `PSCI_AFF_ABSENT`. The latter state is used to cater for |
| system topologies where certain affinity instances are unimplemented. For |
| example, consider a platform that implements a single cluster with four cores and |
| another core implemented directly on the interconnect with the cluster. The |
| `MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single |
| core is 0x100 to indicate that it does not belong to cluster 0. Cluster 1 |
| is missing but needs to be accounted for to reach this single core in the |
| topology tree. Therefore it is marked as `PSCI_AFF_ABSENT`. |
| |
| |
| ### Function : platform_setup_pm() [mandatory] |
| |
| Argument : const plat_pm_ops ** |
| Return : int |
| |
| This function may execute with the MMU and data caches enabled if the platform |
| port does the necessary initializations in `bl31_plat_arch_setup()`. It is only |
| called by the primary core. |
| |
| This function is called by PSCI initialization code. Its purpose is to export |
| handler routines for platform-specific power management actions by populating |
| the passed pointer with a pointer to the private `plat_pm_ops` structure of |
| BL31. |
| |
| A description of each member of this structure is given below. A platform port |
| is expected to implement these handlers if the corresponding PSCI operation |
| is to be supported and these handlers are expected to succeed if the return |
| type is `void`. |
| |
| #### plat_pm_ops.affinst_standby() |
| |
| Perform the platform-specific setup to enter the standby state indicated by the |
| passed argument. The generic code expects the handler to succeed. |
| |
| #### plat_pm_ops.affinst_on() |
| |
| Perform the platform specific setup to power on an affinity instance, specified |
| by the `MPIDR` (first argument) and `affinity level` (third argument). The |
| `state` (fourth argument) contains the current state of that affinity instance |
| (ON or OFF). This is useful to determine whether any action must be taken. For |
| example, while powering on a core, the cluster that contains this core might |
| already be in the ON state. The platform decides what actions must be taken to |
| transition from the current state to the target state (indicated by the power |
| management operation). The generic code expects the platform to return |
| E_SUCCESS on success or E_INTERN_FAIL for any failure. |
| |
| #### plat_pm_ops.affinst_off() |
| |
| Perform the platform specific setup to power off an affinity instance of the |
| calling core. It is called by the PSCI `CPU_OFF` API implementation. |
| |
| The `affinity level` (first argument) and `state` (second argument) have |
| a similar meaning as described in the `affinst_on()` operation. They |
| identify the affinity instance on which the call is made and its |
| current state. This gives the platform port an indication of the |
| state transition it must make to perform the requested action. For example, if |
| the calling core is the last powered on core in the cluster, after powering down |
| affinity level 0 (the core), the platform port should power down affinity |
| level 1 (the cluster) as well. The generic code expects the handler to succeed. |
| |
| #### plat_pm_ops.affinst_suspend() |
| |
| Perform the platform specific setup to power off an affinity instance of the |
| calling core. It is called by the PSCI `CPU_SUSPEND` API and `SYSTEM_SUSPEND` |
| API implementation |
| |
| The `affinity level` (second argument) and `state` (third argument) have a |
| similar meaning as described in the `affinst_on()` operation. They are used to |
| identify the affinity instance on which the call is made and its current state. |
| This gives the platform port an indication of the state transition it must |
| make to perform the requested action. For example, if the calling core is the |
| last powered on core in the cluster, after powering down affinity level 0 |
| (the core), the platform port should power down affinity level 1 (the cluster) |
| as well. |
| |
| The difference between turning an affinity instance off and suspending it |
| is that in the former case, the affinity instance is expected to re-initialize |
| its state when it is next powered on (see `affinst_on_finish()`). In the latter |
| case, the affinity instance is expected to save enough state so that it can |
| resume execution by restoring this state when it is powered on (see |
| `affinst_suspend_finish()`).The generic code expects the handler to succeed. |
| |
| #### plat_pm_ops.affinst_on_finish() |
| |
| This function is called by the PSCI implementation after the calling core is |
| powered on and released from reset in response to an earlier PSCI `CPU_ON` call. |
| It performs the platform-specific setup required to initialize enough state for |
| this core to enter the Normal world and also provide secure runtime firmware |
| services. |
| |
| The `affinity level` (first argument) and `state` (second argument) have a |
| similar meaning as described in the previous operations. The generic code |
| expects the handler to succeed. |
| |
| #### plat_pm_ops.affinst_suspend_finish() |
| |
| This function is called by the PSCI implementation after the calling core is |
| powered on and released from reset in response to an asynchronous wakeup |
| event, for example a timer interrupt that was programmed by the core during the |
| `CPU_SUSPEND` call or `SYSTEM_SUSPEND` call. It performs the platform-specific |
| setup required to restore the saved state for this core to resume execution |
| in the Normal world and also provide secure runtime firmware services. |
| |
| The `affinity level` (first argument) and `state` (second argument) have a |
| similar meaning as described in the previous operations. The generic code |
| expects the platform to succeed. |
| |
| #### plat_pm_ops.validate_power_state() |
| |
| This function is called by the PSCI implementation during the `CPU_SUSPEND` |
| call to validate the `power_state` parameter of the PSCI API. If the |
| `power_state` is known to be invalid, the platform must return |
| PSCI_E_INVALID_PARAMS as an error, which is propagated back to the Normal |
| world PSCI client. |
| |
| #### plat_pm_ops.validate_ns_entrypoint() |
| |
| This function is called by the PSCI implementation during the `CPU_SUSPEND`, |
| `SYSTEM_SUSPEND` and `CPU_ON` calls to validate the Non-secure `entry_point` |
| parameter passed by the Normal world. If the `entry_point` is known to be |
| invalid, the platform must return PSCI_E_INVALID_PARAMS as an error, which is |
| propagated back to the Normal world PSCI client. |
| |
| #### plat_pm_ops.get_sys_suspend_power_state() |
| |
| This function is called by the PSCI implementation during the `SYSTEM_SUSPEND` |
| call to return the `power_state` parameter. This allows the platform to encode |
| the appropriate State-ID field within the `power_state` parameter which can be |
| utilized in `affinst_suspend()` to suspend to system affinity level. The |
| `power_state` parameter should be in the same format as specified by the |
| PSCI specification for the CPU_SUSPEND API. |
| |
| - - - - - - - - - - - - - - - - - - - - - - - - - - |
| |
| _Copyright (c) 2015, ARM Limited and Contributors. All rights reserved._ |
| |
| |
| [Porting Guide]: porting-guide.md |
| [Power Domain Topology Design]: psci-pd-tree.md |
| [PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf |
| [psci pd tree]: psci-pd-tree.md |
| [my_core_pos]: porting-guide.md#function--plat_my_core_pos |
| [get_target_pwr_state]: porting-guide.md#function--plat_get_target_pwr_state-optional |
| [psci_ops]: porting-guide.md#function--plat_setup_psci_ops-mandatory |
| [plat/arm/board/fvp/fvp_pm.c]: ../plat/arm/board/fvp/fvp_pm.c |
| [plat/common/aarch64/platform_mp_stack.S]: ../plat/common/aarch64/platform_mp_stack.S |
| [plat/common/aarch64/platform_up_stack.S]: ../plat/common/aarch64/platform_up_stack.S |