blob: 638033e440f6fc072f772abb2dfdbbf6bbdb2e9b [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);
Varun Wadekarae87f4b2017-07-10 16:02:05 -0700149 void (*pwr_domain_suspend_early)(const psci_power_state_t *target_state);
Douglas Raillardd7c21b72017-06-28 15:23:03 +0100150 void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
151 void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
152 void (*pwr_domain_suspend_finish)(
153 const psci_power_state_t *target_state);
154 void (*system_off)(void) __dead2;
155 void (*system_reset)(void) __dead2;
156 int (*validate_power_state)(unsigned int power_state,
157 psci_power_state_t *req_state);
158 int (*validate_ns_entrypoint)(unsigned long ns_entrypoint);
159 void (*get_sys_suspend_power_state)(
160 psci_power_state_t *req_state);
161 } plat_psci_ops_t;
162
163The description of these handlers can be found in the `Porting Guide <porting-guide.rst#user-content-function--plat_setup_psci_ops-mandatory>`__.
164The previous ``plat_pm_ops`` structure is deprecated. Compared with the previous
165handlers, the major differences are:
166
167- Difference in parameters
168
169The PSCI 1.0 implementation depends on the ``validate_power_state`` handler to
170convert the power-state parameter (possibly encoding a composite power state)
171passed in a PSCI ``CPU_SUSPEND`` to the ``psci_power_state`` format. This handler
172is now mandatory for PSCI ``CPU_SUSPEND`` support.
173
Varun Wadekarae87f4b2017-07-10 16:02:05 -0700174The ``plat_psci_ops`` handlers, ``pwr_domain_off``, ``pwr_domain_suspend_early``
175and ``pwr_domain_suspend``, are passed the target local state for each affected
176power domain. The platform must execute operations specific to these target
177states. Similarly, ``pwr_domain_on_finish`` and ``pwr_domain_suspend_finish``
178are passed the local states of the affected power domains before wakeup. The
179platform must execute actions to restore these power domains from these specific
Douglas Raillardd7c21b72017-06-28 15:23:03 +0100180local states.
181
182- Difference in invocation
183
184Whereas the power management handlers in ``plat_pm_ops`` used to be invoked
185for each affinity level till the target affinity level, the new handlers
186are only invoked once. The ``target_state`` encodes the target low power
187state or the low power state woken up from for each affected power domain.
188
189- Difference in semantics
190
191Although the previous ``suspend`` handlers could be used for power down as well
192as retention at different affinity levels, the new handlers make this support
193explicit. The ``pwr_domain_suspend`` can be used to specify powerdown and
194retention at various power domain levels subject to the conditions mentioned
195in section 4.2.1 of `PSCI`_
196
197Unlike the previous ``standby`` handler, the ``cpu_standby()`` handler is only used
198as a fast path for placing a core power domain into a standby or retention
199state.
200
201The below diagram shows the sequence of a PSCI SUSPEND call and the interaction
202with the platform layer depicting the exchange of data between PSCI Generic
203layer and the platform layer.
204
205|Image 1|
206
207Refer `plat/arm/board/fvp/fvp\_pm.c`_ for the implementation details of
208these handlers for the FVP. The commit `38dce70f51fb83b27958ba3e2ad15f5635cb1061`_
209demonstrates the migration of ARM reference platforms to the new platform API.
210
211Miscellaneous modifications
212---------------------------
213
214In addition to the framework changes, unification of warm reset entry points on
215wakeup from low power modes has led to a change in the platform API. In the
216earlier implementation, the warm reset entry used to be programmed into the
217mailboxes by the 'ON' and 'SUSPEND' power management hooks. In the PSCI 1.0
218implementation, this information is not required, because it can figure that
219out by querying affinity info state whether to execute the 'suspend\_finisher\`
220or 'on\_finisher'.
221
222As a result, the warm reset entry point must be programmed only once. The
223``plat_setup_psci_ops()`` API takes the secure entry point as an
224additional parameter to enable the platforms to configure their mailbox. The
225plat\_psci\_ops handlers ``pwr_domain_on`` and ``pwr_domain_suspend`` no longer take
226the warm reset entry point as a parameter.
227
228Also, some platform APIs which took ``MPIDR`` as an argument were only ever
229invoked to perform actions specific to the caller core which makes the argument
230redundant. Therefore the platform APIs ``plat_get_my_entrypoint()``,
231``plat_is_my_cpu_primary()``, ``plat_set_my_stack()`` and
232``plat_get_my_stack()`` are defined which are meant to be invoked only for
233operations on the current caller core instead of ``platform_get_entrypoint()``,
234``platform_is_primary_cpu()``, ``platform_set_stack()`` and ``platform_get_stack()``.
235
236Compatibility layer
237-------------------
238
239To ease the migration of the platform ports to the new porting interface,
240a compatibility layer is introduced that essentially implements a glue layer
241between the old platform API and the new API. The build flag
242``ENABLE_PLAT_COMPAT`` (enabled by default), specifies whether to enable this
243layer or not. A platform port which has migrated to the new API can disable
244this flag within the platform specific makefile.
245
246The compatibility layer works on the assumption that the onus of
247state coordination, in case multiple low power states are supported,
248is with the platform. The generic PSCI implementation only takes into
249account whether the suspend request is power down or not. This corresponds
250with the behavior of the PSCI implementation before the introduction of
251new frameworks. Also, it assumes that the affinity levels of the platform
252correspond directly to the power domain levels.
253
254The compatibility layer dynamically constructs the new topology
255description array by querying the platform using ``plat_get_aff_count()``
256and ``plat_get_aff_state()`` APIs. The linear index returned by
257``platform_get_core_pos()`` is used as the core index for the cores. The
258higher level (non-core) power domain nodes must know the cores contained
259within its domain. It does so by storing the core index of first core
260within it and number of core indexes following it. This means that core
261indices returned by ``platform_get_core_pos()`` for cores within a particular
262power domain must be consecutive. We expect that this is the case for most
263platform ports including ARM reference platforms.
264
265The old PSCI helpers like ``psci_get_suspend_powerstate()``,
266``psci_get_suspend_stateid()``, ``psci_get_suspend_stateid_by_mpidr()``,
267``psci_get_max_phys_off_afflvl()`` and ``psci_get_suspend_afflvl()`` are also
268implemented for the compatibility layer. This allows the existing
269platform ports to work with the new PSCI frameworks without significant
270rework.
271
272Deprecated Platform API
273-----------------------
274
275This section documents the deprecated platform porting API.
276
277Common mandatory modifications
278------------------------------
279
280The mandatory macros to be defined by the platform port in ``platform_def.h``
281
282- **#define : PLATFORM\_NUM\_AFFS**
283
284 Defines the total number of nodes in the affinity hierarchy at all affinity
285 levels used by the platform.
286
287- **#define : PLATFORM\_MAX\_AFFLVL**
288
289 Defines the maximum affinity level that the power management operations
290 should apply to. ARMv8-A has support for four affinity levels. It is likely
291 that hardware will implement fewer affinity levels. This macro allows the
292 PSCI implementation to consider only those affinity levels in the system
293 that the platform implements. For example, the Base AEM FVP implements two
294 clusters with a configurable number of cores. It reports the maximum
295 affinity level as 1, resulting in PSCI power control up to the cluster
296 level.
297
298The following functions must be implemented by the platform port to enable
299the reset vector code to perform the required tasks.
300
301Function : platform\_get\_entrypoint() [mandatory]
302~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
303
304::
305
306 Argument : unsigned long
307 Return : unsigned long
308
309This function is called with the ``SCTLR.M`` and ``SCTLR.C`` bits disabled. The core
310is identified by its ``MPIDR``, which is passed as the argument. The function is
311responsible for distinguishing between a warm and cold reset using platform-
312specific means. If it is a warm reset, it returns the entrypoint into the
313BL31 image that the core must jump to. If it is a cold reset, this function
314must return zero.
315
316This function is also responsible for implementing a platform-specific mechanism
317to handle the condition where the core has been warm reset but there is no
318entrypoint to jump to.
319
320This function does not follow the Procedure Call Standard used by the
321Application Binary Interface for the ARM 64-bit architecture. The caller should
322not assume that callee saved registers are preserved across a call to this
323function.
324
325Function : platform\_is\_primary\_cpu() [mandatory]
326~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
327
328::
329
330 Argument : unsigned long
331 Return : unsigned int
332
333This function identifies a core by its ``MPIDR``, which is passed as the argument,
334to determine whether this core is the primary core or a secondary core. A return
335value of zero indicates that the core is not the primary core, while a non-zero
336return value indicates that the core is the primary core.
337
338Common optional modifications
339-----------------------------
340
341Function : platform\_get\_core\_pos()
342~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
343
344::
345
346 Argument : unsigned long
347 Return : int
348
349A platform may need to convert the ``MPIDR`` of a core to an absolute number, which
350can be used as a core-specific linear index into blocks of memory (for example
351while allocating per-core stacks). This routine contains a simple mechanism
352to perform this conversion, using the assumption that each cluster contains a
353maximum of four cores:
354
355::
356
357 linear index = cpu_id + (cluster_id * 4)
358
359 cpu_id = 8-bit value in MPIDR at affinity level 0
360 cluster_id = 8-bit value in MPIDR at affinity level 1
361
362Function : platform\_set\_stack()
363~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
364
365::
366
367 Argument : unsigned long
368 Return : void
369
370This function sets the current stack pointer to the normal memory stack that
371has been allocated for the core specified by MPIDR. For BL images that only
372require a stack for the primary core the parameter is ignored. The size of
373the stack allocated to each core is specified by the platform defined constant
374``PLATFORM_STACK_SIZE``.
375
376Common implementations of this function for the UP and MP BL images are
377provided in `plat/common/aarch64/platform\_up\_stack.S`_ and
378`plat/common/aarch64/platform\_mp\_stack.S`_
379
380Function : platform\_get\_stack()
381~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382
383::
384
385 Argument : unsigned long
386 Return : unsigned long
387
388This function returns the base address of the normal memory stack that
389has been allocated for the core specificed by MPIDR. For BL images that only
390require a stack for the primary core the parameter is ignored. The size of
391the stack allocated to each core is specified by the platform defined constant
392``PLATFORM_STACK_SIZE``.
393
394Common implementations of this function for the UP and MP BL images are
395provided in `plat/common/aarch64/platform\_up\_stack.S`_ and
396`plat/common/aarch64/platform\_mp\_stack.S`_
397
398Modifications for Power State Coordination Interface (in BL31)
399--------------------------------------------------------------
400
401The following functions must be implemented to initialize PSCI functionality in
402the ARM Trusted Firmware.
403
404Function : plat\_get\_aff\_count() [mandatory]
405~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
406
407::
408
409 Argument : unsigned int, unsigned long
410 Return : unsigned int
411
412This function may execute with the MMU and data caches enabled if the platform
413port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only
414called by the primary core.
415
416This function is called by the PSCI initialization code to detect the system
417topology. Its purpose is to return the number of affinity instances implemented
418at a given ``affinity level`` (specified by the first argument) and a given
419``MPIDR`` (specified by the second argument). For example, on a dual-cluster
420system where first cluster implements two cores and the second cluster
421implements four cores, a call to this function with an ``MPIDR`` corresponding
422to the first cluster (``0x0``) and affinity level 0, would return 2. A call
423to this function with an ``MPIDR`` corresponding to the second cluster (``0x100``)
424and affinity level 0, would return 4.
425
426Function : plat\_get\_aff\_state() [mandatory]
427~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
428
429::
430
431 Argument : unsigned int, unsigned long
432 Return : unsigned int
433
434This function may execute with the MMU and data caches enabled if the platform
435port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only
436called by the primary core.
437
438This function is called by the PSCI initialization code. Its purpose is to
439return the state of an affinity instance. The affinity instance is determined by
440the affinity ID at a given ``affinity level`` (specified by the first argument)
441and an ``MPIDR`` (specified by the second argument). The state can be one of
442``PSCI_AFF_PRESENT`` or ``PSCI_AFF_ABSENT``. The latter state is used to cater for
443system topologies where certain affinity instances are unimplemented. For
444example, consider a platform that implements a single cluster with four cores and
445another core implemented directly on the interconnect with the cluster. The
446``MPIDR``\ s of the cluster would range from ``0x0-0x3``. The ``MPIDR`` of the single
447core is 0x100 to indicate that it does not belong to cluster 0. Cluster 1
448is missing but needs to be accounted for to reach this single core in the
449topology tree. Therefore it is marked as ``PSCI_AFF_ABSENT``.
450
451Function : platform\_setup\_pm() [mandatory]
452~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
453
454::
455
456 Argument : const plat_pm_ops **
457 Return : int
458
459This function may execute with the MMU and data caches enabled if the platform
460port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only
461called by the primary core.
462
463This function is called by PSCI initialization code. Its purpose is to export
464handler routines for platform-specific power management actions by populating
465the passed pointer with a pointer to the private ``plat_pm_ops`` structure of
466BL31.
467
468A description of each member of this structure is given below. A platform port
469is expected to implement these handlers if the corresponding PSCI operation
470is to be supported and these handlers are expected to succeed if the return
471type is ``void``.
472
473plat\_pm\_ops.affinst\_standby()
474^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
475
476Perform the platform-specific setup to enter the standby state indicated by the
477passed argument. The generic code expects the handler to succeed.
478
479plat\_pm\_ops.affinst\_on()
480^^^^^^^^^^^^^^^^^^^^^^^^^^^
481
482Perform the platform specific setup to power on an affinity instance, specified
483by the ``MPIDR`` (first argument) and ``affinity level`` (third argument). The
484``state`` (fourth argument) contains the current state of that affinity instance
485(ON or OFF). This is useful to determine whether any action must be taken. For
486example, while powering on a core, the cluster that contains this core might
487already be in the ON state. The platform decides what actions must be taken to
488transition from the current state to the target state (indicated by the power
489management operation). The generic code expects the platform to return
490E\_SUCCESS on success or E\_INTERN\_FAIL for any failure.
491
492plat\_pm\_ops.affinst\_off()
493^^^^^^^^^^^^^^^^^^^^^^^^^^^^
494
495Perform the platform specific setup to power off an affinity instance of the
496calling core. It is called by the PSCI ``CPU_OFF`` API implementation.
497
498The ``affinity level`` (first argument) and ``state`` (second argument) have
499a similar meaning as described in the ``affinst_on()`` operation. They
500identify the affinity instance on which the call is made and its
501current state. This gives the platform port an indication of the
502state transition it must make to perform the requested action. For example, if
503the calling core is the last powered on core in the cluster, after powering down
504affinity level 0 (the core), the platform port should power down affinity
505level 1 (the cluster) as well. The generic code expects the handler to succeed.
506
507plat\_pm\_ops.affinst\_suspend()
508^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
509
510Perform the platform specific setup to power off an affinity instance of the
511calling core. It is called by the PSCI ``CPU_SUSPEND`` API and ``SYSTEM_SUSPEND``
512API implementation
513
514The ``affinity level`` (second argument) and ``state`` (third argument) have a
515similar meaning as described in the ``affinst_on()`` operation. They are used to
516identify the affinity instance on which the call is made and its current state.
517This gives the platform port an indication of the state transition it must
518make to perform the requested action. For example, if the calling core is the
519last powered on core in the cluster, after powering down affinity level 0
520(the core), the platform port should power down affinity level 1 (the cluster)
521as well.
522
523The difference between turning an affinity instance off and suspending it
524is that in the former case, the affinity instance is expected to re-initialize
525its state when it is next powered on (see ``affinst_on_finish()``). In the latter
526case, the affinity instance is expected to save enough state so that it can
527resume execution by restoring this state when it is powered on (see
528``affinst_suspend_finish()``).The generic code expects the handler to succeed.
529
530plat\_pm\_ops.affinst\_on\_finish()
531^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
532
533This function is called by the PSCI implementation after the calling core is
534powered on and released from reset in response to an earlier PSCI ``CPU_ON`` call.
535It performs the platform-specific setup required to initialize enough state for
536this core to enter the Normal world and also provide secure runtime firmware
537services.
538
539The ``affinity level`` (first argument) and ``state`` (second argument) have a
540similar meaning as described in the previous operations. The generic code
541expects the handler to succeed.
542
543plat\_pm\_ops.affinst\_suspend\_finish()
544^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
545
546This function is called by the PSCI implementation after the calling core is
547powered on and released from reset in response to an asynchronous wakeup
548event, for example a timer interrupt that was programmed by the core during the
549``CPU_SUSPEND`` call or ``SYSTEM_SUSPEND`` call. It performs the platform-specific
550setup required to restore the saved state for this core to resume execution
551in the Normal world and also provide secure runtime firmware services.
552
553The ``affinity level`` (first argument) and ``state`` (second argument) have a
554similar meaning as described in the previous operations. The generic code
555expects the platform to succeed.
556
557plat\_pm\_ops.validate\_power\_state()
558^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
559
560This function is called by the PSCI implementation during the ``CPU_SUSPEND``
561call to validate the ``power_state`` parameter of the PSCI API. If the
562``power_state`` is known to be invalid, the platform must return
563PSCI\_E\_INVALID\_PARAMS as an error, which is propagated back to the Normal
564world PSCI client.
565
566plat\_pm\_ops.validate\_ns\_entrypoint()
567^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
568
569This function is called by the PSCI implementation during the ``CPU_SUSPEND``,
570``SYSTEM_SUSPEND`` and ``CPU_ON`` calls to validate the Non-secure ``entry_point``
571parameter passed by the Normal world. If the ``entry_point`` is known to be
572invalid, the platform must return PSCI\_E\_INVALID\_PARAMS as an error, which is
573propagated back to the Normal world PSCI client.
574
575plat\_pm\_ops.get\_sys\_suspend\_power\_state()
576^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
577
578This function is called by the PSCI implementation during the ``SYSTEM_SUSPEND``
579call to return the ``power_state`` parameter. This allows the platform to encode
580the appropriate State-ID field within the ``power_state`` parameter which can be
581utilized in ``affinst_suspend()`` to suspend to system affinity level. The
582``power_state`` parameter should be in the same format as specified by the
583PSCI specification for the CPU\_SUSPEND API.
584
585--------------
586
587*Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.*
588
589.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
590.. _Porting Guide: porting-guide.rst#user-content-function--plat_my_core_pos
591.. _psci pd tree: psci-pd-tree.rst
592.. _plat/arm/board/fvp/fvp\_pm.c: ../plat/arm/board/fvp/fvp_pm.c
593.. _38dce70f51fb83b27958ba3e2ad15f5635cb1061: https://github.com/ARM-software/arm-trusted-firmware/commit/38dce70f51fb83b27958ba3e2ad15f5635cb1061
594.. _plat/common/aarch64/platform\_up\_stack.S: ../plat/common/aarch64/platform_up_stack.S
595.. _plat/common/aarch64/platform\_mp\_stack.S: ../plat/common/aarch64/platform_mp_stack.S
596
597.. |Image 1| image:: diagrams/psci-suspend-sequence.png?raw=true