blob: 5e8eeba18c7902d6d65b0df83b5b4b22005b75a6 [file] [log] [blame]
Douglas Raillardd7c21b72017-06-28 15:23:03 +01001Guide to migrate to new Platform porting interface
2==================================================
3
4
5.. section-numbering::
6 :suffix: .
7
8.. contents::
9
10--------------
11
12Introduction
13------------
14
15The PSCI implementation in Trusted Firmware has undergone a redesign because of
16three requirements that the PSCI 1.0 specification introduced :
17
18- Removing the framework assumption about the structure of the MPIDR, and
19 its relation to the power topology enables support for deeper and more
20 complex hierarchies.
21
22- Reworking the power state coordination implementation in the framework
23 to support the more detailed PSCI 1.0 requirements and reduce platform
24 port complexity
25
26- Enable the use of the extended power\_state parameter and the larger StateID
27 field
28
29The PSCI 1.0 implementation introduces new frameworks to fulfill the above
30requirements. These framework changes mean that the platform porting API must
31also be modified. This document is a guide to assist migration of the existing
32platform ports to the new platform API.
33
34This document describes the new platform API and compares it with the
35deprecated API. It also describes the compatibility layer that enables the
36existing platform ports to work with the PSCI 1.0 implementation. The
37deprecated platform API is documented for reference.
38
39Platform API modification due to PSCI framework changes
40-------------------------------------------------------
41
42This section describes changes to the platform APIs.
43
44Power domain topology framework platform API modifications
45----------------------------------------------------------
46
47This removes the assumption in the PSCI implementation that MPIDR
48based affinity instances map directly to power domains. A power domain, as
49described in section 4.2 of `PSCI`_, could contain a core or a logical group
50of cores (a cluster) which share some state on which power management
51operations can be performed. The existing affinity instance based APIs
52``plat_get_aff_count()`` and ``plat_get_aff_state()`` are deprecated. The new
53platform interfaces that are introduced for this framework are:
54
55- ``plat_core_pos_by_mpidr()``
56- ``plat_my_core_pos()``
57- ``plat_get_power_domain_tree_desc()``
58
59``plat_my_core_pos()`` and ``plat_core_pos_by_mpidr()`` are mandatory
60and are meant to replace the existing ``platform_get_core_pos()`` API.
61The description of these APIs can be found in the `Porting Guide`_.
62These are used by the power domain topology framework such that:
63
64#. The generic PSCI code does not generate MPIDRs or use them to query the
65 platform about the number of power domains at a particular power level. The
66 ``plat_get_power_domain_tree_desc()`` provides a description of the power
67 domain tree on the SoC through a pointer to the byte array containing the
68 power domain topology tree description data structure.
69
70#. The linear indices returned by ``plat_core_pos_by_mpidr()`` and
71 ``plat_my_core_pos()`` are used to retrieve core power domain nodes from
72 the power domain tree. These core indices are unique for a core and it is a
73 number between ``0`` and ``PLATFORM_CORE_COUNT - 1``. The platform can choose
74 to implement a static mapping between ``MPIDR`` and core index or implement
75 a dynamic mapping, choosing to skip the unavailable/unused cores to compact
76 the core indices.
77
78In addition, the platforms must define the macros ``PLAT_NUM_PWR_DOMAINS`` and
79``PLAT_MAX_PWR_LVL`` which replace the macros ``PLAT_NUM_AFFS`` and
80``PLATFORM_MAX_AFFLVL`` respectively. On platforms where the affinity instances
81correspond to power domains, the values of new macros remain the same as the
82old ones.
83
84More details on the power domain topology description and its platform
85interface can be found in `psci pd tree`_.
86
87Composite power state framework platform API modifications
88----------------------------------------------------------
89
90The state-ID field in the power-state parameter of a CPU\_SUSPEND call can be
91used to describe the composite power states specific to a platform. The existing
92PSCI state coordination had the limitation that it operates on a run/off
93granularity of power states and it did not interpret the state-ID field. This
94was acceptable as the specification requirement in PSCI 0.2 and the framework's
95approach to coordination only required maintaining a reference
96count of the number of cores that have requested the cluster to remain powered.
97
98In the PSCI 1.0 specification, this approach is non optimal. If composite
99power states are used, the PSCI implementation cannot make global
100decisions about state coordination required because it does not understand the
101platform specific states.
102
103The PSCI 1.0 implementation now defines a generic representation of the
104power-state parameter :
105
106.. code:: c
107
108 typedef struct psci_power_state {
109 plat_local_state_t pwr_domain_state[PLAT_MAX_PWR_LVL + 1];
110 } psci_power_state_t;
111
112``pwr_domain_state`` is an array where each index corresponds to a power level.
113Each entry in the array contains the local power state the power domain at
114that power level could enter. The meaning of the local power state value is
115platform defined, and can vary between levels in a single platform. The PSCI
116implementation constraints the values only so that it can classify the state
117as RUN, RETENTION or OFF as required by the specification:
118
119#. Zero means RUN
120
121#. All OFF state values at all levels must be higher than all
122 RETENTION state values at all levels
123
124The platform is required to define the macros ``PLAT_MAX_RET_STATE`` and
125``PLAT_MAX_OFF_STATE`` to the framework. The requirement for these macros can
126be found in the `Porting Guide <porting-guide.rst>`__.
127
128The PSCI 1.0 implementation adds support to involve the platform in state
129coordination. This enables the platform to decide the final target state.
130During a request to place a power domain in a low power state, the platform
131is passed an array of requested ``plat_local_state_t`` for that power domain by
132each core within it through the ``plat_get_target_pwr_state()`` API. This API
133coordinates amongst these requested states to determine a target
134``plat_local_state_t`` for that power domain. A default weak implementation of
135this API is provided in the platform layer which returns the minimum of the
136requested local states back to the PSCI state coordination. More details
137of ``plat_get_target_pwr_state()`` API can be found in the
138`Porting Guide <porting-guide.rst#user-content-function--plat_get_target_pwr_state-optional>`__.
139
140The PSCI Generic implementation expects platform ports to populate the handlers
141for the ``plat_psci_ops`` structure which is declared as :
142
143.. code:: c
144
145 typedef struct plat_psci_ops {
146 void (*cpu_standby)(plat_local_state_t cpu_state);
147 int (*pwr_domain_on)(u_register_t mpidr);
148 void (*pwr_domain_off)(const psci_power_state_t *target_state);
149 void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
150 void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
151 void (*pwr_domain_suspend_finish)(
152 const psci_power_state_t *target_state);
153 void (*system_off)(void) __dead2;
154 void (*system_reset)(void) __dead2;
155 int (*validate_power_state)(unsigned int power_state,
156 psci_power_state_t *req_state);
157 int (*validate_ns_entrypoint)(unsigned long ns_entrypoint);
158 void (*get_sys_suspend_power_state)(
159 psci_power_state_t *req_state);
160 } plat_psci_ops_t;
161
162The description of these handlers can be found in the `Porting Guide <porting-guide.rst#user-content-function--plat_setup_psci_ops-mandatory>`__.
163The previous ``plat_pm_ops`` structure is deprecated. Compared with the previous
164handlers, the major differences are:
165
166- Difference in parameters
167
168The PSCI 1.0 implementation depends on the ``validate_power_state`` handler to
169convert the power-state parameter (possibly encoding a composite power state)
170passed in a PSCI ``CPU_SUSPEND`` to the ``psci_power_state`` format. This handler
171is now mandatory for PSCI ``CPU_SUSPEND`` support.
172
173The ``plat_psci_ops`` handlers, ``pwr_domain_off`` and ``pwr_domain_suspend``, are
174passed the target local state for each affected power domain. The platform
175must execute operations specific to these target states. Similarly,
176``pwr_domain_on_finish`` and ``pwr_domain_suspend_finish`` are passed the local
177states of the affected power domains before wakeup. The platform
178must execute actions to restore these power domains from these specific
179local states.
180
181- Difference in invocation
182
183Whereas the power management handlers in ``plat_pm_ops`` used to be invoked
184for each affinity level till the target affinity level, the new handlers
185are only invoked once. The ``target_state`` encodes the target low power
186state or the low power state woken up from for each affected power domain.
187
188- Difference in semantics
189
190Although the previous ``suspend`` handlers could be used for power down as well
191as retention at different affinity levels, the new handlers make this support
192explicit. The ``pwr_domain_suspend`` can be used to specify powerdown and
193retention at various power domain levels subject to the conditions mentioned
194in section 4.2.1 of `PSCI`_
195
196Unlike the previous ``standby`` handler, the ``cpu_standby()`` handler is only used
197as a fast path for placing a core power domain into a standby or retention
198state.
199
200The below diagram shows the sequence of a PSCI SUSPEND call and the interaction
201with the platform layer depicting the exchange of data between PSCI Generic
202layer and the platform layer.
203
204|Image 1|
205
206Refer `plat/arm/board/fvp/fvp\_pm.c`_ for the implementation details of
207these handlers for the FVP. The commit `38dce70f51fb83b27958ba3e2ad15f5635cb1061`_
208demonstrates the migration of ARM reference platforms to the new platform API.
209
210Miscellaneous modifications
211---------------------------
212
213In addition to the framework changes, unification of warm reset entry points on
214wakeup from low power modes has led to a change in the platform API. In the
215earlier implementation, the warm reset entry used to be programmed into the
216mailboxes by the 'ON' and 'SUSPEND' power management hooks. In the PSCI 1.0
217implementation, this information is not required, because it can figure that
218out by querying affinity info state whether to execute the 'suspend\_finisher\`
219or 'on\_finisher'.
220
221As a result, the warm reset entry point must be programmed only once. The
222``plat_setup_psci_ops()`` API takes the secure entry point as an
223additional parameter to enable the platforms to configure their mailbox. The
224plat\_psci\_ops handlers ``pwr_domain_on`` and ``pwr_domain_suspend`` no longer take
225the warm reset entry point as a parameter.
226
227Also, some platform APIs which took ``MPIDR`` as an argument were only ever
228invoked to perform actions specific to the caller core which makes the argument
229redundant. Therefore the platform APIs ``plat_get_my_entrypoint()``,
230``plat_is_my_cpu_primary()``, ``plat_set_my_stack()`` and
231``plat_get_my_stack()`` are defined which are meant to be invoked only for
232operations on the current caller core instead of ``platform_get_entrypoint()``,
233``platform_is_primary_cpu()``, ``platform_set_stack()`` and ``platform_get_stack()``.
234
235Compatibility layer
236-------------------
237
238To ease the migration of the platform ports to the new porting interface,
239a compatibility layer is introduced that essentially implements a glue layer
240between the old platform API and the new API. The build flag
241``ENABLE_PLAT_COMPAT`` (enabled by default), specifies whether to enable this
242layer or not. A platform port which has migrated to the new API can disable
243this flag within the platform specific makefile.
244
245The compatibility layer works on the assumption that the onus of
246state coordination, in case multiple low power states are supported,
247is with the platform. The generic PSCI implementation only takes into
248account whether the suspend request is power down or not. This corresponds
249with the behavior of the PSCI implementation before the introduction of
250new frameworks. Also, it assumes that the affinity levels of the platform
251correspond directly to the power domain levels.
252
253The compatibility layer dynamically constructs the new topology
254description array by querying the platform using ``plat_get_aff_count()``
255and ``plat_get_aff_state()`` APIs. The linear index returned by
256``platform_get_core_pos()`` is used as the core index for the cores. The
257higher level (non-core) power domain nodes must know the cores contained
258within its domain. It does so by storing the core index of first core
259within it and number of core indexes following it. This means that core
260indices returned by ``platform_get_core_pos()`` for cores within a particular
261power domain must be consecutive. We expect that this is the case for most
262platform ports including ARM reference platforms.
263
264The old PSCI helpers like ``psci_get_suspend_powerstate()``,
265``psci_get_suspend_stateid()``, ``psci_get_suspend_stateid_by_mpidr()``,
266``psci_get_max_phys_off_afflvl()`` and ``psci_get_suspend_afflvl()`` are also
267implemented for the compatibility layer. This allows the existing
268platform ports to work with the new PSCI frameworks without significant
269rework.
270
271Deprecated Platform API
272-----------------------
273
274This section documents the deprecated platform porting API.
275
276Common mandatory modifications
277------------------------------
278
279The mandatory macros to be defined by the platform port in ``platform_def.h``
280
281- **#define : PLATFORM\_NUM\_AFFS**
282
283 Defines the total number of nodes in the affinity hierarchy at all affinity
284 levels used by the platform.
285
286- **#define : PLATFORM\_MAX\_AFFLVL**
287
288 Defines the maximum affinity level that the power management operations
289 should apply to. ARMv8-A has support for four affinity levels. It is likely
290 that hardware will implement fewer affinity levels. This macro allows the
291 PSCI implementation to consider only those affinity levels in the system
292 that the platform implements. For example, the Base AEM FVP implements two
293 clusters with a configurable number of cores. It reports the maximum
294 affinity level as 1, resulting in PSCI power control up to the cluster
295 level.
296
297The following functions must be implemented by the platform port to enable
298the reset vector code to perform the required tasks.
299
300Function : platform\_get\_entrypoint() [mandatory]
301~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
302
303::
304
305 Argument : unsigned long
306 Return : unsigned long
307
308This function is called with the ``SCTLR.M`` and ``SCTLR.C`` bits disabled. The core
309is identified by its ``MPIDR``, which is passed as the argument. The function is
310responsible for distinguishing between a warm and cold reset using platform-
311specific means. If it is a warm reset, it returns the entrypoint into the
312BL31 image that the core must jump to. If it is a cold reset, this function
313must return zero.
314
315This function is also responsible for implementing a platform-specific mechanism
316to handle the condition where the core has been warm reset but there is no
317entrypoint to jump to.
318
319This function does not follow the Procedure Call Standard used by the
320Application Binary Interface for the ARM 64-bit architecture. The caller should
321not assume that callee saved registers are preserved across a call to this
322function.
323
324Function : platform\_is\_primary\_cpu() [mandatory]
325~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
326
327::
328
329 Argument : unsigned long
330 Return : unsigned int
331
332This function identifies a core by its ``MPIDR``, which is passed as the argument,
333to determine whether this core is the primary core or a secondary core. A return
334value of zero indicates that the core is not the primary core, while a non-zero
335return value indicates that the core is the primary core.
336
337Common optional modifications
338-----------------------------
339
340Function : platform\_get\_core\_pos()
341~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
342
343::
344
345 Argument : unsigned long
346 Return : int
347
348A platform may need to convert the ``MPIDR`` of a core to an absolute number, which
349can be used as a core-specific linear index into blocks of memory (for example
350while allocating per-core stacks). This routine contains a simple mechanism
351to perform this conversion, using the assumption that each cluster contains a
352maximum of four cores:
353
354::
355
356 linear index = cpu_id + (cluster_id * 4)
357
358 cpu_id = 8-bit value in MPIDR at affinity level 0
359 cluster_id = 8-bit value in MPIDR at affinity level 1
360
361Function : platform\_set\_stack()
362~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
363
364::
365
366 Argument : unsigned long
367 Return : void
368
369This function sets the current stack pointer to the normal memory stack that
370has been allocated for the core specified by MPIDR. For BL images that only
371require a stack for the primary core the parameter is ignored. The size of
372the stack allocated to each core is specified by the platform defined constant
373``PLATFORM_STACK_SIZE``.
374
375Common implementations of this function for the UP and MP BL images are
376provided in `plat/common/aarch64/platform\_up\_stack.S`_ and
377`plat/common/aarch64/platform\_mp\_stack.S`_
378
379Function : platform\_get\_stack()
380~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
381
382::
383
384 Argument : unsigned long
385 Return : unsigned long
386
387This function returns the base address of the normal memory stack that
388has been allocated for the core specificed by MPIDR. For BL images that only
389require a stack for the primary core the parameter is ignored. The size of
390the stack allocated to each core is specified by the platform defined constant
391``PLATFORM_STACK_SIZE``.
392
393Common implementations of this function for the UP and MP BL images are
394provided in `plat/common/aarch64/platform\_up\_stack.S`_ and
395`plat/common/aarch64/platform\_mp\_stack.S`_
396
397Modifications for Power State Coordination Interface (in BL31)
398--------------------------------------------------------------
399
400The following functions must be implemented to initialize PSCI functionality in
401the ARM Trusted Firmware.
402
403Function : plat\_get\_aff\_count() [mandatory]
404~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
405
406::
407
408 Argument : unsigned int, unsigned long
409 Return : unsigned int
410
411This function may execute with the MMU and data caches enabled if the platform
412port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only
413called by the primary core.
414
415This function is called by the PSCI initialization code to detect the system
416topology. Its purpose is to return the number of affinity instances implemented
417at a given ``affinity level`` (specified by the first argument) and a given
418``MPIDR`` (specified by the second argument). For example, on a dual-cluster
419system where first cluster implements two cores and the second cluster
420implements four cores, a call to this function with an ``MPIDR`` corresponding
421to the first cluster (``0x0``) and affinity level 0, would return 2. A call
422to this function with an ``MPIDR`` corresponding to the second cluster (``0x100``)
423and affinity level 0, would return 4.
424
425Function : plat\_get\_aff\_state() [mandatory]
426~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
427
428::
429
430 Argument : unsigned int, unsigned long
431 Return : unsigned int
432
433This function may execute with the MMU and data caches enabled if the platform
434port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only
435called by the primary core.
436
437This function is called by the PSCI initialization code. Its purpose is to
438return the state of an affinity instance. The affinity instance is determined by
439the affinity ID at a given ``affinity level`` (specified by the first argument)
440and an ``MPIDR`` (specified by the second argument). The state can be one of
441``PSCI_AFF_PRESENT`` or ``PSCI_AFF_ABSENT``. The latter state is used to cater for
442system topologies where certain affinity instances are unimplemented. For
443example, consider a platform that implements a single cluster with four cores and
444another core implemented directly on the interconnect with the cluster. The
445``MPIDR``\ s of the cluster would range from ``0x0-0x3``. The ``MPIDR`` of the single
446core is 0x100 to indicate that it does not belong to cluster 0. Cluster 1
447is missing but needs to be accounted for to reach this single core in the
448topology tree. Therefore it is marked as ``PSCI_AFF_ABSENT``.
449
450Function : platform\_setup\_pm() [mandatory]
451~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
452
453::
454
455 Argument : const plat_pm_ops **
456 Return : int
457
458This function may execute with the MMU and data caches enabled if the platform
459port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only
460called by the primary core.
461
462This function is called by PSCI initialization code. Its purpose is to export
463handler routines for platform-specific power management actions by populating
464the passed pointer with a pointer to the private ``plat_pm_ops`` structure of
465BL31.
466
467A description of each member of this structure is given below. A platform port
468is expected to implement these handlers if the corresponding PSCI operation
469is to be supported and these handlers are expected to succeed if the return
470type is ``void``.
471
472plat\_pm\_ops.affinst\_standby()
473^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
474
475Perform the platform-specific setup to enter the standby state indicated by the
476passed argument. The generic code expects the handler to succeed.
477
478plat\_pm\_ops.affinst\_on()
479^^^^^^^^^^^^^^^^^^^^^^^^^^^
480
481Perform the platform specific setup to power on an affinity instance, specified
482by the ``MPIDR`` (first argument) and ``affinity level`` (third argument). The
483``state`` (fourth argument) contains the current state of that affinity instance
484(ON or OFF). This is useful to determine whether any action must be taken. For
485example, while powering on a core, the cluster that contains this core might
486already be in the ON state. The platform decides what actions must be taken to
487transition from the current state to the target state (indicated by the power
488management operation). The generic code expects the platform to return
489E\_SUCCESS on success or E\_INTERN\_FAIL for any failure.
490
491plat\_pm\_ops.affinst\_off()
492^^^^^^^^^^^^^^^^^^^^^^^^^^^^
493
494Perform the platform specific setup to power off an affinity instance of the
495calling core. It is called by the PSCI ``CPU_OFF`` API implementation.
496
497The ``affinity level`` (first argument) and ``state`` (second argument) have
498a similar meaning as described in the ``affinst_on()`` operation. They
499identify the affinity instance on which the call is made and its
500current state. This gives the platform port an indication of the
501state transition it must make to perform the requested action. For example, if
502the calling core is the last powered on core in the cluster, after powering down
503affinity level 0 (the core), the platform port should power down affinity
504level 1 (the cluster) as well. The generic code expects the handler to succeed.
505
506plat\_pm\_ops.affinst\_suspend()
507^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
508
509Perform the platform specific setup to power off an affinity instance of the
510calling core. It is called by the PSCI ``CPU_SUSPEND`` API and ``SYSTEM_SUSPEND``
511API implementation
512
513The ``affinity level`` (second argument) and ``state`` (third argument) have a
514similar meaning as described in the ``affinst_on()`` operation. They are used to
515identify the affinity instance on which the call is made and its current state.
516This gives the platform port an indication of the state transition it must
517make to perform the requested action. For example, if the calling core is the
518last powered on core in the cluster, after powering down affinity level 0
519(the core), the platform port should power down affinity level 1 (the cluster)
520as well.
521
522The difference between turning an affinity instance off and suspending it
523is that in the former case, the affinity instance is expected to re-initialize
524its state when it is next powered on (see ``affinst_on_finish()``). In the latter
525case, the affinity instance is expected to save enough state so that it can
526resume execution by restoring this state when it is powered on (see
527``affinst_suspend_finish()``).The generic code expects the handler to succeed.
528
529plat\_pm\_ops.affinst\_on\_finish()
530^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
531
532This function is called by the PSCI implementation after the calling core is
533powered on and released from reset in response to an earlier PSCI ``CPU_ON`` call.
534It performs the platform-specific setup required to initialize enough state for
535this core to enter the Normal world and also provide secure runtime firmware
536services.
537
538The ``affinity level`` (first argument) and ``state`` (second argument) have a
539similar meaning as described in the previous operations. The generic code
540expects the handler to succeed.
541
542plat\_pm\_ops.affinst\_suspend\_finish()
543^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
544
545This function is called by the PSCI implementation after the calling core is
546powered on and released from reset in response to an asynchronous wakeup
547event, for example a timer interrupt that was programmed by the core during the
548``CPU_SUSPEND`` call or ``SYSTEM_SUSPEND`` call. It performs the platform-specific
549setup required to restore the saved state for this core to resume execution
550in the Normal world and also provide secure runtime firmware services.
551
552The ``affinity level`` (first argument) and ``state`` (second argument) have a
553similar meaning as described in the previous operations. The generic code
554expects the platform to succeed.
555
556plat\_pm\_ops.validate\_power\_state()
557^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
558
559This function is called by the PSCI implementation during the ``CPU_SUSPEND``
560call to validate the ``power_state`` parameter of the PSCI API. If the
561``power_state`` is known to be invalid, the platform must return
562PSCI\_E\_INVALID\_PARAMS as an error, which is propagated back to the Normal
563world PSCI client.
564
565plat\_pm\_ops.validate\_ns\_entrypoint()
566^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
567
568This function is called by the PSCI implementation during the ``CPU_SUSPEND``,
569``SYSTEM_SUSPEND`` and ``CPU_ON`` calls to validate the Non-secure ``entry_point``
570parameter passed by the Normal world. If the ``entry_point`` is known to be
571invalid, the platform must return PSCI\_E\_INVALID\_PARAMS as an error, which is
572propagated back to the Normal world PSCI client.
573
574plat\_pm\_ops.get\_sys\_suspend\_power\_state()
575^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
576
577This function is called by the PSCI implementation during the ``SYSTEM_SUSPEND``
578call to return the ``power_state`` parameter. This allows the platform to encode
579the appropriate State-ID field within the ``power_state`` parameter which can be
580utilized in ``affinst_suspend()`` to suspend to system affinity level. The
581``power_state`` parameter should be in the same format as specified by the
582PSCI specification for the CPU\_SUSPEND API.
583
584--------------
585
586*Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.*
587
588.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
589.. _Porting Guide: porting-guide.rst#user-content-function--plat_my_core_pos
590.. _psci pd tree: psci-pd-tree.rst
591.. _plat/arm/board/fvp/fvp\_pm.c: ../plat/arm/board/fvp/fvp_pm.c
592.. _38dce70f51fb83b27958ba3e2ad15f5635cb1061: https://github.com/ARM-software/arm-trusted-firmware/commit/38dce70f51fb83b27958ba3e2ad15f5635cb1061
593.. _plat/common/aarch64/platform\_up\_stack.S: ../plat/common/aarch64/platform_up_stack.S
594.. _plat/common/aarch64/platform\_mp\_stack.S: ../plat/common/aarch64/platform_mp_stack.S
595
596.. |Image 1| image:: diagrams/psci-suspend-sequence.png?raw=true