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