summaryrefslogtreecommitdiff
path: root/docs/platform-migration-guide.md
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2015-06-08 12:32:50 +0100
committerAchin Gupta <achin.gupta@arm.com>2015-08-13 23:48:07 +0100
commit58523c076a4bd766fccd207c493cf1b918fda9db (patch)
tree1b929799f1a48c5bd5415b78a765bfe77c719cfd /docs/platform-migration-guide.md
parentf9e858b1f7b27d8e0b89cc7e12e7a90755d0dd00 (diff)
PSCI: Add documentation and fix plat_is_my_cpu_primary()
This patch adds the necessary documentation updates to porting_guide.md for the changes in the platform interface mandated as a result of the new PSCI Topology and power state management frameworks. It also adds a new document `platform-migration-guide.md` to aid the migration of existing platform ports to the new API. The patch fixes the implementation and callers of plat_is_my_cpu_primary() to use w0 as the return parameter as implied by the function signature rather than x0 which was used previously. Change-Id: Ic11e73019188c8ba2bd64c47e1729ff5acdcdd5b
Diffstat (limited to 'docs/platform-migration-guide.md')
-rw-r--r--docs/platform-migration-guide.md574
1 files changed, 574 insertions, 0 deletions
diff --git a/docs/platform-migration-guide.md b/docs/platform-migration-guide.md
new file mode 100644
index 00000000..806fa19d
--- /dev/null
+++ b/docs/platform-migration-guide.md
@@ -0,0 +1,574 @@
+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_count()` 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. The framework's
+approach to coordination only requires 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.
+
+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 b6df6ccbc88cc14592f5e603ef580d3cbf4733c3
+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_count()` 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
+BL3-1 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 BL3-1)
+
+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
+BL3-1.
+
+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