Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
60e062fb
Unverified
Commit
60e062fb
authored
6 years ago
by
danh-arm
Committed by
GitHub
6 years ago
Browse files
Options
Download
Plain Diff
Merge pull request #1486 from antonio-nino-diaz-arm/an/psci-misra
Fix several MISRA defects in PSCI library
parents
d87d524e
6b7b0f36
master
v2.5
v2.5-rc1
v2.5-rc0
v2.4
v2.4-rc2
v2.4-rc1
v2.4-rc0
v2.3
v2.3-rc2
v2.3-rc1
v2.3-rc0
v2.2
v2.2-rc2
v2.2-rc1
v2.2-rc0
v2.1
v2.1-rc1
v2.1-rc0
v2.0
v2.0-rc0
v1.6
v1.6-rc1
v1.6-rc0
arm_cca_v0.2
arm_cca_v0.1
No related merge requests found
Changes
43
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
include/lib/aarch64/arch.h
+7
-7
include/lib/aarch64/arch.h
include/lib/pmf/pmf.h
+8
-8
include/lib/pmf/pmf.h
include/lib/pmf/pmf_helpers.h
+7
-7
include/lib/pmf/pmf_helpers.h
include/lib/psci/psci.h
+61
-41
include/lib/psci/psci.h
include/lib/psci/psci_compat.h
+11
-10
include/lib/psci/psci_compat.h
include/lib/psci/psci_lib.h
+9
-10
include/lib/psci/psci_lib.h
include/lib/utils_def.h
+21
-15
include/lib/utils_def.h
include/plat/arm/common/arm_def.h
+6
-6
include/plat/arm/common/arm_def.h
include/plat/common/platform.h
+3
-4
include/plat/common/platform.h
lib/psci/psci_common.c
+90
-72
lib/psci/psci_common.c
lib/psci/psci_main.c
+94
-54
lib/psci/psci_main.c
lib/psci/psci_mem_protect.c
+13
-12
lib/psci/psci_mem_protect.c
lib/psci/psci_off.c
+9
-10
lib/psci/psci_off.c
lib/psci/psci_on.c
+34
-17
lib/psci/psci_on.c
lib/psci/psci_private.h
+161
-106
lib/psci/psci_private.h
lib/psci/psci_setup.c
+36
-34
lib/psci/psci_setup.c
lib/psci/psci_stat.c
+25
-22
lib/psci/psci_stat.c
lib/psci/psci_suspend.c
+21
-21
lib/psci/psci_suspend.c
lib/psci/psci_system_off.c
+21
-19
lib/psci/psci_system_off.c
plat/allwinner/common/include/platform_def.h
+8
-7
plat/allwinner/common/include/platform_def.h
with
645 additions
and
482 deletions
+645
-482
include/lib/aarch64/arch.h
View file @
60e062fb
...
...
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
ARCH_H
__
#define
__
ARCH_H
__
#ifndef ARCH_H
#define ARCH_H
#include <utils_def.h>
...
...
@@ -37,10 +37,10 @@
#define MPIDR_AFF3_SHIFT U(32)
#define MPIDR_AFFINITY_MASK ULL(0xff00ffffff)
#define MPIDR_AFFLVL_SHIFT U(3)
#define MPIDR_AFFLVL0 U
LL
(0x0)
#define MPIDR_AFFLVL1 U
LL
(0x1)
#define MPIDR_AFFLVL2 U
LL
(0x2)
#define MPIDR_AFFLVL3 U
LL
(0x3)
#define MPIDR_AFFLVL0 U(0x0)
#define MPIDR_AFFLVL1 U(0x1)
#define MPIDR_AFFLVL2 U(0x2)
#define MPIDR_AFFLVL3 U(0x3)
#define MPIDR_AFFLVL0_VAL(mpidr) \
(((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
#define MPIDR_AFFLVL1_VAL(mpidr) \
...
...
@@ -739,4 +739,4 @@
#define ERXMISC0_EL1 S3_0_C5_C4_4
#define ERXMISC1_EL1 S3_0_C5_C4_5
#endif
/*
__
ARCH_H
__
*/
#endif
/* ARCH_H */
This diff is collapsed.
Click to expand it.
include/lib/pmf/pmf.h
View file @
60e062fb
...
...
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
PMF_H
__
#define
__
PMF_H
__
#ifndef PMF_H
#define PMF_H
#include <cassert.h>
#include <pmf_helpers.h>
...
...
@@ -31,8 +31,8 @@
* Flags passed to PMF_GET_TIMESTAMP_XXX
* and PMF_CAPTURE_TIMESTAMP
*/
#define PMF_CACHE_MAINT (
1
<< 0)
#define PMF_NO_CACHE_MAINT
0
#define PMF_CACHE_MAINT (
U(1)
<< 0)
#define PMF_NO_CACHE_MAINT
U(0)
/*
* Defines for PMF SMC function ids.
...
...
@@ -68,7 +68,7 @@
#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \
do { \
unsigned long long ts = read_cntpct_el0(); \
if ((_flags) & PMF_CACHE_MAINT)
\
if ((
(
_flags) & PMF_CACHE_MAINT)
!= 0U)
\
pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
else \
pmf_capture_timestamp_ ## _name((_tid), ts); \
...
...
@@ -78,7 +78,7 @@
do { \
(_tsval) = read_cntpct_el0(); \
CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
if ((_flags) & PMF_CACHE_MAINT)
\
if ((
(
_flags) & PMF_CACHE_MAINT)
!= 0U)
\
pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
else \
pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
...
...
@@ -87,7 +87,7 @@
#define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \
do { \
CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
if ((_flags) & PMF_CACHE_MAINT)
\
if ((
(
_flags) & PMF_CACHE_MAINT)
!= 0U)
\
pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
else \
pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
...
...
@@ -173,4 +173,4 @@ uintptr_t pmf_smc_handler(unsigned int smc_fid,
void
*
handle
,
u_register_t
flags
);
#endif
/*
__
PMF_H
__
*/
#endif
/* PMF_H */
This diff is collapsed.
Click to expand it.
include/lib/pmf/pmf_helpers.h
View file @
60e062fb
...
...
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
PMF_HELPERS_H
__
#define
__
PMF_HELPERS_H
__
#ifndef PMF_HELPERS_H
#define PMF_HELPERS_H
#include <arch_helpers.h>
#include <assert.h>
...
...
@@ -77,9 +77,9 @@ typedef struct pmf_svc_desc {
CASSERT(_flags, select_proper_config); \
PMF_VALIDATE_TID(_name, tid); \
uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
if ((_flags) & PMF_STORE_ENABLE) \
if ((
(
_flags) & PMF_STORE_ENABLE)
!= 0)
\
__pmf_store_timestamp(base_addr, tid, ts); \
if ((_flags) & PMF_DUMP_ENABLE)
\
if ((
(
_flags) & PMF_DUMP_ENABLE)
!= 0)
\
__pmf_dump_timestamp(tid, ts); \
} \
void pmf_capture_timestamp_with_cache_maint_ ## _name( \
...
...
@@ -92,9 +92,9 @@ typedef struct pmf_svc_desc {
CASSERT(_flags, select_proper_config); \
PMF_VALIDATE_TID(_name, tid); \
uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
if ((_flags) & PMF_STORE_ENABLE) \
if ((
(
_flags) & PMF_STORE_ENABLE)
!= 0)
\
__pmf_store_timestamp_with_cache_maint(base_addr, tid, ts);\
if ((_flags) & PMF_DUMP_ENABLE)
\
if ((
(
_flags) & PMF_DUMP_ENABLE)
!= 0)
\
__pmf_dump_timestamp(tid, ts); \
}
...
...
@@ -159,4 +159,4 @@ unsigned long long __pmf_get_timestamp(uintptr_t base_addr,
unsigned
int
tid
,
unsigned
int
cpuid
,
unsigned
int
flags
);
#endif
/*
__
PMF_HELPERS_H
__
*/
#endif
/* PMF_HELPERS_H */
This diff is collapsed.
Click to expand it.
include/lib/psci/psci.h
View file @
60e062fb
/*
* Copyright (c) 2013-201
7
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
PSCI_H
__
#define
__
PSCI_H
__
#ifndef PSCI_H
#define PSCI_H
#include <bakery_lock.h>
#include <bl_common.h>
...
...
@@ -22,14 +22,14 @@
#ifdef PLAT_NUM_PWR_DOMAINS
#define PSCI_NUM_PWR_DOMAINS PLAT_NUM_PWR_DOMAINS
#else
#define PSCI_NUM_PWR_DOMAINS (
U(2)
* PLATFORM_CORE_COUNT)
#define PSCI_NUM_PWR_DOMAINS (
2
* PLATFORM_CORE_COUNT)
#endif
#define PSCI_NUM_NON_CPU_PWR_DOMAINS (PSCI_NUM_PWR_DOMAINS - \
PLATFORM_CORE_COUNT)
/* This is the power level corresponding to a CPU */
#define PSCI_CPU_PWR_LVL (0)
#define PSCI_CPU_PWR_LVL
U
(0)
/*
* The maximum power level supported by PSCI. Since PSCI CPU_SUSPEND
...
...
@@ -71,9 +71,6 @@
#define PSCI_MEM_CHK_RANGE_AARCH32 U(0x84000014)
#define PSCI_MEM_CHK_RANGE_AARCH64 U(0xc4000014)
/* Macro to help build the psci capabilities bitfield */
#define define_psci_cap(x) (U(1) << (x & U(0x1f)))
/*
* Number of PSCI calls (above) implemented
*/
...
...
@@ -92,9 +89,9 @@
/*******************************************************************************
* PSCI Migrate and friends
******************************************************************************/
#define PSCI_TOS_UP_MIG_CAP
U(0)
#define PSCI_TOS_NOT_UP_MIG_CAP
U(1)
#define PSCI_TOS_NOT_PRESENT_MP
U(2)
#define PSCI_TOS_UP_MIG_CAP
0
#define PSCI_TOS_NOT_UP_MIG_CAP
1
#define PSCI_TOS_NOT_PRESENT_MP
2
/*******************************************************************************
* PSCI CPU_SUSPEND 'power_state' parameter specific defines
...
...
@@ -124,12 +121,6 @@
#define PSTATE_TYPE_POWERDOWN U(0x1)
#define PSTATE_TYPE_MASK U(0x1)
#define psci_get_pstate_id(pstate) (((pstate) >> PSTATE_ID_SHIFT) & \
PSTATE_ID_MASK)
#define psci_get_pstate_type(pstate) (((pstate) >> PSTATE_TYPE_SHIFT) & \
PSTATE_TYPE_MASK)
#define psci_check_power_state(pstate) ((pstate) & PSTATE_VALID_MASK)
/*******************************************************************************
* PSCI CPU_FEATURES feature flag specific defines
******************************************************************************/
...
...
@@ -172,16 +163,41 @@
/*
* SYSTEM_RESET2 macros
*/
#define PSCI_RESET2_TYPE_VENDOR_SHIFT 31
#define PSCI_RESET2_TYPE_VENDOR (
1
U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
#define PSCI_RESET2_TYPE_ARCH (
0
U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
#define PSCI_RESET2_SYSTEM_WARM_RESET (PSCI_RESET2_TYPE_ARCH | 0)
#define PSCI_RESET2_TYPE_VENDOR_SHIFT
U(
31
)
#define PSCI_RESET2_TYPE_VENDOR (U
(1)
<< PSCI_RESET2_TYPE_VENDOR_SHIFT)
#define PSCI_RESET2_TYPE_ARCH (U
(0)
<< PSCI_RESET2_TYPE_VENDOR_SHIFT)
#define PSCI_RESET2_SYSTEM_WARM_RESET (PSCI_RESET2_TYPE_ARCH |
U(
0)
)
#ifndef __ASSEMBLY__
#include <stdint.h>
#include <types.h>
/* Function to help build the psci capabilities bitfield */
static
inline
unsigned
int
define_psci_cap
(
unsigned
int
x
)
{
return
U
(
1
)
<<
(
x
&
U
(
0x1f
));
}
/* Power state helper functions */
static
inline
unsigned
int
psci_get_pstate_id
(
unsigned
int
power_state
)
{
return
((
power_state
)
>>
PSTATE_ID_SHIFT
)
&
PSTATE_ID_MASK
;
}
static
inline
unsigned
int
psci_get_pstate_type
(
unsigned
int
power_state
)
{
return
((
power_state
)
>>
PSTATE_TYPE_SHIFT
)
&
PSTATE_TYPE_MASK
;
}
static
inline
unsigned
int
psci_check_power_state
(
unsigned
int
power_state
)
{
return
((
power_state
)
&
PSTATE_VALID_MASK
);
}
/*
* These are the states reported by the PSCI_AFFINITY_INFO API for the specified
* CPU. The definitions of these states can be found in Section 5.7.1 in the
...
...
@@ -198,11 +214,9 @@ typedef enum {
* specified CPU. The definitions of these states can be found in Section 5.15.3
* of PSCI specification (ARM DEN 0022C).
*/
typedef
enum
{
HW_ON
=
U
(
0
),
HW_OFF
=
U
(
1
),
HW_STANDBY
=
U
(
2
)
}
node_hw_state_t
;
#define HW_ON 0
#define HW_OFF 1
#define HW_STANDBY 2
/*
* Macro to represent invalid affinity level within PSCI.
...
...
@@ -215,27 +229,33 @@ typedef enum {
typedef
uint8_t
plat_local_state_t
;
/* The local state macro used to represent RUN state. */
#define PSCI_LOCAL_STATE_RUN
U(0)
#define PSCI_LOCAL_STATE_RUN U(0)
/*
*
Macro
to test whether the plat_local_state is RUN state
*
Function
to test whether the plat_local_state is RUN state
*/
#define is_local_state_run(plat_local_state) \
((plat_local_state) == PSCI_LOCAL_STATE_RUN)
static
inline
int
is_local_state_run
(
unsigned
int
plat_local_state
)
{
return
(
plat_local_state
==
PSCI_LOCAL_STATE_RUN
)
?
1
:
0
;
}
/*
*
Macro
to test whether the plat_local_state is RETENTION state
*
Function
to test whether the plat_local_state is RETENTION state
*/
#define is_local_state_retn(plat_local_state) \
(((plat_local_state) > PSCI_LOCAL_STATE_RUN) && \
((plat_local_state) <= PLAT_MAX_RET_STATE))
static
inline
int
is_local_state_retn
(
unsigned
int
plat_local_state
)
{
return
((
plat_local_state
>
PSCI_LOCAL_STATE_RUN
)
&&
(
plat_local_state
<=
PLAT_MAX_RET_STATE
))
?
1
:
0
;
}
/*
*
Macro
to test whether the plat_local_state is OFF state
*
Function
to test whether the plat_local_state is OFF state
*/
#define is_local_state_off(plat_local_state) \
(((plat_local_state) > PLAT_MAX_RET_STATE) && \
((plat_local_state) <= PLAT_MAX_OFF_STATE))
static
inline
int
is_local_state_off
(
unsigned
int
plat_local_state
)
{
return
((
plat_local_state
>
PLAT_MAX_RET_STATE
)
&&
(
plat_local_state
<=
PLAT_MAX_OFF_STATE
))
?
1
:
0
;
}
/*****************************************************************************
* This data structure defines the representation of the power state parameter
...
...
@@ -266,7 +286,7 @@ typedef struct psci_cpu_data {
* Highest power level which takes part in a power management
* operation.
*/
unsigned
char
target_pwrlvl
;
unsigned
int
target_pwrlvl
;
/* The local power state of this CPU */
plat_local_state_t
local_state
;
...
...
@@ -324,7 +344,7 @@ int psci_affinity_info(u_register_t target_affinity,
unsigned
int
lowest_affinity_level
);
int
psci_migrate
(
u_register_t
target_cpu
);
int
psci_migrate_info_type
(
void
);
long
psci_migrate_info_up_cpu
(
void
);
u_register_t
psci_migrate_info_up_cpu
(
void
);
int
psci_node_hw_state
(
u_register_t
target_cpu
,
unsigned
int
power_level
);
int
psci_features
(
unsigned
int
psci_fid
);
...
...
@@ -339,4 +359,4 @@ void psci_entrypoint(void) __deprecated;
#endif
/*__ASSEMBLY__*/
#endif
/*
__
PSCI_H
__
*/
#endif
/* PSCI_H */
This diff is collapsed.
Click to expand it.
include/lib/psci/psci_compat.h
View file @
60e062fb
/*
* Copyright (c) 2015-201
6
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
PSCI_COMPAT_H
__
#define
__
PSCI_COMPAT_H
__
#ifndef PSCI_COMPAT_H
#define PSCI_COMPAT_H
#include <arch.h>
#include <platform_def.h>
#include <utils_def.h>
#ifndef __ASSEMBLY__
/*
...
...
@@ -25,10 +26,10 @@
#define PSCI_AFF_ABSENT 0x0
#define PSCI_AFF_PRESENT 0x1
#define PSCI_STATE_ON 0x0
#define PSCI_STATE_OFF 0x1
#define PSCI_STATE_ON_PENDING 0x2
#define PSCI_STATE_SUSPEND 0x3
#define PSCI_STATE_ON
U(
0x0
)
#define PSCI_STATE_OFF
U(
0x1
)
#define PSCI_STATE_ON_PENDING
U(
0x2
)
#define PSCI_STATE_SUSPEND
U(
0x3
)
/*
* Using the compatibility platform interfaces means that the local states
...
...
@@ -38,8 +39,8 @@
* involved. Hence if we assume 3 generic states viz, run, standby and
* power down, we can assign 1 and 2 to standby and power down respectively.
*/
#define PLAT_MAX_RET_STATE
1
#define PLAT_MAX_OFF_STATE
2
#define PLAT_MAX_RET_STATE
U(1)
#define PLAT_MAX_OFF_STATE
U(2)
/*
* Macro to represent invalid affinity level within PSCI.
...
...
@@ -89,4 +90,4 @@ unsigned int psci_get_max_phys_off_afflvl(void);
int
psci_get_suspend_afflvl
(
void
);
#endif
/* ____ASSEMBLY__ */
#endif
/*
__
PSCI_COMPAT_H
__
*/
#endif
/* PSCI_COMPAT_H */
This diff is collapsed.
Click to expand it.
include/lib/psci/psci_lib.h
View file @
60e062fb
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017
-2018
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
PSCI_LIB_H
__
#define
__
PSCI_LIB_H
__
#ifndef PSCI_LIB_H
#define PSCI_LIB_H
#include <ep_info.h>
...
...
@@ -20,9 +20,9 @@
******************************************************************************/
typedef
struct
spd_pm_ops
{
void
(
*
svc_on
)(
u_register_t
target_cpu
);
int32_t
(
*
svc_off
)(
u_register_t
__unused
);
int32_t
(
*
svc_off
)(
u_register_t
__unused
unused
);
void
(
*
svc_suspend
)(
u_register_t
max_off_pwrlvl
);
void
(
*
svc_on_finish
)(
u_register_t
__unused
);
void
(
*
svc_on_finish
)(
u_register_t
__unused
unused
);
void
(
*
svc_suspend_finish
)(
u_register_t
max_off_pwrlvl
);
int32_t
(
*
svc_migrate
)(
u_register_t
from_cpu
,
u_register_t
to_cpu
);
int32_t
(
*
svc_migrate_info
)(
u_register_t
*
resident_cpu
);
...
...
@@ -58,17 +58,17 @@ typedef struct psci_lib_args {
.h.type = (uint8_t)PARAM_PSCI_LIB_ARGS, \
.h.version = (uint8_t)VERSION_1, \
.h.size = (uint16_t)sizeof(_name), \
.h.attr = 0, \
.h.attr = 0
U
, \
.mailbox_ep = (_entry) \
}
/* Helper macro to verify the pointer to psci_lib_args_t structure */
#define VERIFY_PSCI_LIB_ARGS_V1(_p) ((_p)
\
#define VERIFY_PSCI_LIB_ARGS_V1(_p) ((
(
_p)
!= NULL)
\
&& ((_p)->h.type == PARAM_PSCI_LIB_ARGS) \
&& ((_p)->h.version == VERSION_1) \
&& ((_p)->h.size == sizeof(*(_p))) \
&& ((_p)->h.attr == 0) \
&& ((_p)->mailbox_ep))
&& ((_p)->mailbox_ep
!= NULL
))
/******************************************************************************
* PSCI Library Interfaces
...
...
@@ -89,5 +89,4 @@ void psci_prepare_next_non_secure_ctx(
entry_point_info_t
*
next_image_info
);
#endif
/* __ASSEMBLY__ */
#endif
/* __PSCI_LIB_H */
#endif
/* PSCI_LIB_H */
This diff is collapsed.
Click to expand it.
include/lib/utils_def.h
View file @
60e062fb
...
...
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
UTILS_DEF_H
__
#define
__
UTILS_DEF_H
__
#ifndef UTILS_DEF_H
#define UTILS_DEF_H
/* Compute the number of elements in the given array */
#define ARRAY_SIZE(a) \
...
...
@@ -88,31 +88,37 @@
* Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
* Both arguments must be unsigned pointer values (i.e. uintptr_t).
*/
#define check_uptr_overflow(ptr, inc) \
((
(
ptr) > UINTPTR_MAX - (inc))
? 1 : 0
)
#define check_uptr_overflow(
_
ptr,
_
inc) \
((
_
ptr) >
(
UINTPTR_MAX - (
_
inc)))
/*
* Evaluates to 1 if (u32 + inc) overflows, 0 otherwise.
* Both arguments must be 32-bit unsigned integers (i.e. effectively uint32_t).
*/
#define check_u32_overflow(u32, inc) \
((u32) > (UINT32_MAX - (inc))
? 1 : 0
)
#define check_u32_overflow(
_
u32,
_
inc) \
((
_
u32) > (UINT32_MAX - (
_
inc)))
/*
* For those constants to be shared between C and other sources, apply a '
u'
* or '
ull
' suffix to the argument only in C, to avoid
undefined or unintended
* behaviour.
* For those constants to be shared between C and other sources, apply a '
U',
*
'UL', 'ULL', 'L'
or '
LL
' suffix to the argument only in C, to avoid
*
undefined or unintended
behaviour.
*
* The GNU assembler and linker do not support the
'u' and 'ull'
suffix (it
*
causes the
build process to fail) therefore the suffix is omitted when used
*
in linker
scripts and assembler files.
* The GNU assembler and linker do not support the
se
suffix
es
(it
causes the
* build process to fail) therefore the suffix is omitted when used
in linker
* scripts and assembler files.
*/
#if defined(__LINKER__) || defined(__ASSEMBLY__)
# define U(_x) (_x)
# define U(_x) (_x)
# define UL(_x) (_x)
# define ULL(_x) (_x)
# define L(_x) (_x)
# define LL(_x) (_x)
#else
# define U(_x) (_x##U)
# define U(_x) (_x##U)
# define UL(_x) (_x##UL)
# define ULL(_x) (_x##ULL)
# define L(_x) (_x##L)
# define LL(_x) (_x##LL)
#endif
/* Register size of the current architecture. */
...
...
@@ -147,4 +153,4 @@
#define ASSERT_SYM_PTR_ALIGN(sym) assert(((size_t)(sym) % __alignof__(*(sym))) == 0)
#endif
/*
__
UTILS_DEF_H
__
*/
#endif
/* UTILS_DEF_H */
This diff is collapsed.
Click to expand it.
include/plat/arm/common/arm_def.h
View file @
60e062fb
...
...
@@ -3,8 +3,8 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
ARM_DEF_H
__
#define
__
ARM_DEF_H
__
#ifndef ARM_DEF_H
#define ARM_DEF_H
#include <arch.h>
#include <common_def.h>
...
...
@@ -40,12 +40,12 @@
* within the power-state parameter.
*/
/* Local power state for power domains in Run state. */
#define ARM_LOCAL_STATE_RUN
0
#define ARM_LOCAL_STATE_RUN
U(0)
/* Local power state for retention. Valid only for CPU power domains */
#define ARM_LOCAL_STATE_RET
1
#define ARM_LOCAL_STATE_RET
U(1)
/* Local power state for OFF/power-down. Valid for CPU and cluster power
domains */
#define ARM_LOCAL_STATE_OFF
2
#define ARM_LOCAL_STATE_OFF
U(2)
/* Memory location options for TSP */
#define ARM_TRUSTED_SRAM_ID 0
...
...
@@ -528,4 +528,4 @@
SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
#endif
/*
__
ARM_DEF_H
__
*/
#endif
/* ARM_DEF_H */
This diff is collapsed.
Click to expand it.
include/plat/common/platform.h
View file @
60e062fb
...
...
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
PLATFORM_H
__
#define
__
PLATFORM_H
__
#ifndef PLATFORM_H
#define PLATFORM_H
#include <psci.h>
#include <stdint.h>
...
...
@@ -401,5 +401,4 @@ unsigned int platform_get_core_pos(unsigned long mpidr) __deprecated;
#endif
/* __ENABLE_PLAT_COMPAT__ */
#endif
/* __PLATFORM_H__ */
#endif
/* PLATFORM_H */
This diff is collapsed.
Click to expand it.
lib/psci/psci_common.c
View file @
60e062fb
/*
* Copyright (c) 2013-201
7
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -68,9 +68,9 @@ const plat_psci_ops_t *psci_plat_pm_ops;
/******************************************************************************
* Check that the maximum power level supported by the platform makes sense
*****************************************************************************/
CASSERT
(
PLAT_MAX_PWR_LVL
<=
PSCI_MAX_PWR_LVL
&&
\
PLAT_MAX_PWR_LVL
>=
PSCI_CPU_PWR_LVL
,
\
assert_platform_max_pwrlvl_check
);
CASSERT
(
(
PLAT_MAX_PWR_LVL
<=
PSCI_MAX_PWR_LVL
)
&&
(
PLAT_MAX_PWR_LVL
>=
PSCI_CPU_PWR_LVL
)
,
assert_platform_max_pwrlvl_check
);
/*
* The plat_local_state used by the platform is one of these types: RUN,
...
...
@@ -93,17 +93,25 @@ typedef enum plat_local_state_type {
STATE_TYPE_OFF
}
plat_local_state_type_t
;
/* The macro used to categorize plat_local_state. */
#define find_local_state_type(plat_local_state) \
((plat_local_state) ? ((plat_local_state > PLAT_MAX_RET_STATE) \
? STATE_TYPE_OFF : STATE_TYPE_RETN) \
: STATE_TYPE_RUN)
/* Function used to categorize plat_local_state. */
static
plat_local_state_type_t
find_local_state_type
(
plat_local_state_t
state
)
{
if
(
state
!=
0U
)
{
if
(
state
>
PLAT_MAX_RET_STATE
)
{
return
STATE_TYPE_OFF
;
}
else
{
return
STATE_TYPE_RETN
;
}
}
else
{
return
STATE_TYPE_RUN
;
}
}
/******************************************************************************
* Check that the maximum retention level supported by the platform is less
* than the maximum off level.
*****************************************************************************/
CASSERT
(
PLAT_MAX_RET_STATE
<
PLAT_MAX_OFF_STATE
,
\
CASSERT
(
PLAT_MAX_RET_STATE
<
PLAT_MAX_OFF_STATE
,
assert_platform_max_off_and_retn_state_check
);
/******************************************************************************
...
...
@@ -114,10 +122,10 @@ int psci_validate_power_state(unsigned int power_state,
psci_power_state_t
*
state_info
)
{
/* Check SBZ bits in power state are zero */
if
(
psci_check_power_state
(
power_state
))
if
(
psci_check_power_state
(
power_state
)
!=
0U
)
return
PSCI_E_INVALID_PARAMS
;
assert
(
psci_plat_pm_ops
->
validate_power_state
);
assert
(
psci_plat_pm_ops
->
validate_power_state
!=
NULL
);
/* Validate the power_state using platform pm_ops */
return
psci_plat_pm_ops
->
validate_power_state
(
power_state
,
state_info
);
...
...
@@ -133,7 +141,7 @@ void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info)
* Assert that the required pm_ops hook is implemented to ensure that
* the capability detected during psci_setup() is valid.
*/
assert
(
psci_plat_pm_ops
->
get_sys_suspend_power_state
);
assert
(
psci_plat_pm_ops
->
get_sys_suspend_power_state
!=
NULL
);
/*
* Query the platform for the power_state required for system suspend
...
...
@@ -149,7 +157,7 @@ void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info)
******************************************************************************/
unsigned
int
psci_is_last_on_cpu
(
void
)
{
unsigned
int
cpu_idx
,
my_idx
=
plat_my_core_pos
();
int
cpu_idx
,
my_idx
=
(
int
)
plat_my_core_pos
();
for
(
cpu_idx
=
0
;
cpu_idx
<
PLATFORM_CORE_COUNT
;
cpu_idx
++
)
{
if
(
cpu_idx
==
my_idx
)
{
...
...
@@ -201,7 +209,7 @@ static void psci_set_req_local_pwr_state(unsigned int pwrlvl,
assert
(
pwrlvl
>
PSCI_CPU_PWR_LVL
);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
psci_req_local_pwr_states
[
pwrlvl
-
1
][
cpu_idx
]
=
req_pwr_state
;
psci_req_local_pwr_states
[
pwrlvl
-
1
U
][
cpu_idx
]
=
req_pwr_state
;
#pragma GCC diagnostic pop
}
...
...
@@ -211,8 +219,15 @@ static void psci_set_req_local_pwr_state(unsigned int pwrlvl,
void
psci_init_req_local_pwr_states
(
void
)
{
/* Initialize the requested state of all non CPU power domains as OFF */
memset
(
&
psci_req_local_pwr_states
,
PLAT_MAX_OFF_STATE
,
sizeof
(
psci_req_local_pwr_states
));
unsigned
int
pwrlvl
;
int
core
;
for
(
pwrlvl
=
0U
;
pwrlvl
<
PLAT_MAX_PWR_LVL
;
pwrlvl
++
)
{
for
(
core
=
0
;
core
<
PLATFORM_CORE_COUNT
;
core
++
)
{
psci_req_local_pwr_states
[
pwrlvl
][
core
]
=
PLAT_MAX_OFF_STATE
;
}
}
}
/******************************************************************************
...
...
@@ -224,11 +239,11 @@ void psci_init_req_local_pwr_states(void)
* assertion is added to prevent us from accessing the CPU power level.
*****************************************************************************/
static
plat_local_state_t
*
psci_get_req_local_pwr_states
(
unsigned
int
pwrlvl
,
unsigned
int
cpu_idx
)
int
cpu_idx
)
{
assert
(
pwrlvl
>
PSCI_CPU_PWR_LVL
);
return
&
psci_req_local_pwr_states
[
pwrlvl
-
1
][
cpu_idx
];
return
&
psci_req_local_pwr_states
[
pwrlvl
-
1
U
][
cpu_idx
];
}
/*
...
...
@@ -291,7 +306,7 @@ void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
parent_idx
=
psci_cpu_pd_nodes
[
plat_my_core_pos
()].
parent_node
;
/* Copy the local power state from node to state_info */
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
U
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
pd_state
[
lvl
]
=
get_non_cpu_pd_node_local_state
(
parent_idx
);
parent_idx
=
psci_non_cpu_pd_nodes
[
parent_idx
].
parent_node
;
}
...
...
@@ -324,7 +339,7 @@ static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
parent_idx
=
psci_cpu_pd_nodes
[
plat_my_core_pos
()].
parent_node
;
/* Copy the local_state from state_info */
for
(
lvl
=
1
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
for
(
lvl
=
1
U
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
set_non_cpu_pd_node_local_state
(
parent_idx
,
pd_state
[
lvl
]);
parent_idx
=
psci_non_cpu_pd_nodes
[
parent_idx
].
parent_node
;
}
...
...
@@ -334,15 +349,17 @@ static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
/*******************************************************************************
* PSCI helper function to get the parent nodes corresponding to a cpu_index.
******************************************************************************/
void
psci_get_parent_pwr_domain_nodes
(
unsigned
int
cpu_idx
,
void
psci_get_parent_pwr_domain_nodes
(
int
cpu_idx
,
unsigned
int
end_lvl
,
unsigned
int
node_index
[]
)
unsigned
int
*
node_index
)
{
unsigned
int
parent_node
=
psci_cpu_pd_nodes
[
cpu_idx
].
parent_node
;
unsigned
int
i
;
unsigned
int
*
node
=
node_index
;
for
(
i
=
PSCI_CPU_PWR_LVL
+
1
;
i
<=
end_lvl
;
i
++
)
{
*
node_index
++
=
parent_node
;
for
(
i
=
PSCI_CPU_PWR_LVL
+
1U
;
i
<=
end_lvl
;
i
++
)
{
*
node
=
parent_node
;
node
++
;
parent_node
=
psci_non_cpu_pd_nodes
[
parent_node
].
parent_node
;
}
}
...
...
@@ -358,7 +375,7 @@ void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl)
parent_idx
=
psci_cpu_pd_nodes
[
cpu_idx
].
parent_node
;
/* Reset the local_state to RUN for the non cpu power domains. */
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
U
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
set_non_cpu_pd_node_local_state
(
parent_idx
,
PSCI_LOCAL_STATE_RUN
);
psci_set_req_local_pwr_state
(
lvl
,
...
...
@@ -398,7 +415,8 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
psci_power_state_t
*
state_info
)
{
unsigned
int
lvl
,
parent_idx
,
cpu_idx
=
plat_my_core_pos
();
unsigned
int
start_idx
,
ncpus
;
int
start_idx
;
unsigned
int
ncpus
;
plat_local_state_t
target_state
,
*
req_states
;
assert
(
end_pwrlvl
<=
PLAT_MAX_PWR_LVL
);
...
...
@@ -406,7 +424,7 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
/* For level 0, the requested state will be equivalent
to target state */
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
U
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
/* First update the requested power state */
psci_set_req_local_pwr_state
(
lvl
,
cpu_idx
,
...
...
@@ -428,7 +446,7 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
state_info
->
pwr_domain_state
[
lvl
]
=
target_state
;
/* Break early if the negotiated target power state is RUN */
if
(
is_local_state_run
(
state_info
->
pwr_domain_state
[
lvl
]))
if
(
is_local_state_run
(
state_info
->
pwr_domain_state
[
lvl
])
!=
0
)
break
;
parent_idx
=
psci_non_cpu_pd_nodes
[
parent_idx
].
parent_node
;
...
...
@@ -440,7 +458,7 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
* We update the requested power state from state_info and then
* set the target state as RUN.
*/
for
(
lvl
=
lvl
+
1
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
for
(
lvl
=
lvl
+
1
U
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
psci_set_req_local_pwr_state
(
lvl
,
cpu_idx
,
state_info
->
pwr_domain_state
[
lvl
]);
state_info
->
pwr_domain_state
[
lvl
]
=
PSCI_LOCAL_STATE_RUN
;
...
...
@@ -478,7 +496,7 @@ int psci_validate_suspend_req(const psci_power_state_t *state_info,
/* All power domain levels are in a RUN state to begin with */
deepest_state_type
=
STATE_TYPE_RUN
;
for
(
i
=
target_lvl
;
i
>=
PSCI_CPU_PWR_LVL
;
i
--
)
{
for
(
i
=
(
int
)
target_lvl
;
i
>=
(
int
)
PSCI_CPU_PWR_LVL
;
i
--
)
{
state
=
state_info
->
pwr_domain_state
[
i
];
req_state_type
=
find_local_state_type
(
state
);
...
...
@@ -507,8 +525,9 @@ int psci_validate_suspend_req(const psci_power_state_t *state_info,
* has to be invalid and max retention level has to be a valid power
* level.
*/
if
(
!
is_power_down_state
&&
(
max_off_lvl
!=
PSCI_INVALID_PWR_LVL
||
max_retn_lvl
==
PSCI_INVALID_PWR_LVL
))
if
((
is_power_down_state
==
0U
)
&&
((
max_off_lvl
!=
PSCI_INVALID_PWR_LVL
)
||
(
max_retn_lvl
==
PSCI_INVALID_PWR_LVL
)))
return
PSCI_E_INVALID_PARAMS
;
return
PSCI_E_SUCCESS
;
...
...
@@ -522,9 +541,9 @@ unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info)
{
int
i
;
for
(
i
=
PLAT_MAX_PWR_LVL
;
i
>=
PSCI_CPU_PWR_LVL
;
i
--
)
{
if
(
is_local_state_off
(
state_info
->
pwr_domain_state
[
i
]))
return
i
;
for
(
i
=
(
int
)
PLAT_MAX_PWR_LVL
;
i
>=
(
int
)
PSCI_CPU_PWR_LVL
;
i
--
)
{
if
(
is_local_state_off
(
state_info
->
pwr_domain_state
[
i
])
!=
0
)
return
(
unsigned
int
)
i
;
}
return
PSCI_INVALID_PWR_LVL
;
...
...
@@ -538,9 +557,9 @@ unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info)
{
int
i
;
for
(
i
=
PLAT_MAX_PWR_LVL
;
i
>=
PSCI_CPU_PWR_LVL
;
i
--
)
{
if
(
!
is_local_state_run
(
state_info
->
pwr_domain_state
[
i
]))
return
i
;
for
(
i
=
(
int
)
PLAT_MAX_PWR_LVL
;
i
>=
(
int
)
PSCI_CPU_PWR_LVL
;
i
--
)
{
if
(
is_local_state_run
(
state_info
->
pwr_domain_state
[
i
])
==
0
)
return
(
unsigned
int
)
i
;
}
return
PSCI_INVALID_PWR_LVL
;
...
...
@@ -551,14 +570,13 @@ unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info)
* tree that the operation should be applied to. It picks up locks in order of
* increasing power domain level in the range specified.
******************************************************************************/
void
psci_acquire_pwr_domain_locks
(
unsigned
int
end_pwrlvl
,
unsigned
int
cpu_idx
)
void
psci_acquire_pwr_domain_locks
(
unsigned
int
end_pwrlvl
,
int
cpu_idx
)
{
unsigned
int
parent_idx
=
psci_cpu_pd_nodes
[
cpu_idx
].
parent_node
;
unsigned
int
level
;
/* No locking required for level 0. Hence start locking from level 1 */
for
(
level
=
PSCI_CPU_PWR_LVL
+
1
;
level
<=
end_pwrlvl
;
level
++
)
{
for
(
level
=
PSCI_CPU_PWR_LVL
+
1
U
;
level
<=
end_pwrlvl
;
level
++
)
{
psci_lock_get
(
&
psci_non_cpu_pd_nodes
[
parent_idx
]);
parent_idx
=
psci_non_cpu_pd_nodes
[
parent_idx
].
parent_node
;
}
...
...
@@ -569,18 +587,17 @@ void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
* tree that the operation should be applied to. It releases the locks in order
* of decreasing power domain level in the range specified.
******************************************************************************/
void
psci_release_pwr_domain_locks
(
unsigned
int
end_pwrlvl
,
unsigned
int
cpu_idx
)
void
psci_release_pwr_domain_locks
(
unsigned
int
end_pwrlvl
,
int
cpu_idx
)
{
unsigned
int
parent_idx
,
parent_nodes
[
PLAT_MAX_PWR_LVL
]
=
{
0
};
int
level
;
unsigned
int
level
;
/* Get the parent nodes */
psci_get_parent_pwr_domain_nodes
(
cpu_idx
,
end_pwrlvl
,
parent_nodes
);
/* Unlock top down. No unlocking required for level 0. */
for
(
level
=
end_pwrlvl
;
level
>=
PSCI_CPU_PWR_LVL
+
1
;
level
--
)
{
parent_idx
=
parent_nodes
[
level
-
1
];
for
(
level
=
end_pwrlvl
;
level
>=
PSCI_CPU_PWR_LVL
+
1
U
;
level
--
)
{
parent_idx
=
parent_nodes
[
level
-
1
U
];
psci_lock_release
(
&
psci_non_cpu_pd_nodes
[
parent_idx
]);
}
}
...
...
@@ -656,11 +673,12 @@ static int psci_get_ns_ep_info(entry_point_info_t *ep,
u_register_t
ns_scr_el3
=
read_scr_el3
();
u_register_t
ns_sctlr_el1
=
read_sctlr_el1
();
sctlr
=
ns_scr_el3
&
SCR_HCE_BIT
?
read_sctlr_el2
()
:
ns_sctlr_el1
;
sctlr
=
((
ns_scr_el3
&
SCR_HCE_BIT
)
!=
0U
)
?
read_sctlr_el2
()
:
ns_sctlr_el1
;
ee
=
0
;
ep_attr
=
NON_SECURE
|
EP_ST_DISABLE
;
if
(
sctlr
&
SCTLR_EE_BIT
)
{
if
(
(
sctlr
&
SCTLR_EE_BIT
)
!=
0U
)
{
ep_attr
|=
EP_EE_BIG
;
ee
=
1
;
}
...
...
@@ -674,21 +692,22 @@ static int psci_get_ns_ep_info(entry_point_info_t *ep,
* Figure out whether the cpu enters the non-secure address space
* in aarch32 or aarch64
*/
if
(
ns_scr_el3
&
SCR_RW_BIT
)
{
if
(
(
ns_scr_el3
&
SCR_RW_BIT
)
!=
0U
)
{
/*
* Check whether a Thumb entry point has been provided for an
* aarch64 EL
*/
if
(
entrypoint
&
0x1
)
if
(
(
entrypoint
&
0x1
UL
)
!=
0UL
)
return
PSCI_E_INVALID_ADDRESS
;
mode
=
ns_scr_el3
&
SCR_HCE_BIT
?
MODE_EL2
:
MODE_EL1
;
mode
=
((
ns_scr_el3
&
SCR_HCE_BIT
)
!=
0U
)
?
MODE_EL2
:
MODE_EL1
;
ep
->
spsr
=
SPSR_64
(
mode
,
MODE_SP_ELX
,
DISABLE_ALL_EXCEPTIONS
);
}
else
{
mode
=
ns_scr_el3
&
SCR_HCE_BIT
?
MODE32_hyp
:
MODE32_svc
;
mode
=
((
ns_scr_el3
&
SCR_HCE_BIT
)
!=
0U
)
?
MODE32_hyp
:
MODE32_svc
;
/*
* TODO: Choose async. exception bits if HYP mode is not
...
...
@@ -715,7 +734,7 @@ int psci_validate_entry_point(entry_point_info_t *ep,
int
rc
;
/* Validate the entrypoint using platform psci_ops */
if
(
psci_plat_pm_ops
->
validate_ns_entrypoint
)
{
if
(
psci_plat_pm_ops
->
validate_ns_entrypoint
!=
NULL
)
{
rc
=
psci_plat_pm_ops
->
validate_ns_entrypoint
(
entrypoint
);
if
(
rc
!=
PSCI_E_SUCCESS
)
return
PSCI_E_INVALID_ADDRESS
;
...
...
@@ -741,7 +760,8 @@ int psci_validate_entry_point(entry_point_info_t *ep,
******************************************************************************/
void
psci_warmboot_entrypoint
(
void
)
{
unsigned
int
end_pwrlvl
,
cpu_idx
=
plat_my_core_pos
();
unsigned
int
end_pwrlvl
;
int
cpu_idx
=
(
int
)
plat_my_core_pos
();
psci_power_state_t
state_info
=
{
{
PSCI_LOCAL_STATE_RUN
}
};
/*
...
...
@@ -764,8 +784,7 @@ void psci_warmboot_entrypoint(void)
* that by the time all locks are taken, the system topology is snapshot
* and state management can be done safely.
*/
psci_acquire_pwr_domain_locks
(
end_pwrlvl
,
cpu_idx
);
psci_acquire_pwr_domain_locks
(
end_pwrlvl
,
cpu_idx
);
psci_get_target_local_pwr_states
(
end_pwrlvl
,
&
state_info
);
...
...
@@ -810,8 +829,7 @@ void psci_warmboot_entrypoint(void)
* This loop releases the lock corresponding to each power level
* in the reverse order to which they were acquired.
*/
psci_release_pwr_domain_locks
(
end_pwrlvl
,
cpu_idx
);
psci_release_pwr_domain_locks
(
end_pwrlvl
,
cpu_idx
);
}
/*******************************************************************************
...
...
@@ -821,13 +839,13 @@ void psci_warmboot_entrypoint(void)
******************************************************************************/
void
psci_register_spd_pm_hook
(
const
spd_pm_ops_t
*
pm
)
{
assert
(
pm
);
assert
(
pm
!=
NULL
);
psci_spd_pm
=
pm
;
if
(
pm
->
svc_migrate
)
if
(
pm
->
svc_migrate
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_MIG_AARCH64
);
if
(
pm
->
svc_migrate_info
)
if
(
pm
->
svc_migrate_info
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_MIG_INFO_UP_CPU_AARCH64
)
|
define_psci_cap
(
PSCI_MIG_INFO_TYPE
);
}
...
...
@@ -843,13 +861,13 @@ int psci_spd_migrate_info(u_register_t *mpidr)
{
int
rc
;
if
(
!
psci_spd_pm
||
!
psci_spd_pm
->
svc_migrate_info
)
if
(
(
psci_spd_pm
==
NULL
)
||
(
psci_spd_pm
->
svc_migrate_info
==
NULL
)
)
return
PSCI_E_NOT_SUPPORTED
;
rc
=
psci_spd_pm
->
svc_migrate_info
(
mpidr
);
assert
(
rc
==
PSCI_TOS_UP_MIG_CAP
||
rc
==
PSCI_TOS_NOT_UP_MIG_CAP
\
||
rc
==
PSCI_TOS_NOT_PRESENT_MP
||
rc
==
PSCI_E_NOT_SUPPORTED
);
assert
(
(
rc
==
PSCI_TOS_UP_MIG_CAP
)
||
(
rc
==
PSCI_TOS_NOT_UP_MIG_CAP
)
||
(
rc
==
PSCI_TOS_NOT_PRESENT_MP
)
||
(
rc
==
PSCI_E_NOT_SUPPORTED
)
)
;
return
rc
;
}
...
...
@@ -862,7 +880,7 @@ int psci_spd_migrate_info(u_register_t *mpidr)
void
psci_print_power_domain_map
(
void
)
{
#if LOG_LEVEL >= LOG_LEVEL_INFO
unsigned
int
idx
;
int
idx
;
plat_local_state_t
state
;
plat_local_state_type_t
state_type
;
...
...
@@ -908,16 +926,16 @@ void psci_print_power_domain_map(void)
*****************************************************************************/
int
psci_secondaries_brought_up
(
void
)
{
unsigned
int
idx
,
n_valid
=
0
;
unsigned
int
idx
,
n_valid
=
0
U
;
for
(
idx
=
0
;
idx
<
ARRAY_SIZE
(
psci_cpu_pd_nodes
);
idx
++
)
{
for
(
idx
=
0
U
;
idx
<
ARRAY_SIZE
(
psci_cpu_pd_nodes
);
idx
++
)
{
if
(
psci_cpu_pd_nodes
[
idx
].
mpidr
!=
PSCI_INVALID_MPIDR
)
n_valid
++
;
}
assert
(
n_valid
);
assert
(
n_valid
>
0U
);
return
(
n_valid
>
1
)
;
return
(
n_valid
>
1
U
)
?
1
:
0
;
}
#if ENABLE_PLAT_COMPAT
...
...
@@ -964,8 +982,8 @@ int psci_get_suspend_stateid_by_mpidr(unsigned long mpidr)
return
PSCI_INVALID_DATA
;
/* Sanity check to verify that the CPU is in CPU_SUSPEND */
if
(
psci_get_aff_info_state_by_idx
(
cpu_idx
)
==
AFF_STATE_ON
&&
!
is_local_state_run
(
psci_get_cpu_local_state_by_idx
(
cpu_idx
)))
if
(
(
psci_get_aff_info_state_by_idx
(
cpu_idx
)
==
AFF_STATE_ON
)
&&
(
!
is_local_state_run
(
psci_get_cpu_local_state_by_idx
(
cpu_idx
)))
)
return
psci_get_pstate_id
(
psci_power_state_compat
[
cpu_idx
]);
return
PSCI_INVALID_DATA
;
...
...
This diff is collapsed.
Click to expand it.
lib/psci/psci_main.c
View file @
60e062fb
...
...
@@ -82,8 +82,8 @@ int psci_cpu_suspend(unsigned int power_state,
}
/* Fast path for CPU standby.*/
if
(
is_cpu_standby_req
(
is_power_down_state
,
target_pwrlvl
))
{
if
(
!
psci_plat_pm_ops
->
cpu_standby
)
if
(
is_cpu_standby_req
(
is_power_down_state
,
target_pwrlvl
)
!=
0
)
{
if
(
psci_plat_pm_ops
->
cpu_standby
==
NULL
)
return
PSCI_E_INVALID_PARAMS
;
/*
...
...
@@ -128,7 +128,7 @@ int psci_cpu_suspend(unsigned int power_state,
* If a power down state has been requested, we need to verify entry
* point and program entry information.
*/
if
(
is_power_down_state
)
{
if
(
is_power_down_state
!=
0U
)
{
rc
=
psci_validate_entry_point
(
&
ep
,
entrypoint
,
context_id
);
if
(
rc
!=
PSCI_E_SUCCESS
)
return
rc
;
...
...
@@ -156,7 +156,7 @@ int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id)
entry_point_info_t
ep
;
/* Check if the current CPU is the last ON CPU in the system */
if
(
!
psci_is_last_on_cpu
())
if
(
psci_is_last_on_cpu
()
==
0U
)
return
PSCI_E_DENIED
;
/* Validate the entry point and get the entry_point_info */
...
...
@@ -171,7 +171,8 @@ int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id)
assert
(
psci_find_target_suspend_lvl
(
&
state_info
)
==
PLAT_MAX_PWR_LVL
);
assert
(
psci_validate_suspend_req
(
&
state_info
,
PSTATE_TYPE_POWERDOWN
)
==
PSCI_E_SUCCESS
);
assert
(
is_local_state_off
(
state_info
.
pwr_domain_state
[
PLAT_MAX_PWR_LVL
]));
assert
(
is_local_state_off
(
state_info
.
pwr_domain_state
[
PLAT_MAX_PWR_LVL
])
!=
0
);
/*
* Do what is needed to enter the system suspend state. This function
...
...
@@ -236,7 +237,8 @@ int psci_affinity_info(u_register_t target_affinity,
* target CPUs shutdown was not seen by the current CPU's cluster. And
* so the cache may contain stale data for the target CPU.
*/
flush_cpu_data_by_index
(
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
flush_cpu_data_by_index
((
unsigned
int
)
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
return
psci_get_aff_info_state_by_idx
(
target_idx
);
}
...
...
@@ -263,10 +265,10 @@ int psci_migrate(u_register_t target_cpu)
if
(
rc
!=
PSCI_E_SUCCESS
)
return
PSCI_E_INVALID_PARAMS
;
assert
(
psci_spd_pm
&&
psci_spd_pm
->
svc_migrate
);
assert
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_migrate
!=
NULL
)
);
rc
=
psci_spd_pm
->
svc_migrate
(
read_mpidr_el1
(),
target_cpu
);
assert
(
rc
==
PSCI_E_SUCCESS
||
rc
==
PSCI_E_INTERN_FAIL
);
assert
(
(
rc
==
PSCI_E_SUCCESS
)
||
(
rc
==
PSCI_E_INTERN_FAIL
)
)
;
return
rc
;
}
...
...
@@ -278,7 +280,7 @@ int psci_migrate_info_type(void)
return
psci_spd_migrate_info
(
&
resident_cpu_mpidr
);
}
long
psci_migrate_info_up_cpu
(
void
)
u_register_t
psci_migrate_info_up_cpu
(
void
)
{
u_register_t
resident_cpu_mpidr
;
int
rc
;
...
...
@@ -288,8 +290,8 @@ long psci_migrate_info_up_cpu(void)
* psci_spd_migrate_info() returns.
*/
rc
=
psci_spd_migrate_info
(
&
resident_cpu_mpidr
);
if
(
rc
!=
PSCI_TOS_NOT_UP_MIG_CAP
&&
rc
!=
PSCI_TOS_UP_MIG_CAP
)
return
PSCI_E_INVALID_PARAMS
;
if
(
(
rc
!=
PSCI_TOS_NOT_UP_MIG_CAP
)
&&
(
rc
!=
PSCI_TOS_UP_MIG_CAP
)
)
return
(
u_register_t
)(
register_t
)
PSCI_E_INVALID_PARAMS
;
return
resident_cpu_mpidr
;
}
...
...
@@ -312,10 +314,11 @@ int psci_node_hw_state(u_register_t target_cpu,
* Dispatch this call to platform to query power controller, and pass on
* to the caller what it returns
*/
assert
(
psci_plat_pm_ops
->
get_node_hw_state
);
assert
(
psci_plat_pm_ops
->
get_node_hw_state
!=
NULL
);
rc
=
psci_plat_pm_ops
->
get_node_hw_state
(
target_cpu
,
power_level
);
assert
((
rc
>=
HW_ON
&&
rc
<=
HW_STANDBY
)
||
rc
==
PSCI_E_NOT_SUPPORTED
||
rc
==
PSCI_E_INVALID_PARAMS
);
assert
(((
rc
>=
HW_ON
)
&&
(
rc
<=
HW_STANDBY
))
||
(
rc
==
PSCI_E_NOT_SUPPORTED
)
||
(
rc
==
PSCI_E_INVALID_PARAMS
));
return
rc
;
}
...
...
@@ -337,17 +340,19 @@ int psci_features(unsigned int psci_fid)
/* Check if the psci fid is supported or not */
if
(
!
(
local_caps
&
define_psci_cap
(
psci_fid
)))
if
((
local_caps
&
define_psci_cap
(
psci_fid
))
==
0U
)
return
PSCI_E_NOT_SUPPORTED
;
/* Format the feature flags */
if
(
psci_fid
==
PSCI_CPU_SUSPEND_AARCH32
||
psci_fid
==
PSCI_CPU_SUSPEND_AARCH64
)
{
if
(
(
psci_fid
==
PSCI_CPU_SUSPEND_AARCH32
)
||
(
psci_fid
==
PSCI_CPU_SUSPEND_AARCH64
)
)
{
/*
* The trusted firmware does not support OS Initiated Mode.
*/
return
(
FF_PSTATE
<<
FF_PSTATE_SHIFT
)
|
((
!
FF_SUPPORTS_OS_INIT_MODE
)
<<
FF_MODE_SUPPORT_SHIFT
);
unsigned
int
ret
=
((
FF_PSTATE
<<
FF_PSTATE_SHIFT
)
|
(((
FF_SUPPORTS_OS_INIT_MODE
==
1U
)
?
0U
:
1U
)
<<
FF_MODE_SUPPORT_SHIFT
));
return
(
int
)
ret
;
}
/* Return 0 for all other fid's */
...
...
@@ -366,50 +371,62 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
void
*
handle
,
u_register_t
flags
)
{
u_register_t
ret
;
if
(
is_caller_secure
(
flags
))
return
SMC_UNK
;
return
(
u_register_t
)
SMC_UNK
;
/* Check the fid against the capabilities */
if
(
!
(
psci_caps
&
define_psci_cap
(
smc_fid
)))
return
SMC_UNK
;
if
((
psci_caps
&
define_psci_cap
(
smc_fid
))
==
0U
)
return
(
u_register_t
)
SMC_UNK
;
if
(((
smc_fid
>>
FUNCID_CC_SHIFT
)
&
FUNCID_CC_MASK
)
==
SMC_32
)
{
/* 32-bit PSCI function, clear top parameter bits */
x
1
=
(
uint32_t
)
x1
;
x
2
=
(
uint32_t
)
x2
;
x
3
=
(
uint32_t
)
x3
;
uint32_t
r
1
=
(
uint32_t
)
x1
;
uint32_t
r
2
=
(
uint32_t
)
x2
;
uint32_t
r
3
=
(
uint32_t
)
x3
;
switch
(
smc_fid
)
{
case
PSCI_VERSION
:
return
psci_version
();
ret
=
(
u_register_t
)
psci_version
();
break
;
case
PSCI_CPU_OFF
:
return
psci_cpu_off
();
ret
=
(
u_register_t
)
psci_cpu_off
();
break
;
case
PSCI_CPU_SUSPEND_AARCH32
:
return
psci_cpu_suspend
(
x1
,
x2
,
x3
);
ret
=
(
u_register_t
)
psci_cpu_suspend
(
r1
,
r2
,
r3
);
break
;
case
PSCI_CPU_ON_AARCH32
:
return
psci_cpu_on
(
x1
,
x2
,
x3
);
ret
=
(
u_register_t
)
psci_cpu_on
(
r1
,
r2
,
r3
);
break
;
case
PSCI_AFFINITY_INFO_AARCH32
:
return
psci_affinity_info
(
x1
,
x2
);
ret
=
(
u_register_t
)
psci_affinity_info
(
r1
,
r2
);
break
;
case
PSCI_MIG_AARCH32
:
return
psci_migrate
(
x1
);
ret
=
(
u_register_t
)
psci_migrate
(
r1
);
break
;
case
PSCI_MIG_INFO_TYPE
:
return
psci_migrate_info_type
();
ret
=
(
u_register_t
)
psci_migrate_info_type
();
break
;
case
PSCI_MIG_INFO_UP_CPU_AARCH32
:
return
psci_migrate_info_up_cpu
();
ret
=
psci_migrate_info_up_cpu
();
break
;
case
PSCI_NODE_HW_STATE_AARCH32
:
return
psci_node_hw_state
(
x1
,
x2
);
ret
=
(
u_register_t
)
psci_node_hw_state
(
r1
,
r2
);
break
;
case
PSCI_SYSTEM_SUSPEND_AARCH32
:
return
psci_system_suspend
(
x1
,
x2
);
ret
=
(
u_register_t
)
psci_system_suspend
(
r1
,
r2
);
break
;
case
PSCI_SYSTEM_OFF
:
psci_system_off
();
...
...
@@ -422,26 +439,34 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
break
;
case
PSCI_FEATURES
:
return
psci_features
(
x1
);
ret
=
(
u_register_t
)
psci_features
(
r1
);
break
;
#if ENABLE_PSCI_STAT
case
PSCI_STAT_RESIDENCY_AARCH32
:
return
psci_stat_residency
(
x1
,
x2
);
ret
=
psci_stat_residency
(
r1
,
r2
);
break
;
case
PSCI_STAT_COUNT_AARCH32
:
return
psci_stat_count
(
x1
,
x2
);
ret
=
psci_stat_count
(
r1
,
r2
);
break
;
#endif
case
PSCI_MEM_PROTECT
:
return
psci_mem_protect
(
x1
);
ret
=
psci_mem_protect
(
r1
);
break
;
case
PSCI_MEM_CHK_RANGE_AARCH32
:
return
psci_mem_chk_range
(
x1
,
x2
);
ret
=
psci_mem_chk_range
(
r1
,
r2
);
break
;
case
PSCI_SYSTEM_RESET2_AARCH32
:
/* We should never return from psci_system_reset2() */
return
psci_system_reset2
(
x1
,
x2
);
ret
=
psci_system_reset2
(
r1
,
r2
);
break
;
default:
WARN
(
"Unimplemented PSCI Call: 0x%x
\n
"
,
smc_fid
);
ret
=
(
u_register_t
)
SMC_UNK
;
break
;
}
}
else
{
...
...
@@ -449,46 +474,61 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
switch
(
smc_fid
)
{
case
PSCI_CPU_SUSPEND_AARCH64
:
return
psci_cpu_suspend
(
x1
,
x2
,
x3
);
ret
=
(
u_register_t
)
psci_cpu_suspend
((
unsigned
int
)
x1
,
x2
,
x3
);
break
;
case
PSCI_CPU_ON_AARCH64
:
return
psci_cpu_on
(
x1
,
x2
,
x3
);
ret
=
(
u_register_t
)
psci_cpu_on
(
x1
,
x2
,
x3
);
break
;
case
PSCI_AFFINITY_INFO_AARCH64
:
return
psci_affinity_info
(
x1
,
x2
);
ret
=
(
u_register_t
)
psci_affinity_info
(
x1
,
(
unsigned
int
)
x2
);
break
;
case
PSCI_MIG_AARCH64
:
return
psci_migrate
(
x1
);
ret
=
(
u_register_t
)
psci_migrate
(
x1
);
break
;
case
PSCI_MIG_INFO_UP_CPU_AARCH64
:
return
psci_migrate_info_up_cpu
();
ret
=
psci_migrate_info_up_cpu
();
break
;
case
PSCI_NODE_HW_STATE_AARCH64
:
return
psci_node_hw_state
(
x1
,
x2
);
ret
=
(
u_register_t
)
psci_node_hw_state
(
x1
,
(
unsigned
int
)
x2
);
break
;
case
PSCI_SYSTEM_SUSPEND_AARCH64
:
return
psci_system_suspend
(
x1
,
x2
);
ret
=
(
u_register_t
)
psci_system_suspend
(
x1
,
x2
);
break
;
#if ENABLE_PSCI_STAT
case
PSCI_STAT_RESIDENCY_AARCH64
:
return
psci_stat_residency
(
x1
,
x2
);
ret
=
psci_stat_residency
(
x1
,
(
unsigned
int
)
x2
);
break
;
case
PSCI_STAT_COUNT_AARCH64
:
return
psci_stat_count
(
x1
,
x2
);
ret
=
psci_stat_count
(
x1
,
(
unsigned
int
)
x2
);
break
;
#endif
case
PSCI_MEM_CHK_RANGE_AARCH64
:
return
psci_mem_chk_range
(
x1
,
x2
);
ret
=
psci_mem_chk_range
(
x1
,
x2
);
break
;
case
PSCI_SYSTEM_RESET2_AARCH64
:
/* We should never return from psci_system_reset2() */
return
psci_system_reset2
(
x1
,
x2
);
ret
=
psci_system_reset2
((
uint32_t
)
x1
,
x2
);
break
;
default:
WARN
(
"Unimplemented PSCI Call: 0x%x
\n
"
,
smc_fid
);
ret
=
(
u_register_t
)
SMC_UNK
;
break
;
}
}
WARN
(
"Unimplemented PSCI Call: 0x%x
\n
"
,
smc_fid
);
return
SMC_UNK
;
return
ret
;
}
This diff is collapsed.
Click to expand it.
lib/psci/psci_mem_protect.c
View file @
60e062fb
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017
-2018
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -9,30 +9,31 @@
#include <utils.h>
#include "psci_private.h"
in
t
psci_mem_protect
(
unsigned
int
enable
)
u_register_
t
psci_mem_protect
(
unsigned
int
enable
)
{
int
val
;
assert
(
psci_plat_pm_ops
->
read_mem_protect
);
assert
(
psci_plat_pm_ops
->
write_mem_protect
);
assert
(
psci_plat_pm_ops
->
read_mem_protect
!=
NULL
);
assert
(
psci_plat_pm_ops
->
write_mem_protect
!=
NULL
);
if
(
psci_plat_pm_ops
->
read_mem_protect
(
&
val
)
<
0
)
return
PSCI_E_NOT_SUPPORTED
;
return
(
u_register_t
)
PSCI_E_NOT_SUPPORTED
;
if
(
psci_plat_pm_ops
->
write_mem_protect
(
enable
)
<
0
)
return
PSCI_E_NOT_SUPPORTED
;
return
(
u_register_t
)
PSCI_E_NOT_SUPPORTED
;
return
val
!=
0
;
return
(
val
!=
0
)
?
1U
:
0U
;
}
in
t
psci_mem_chk_range
(
uintptr_t
base
,
u_register_t
length
)
u_register_
t
psci_mem_chk_range
(
uintptr_t
base
,
u_register_t
length
)
{
int
ret
;
assert
(
psci_plat_pm_ops
->
mem_protect_chk
);
assert
(
psci_plat_pm_ops
->
mem_protect_chk
!=
NULL
);
if
(
length
==
0
||
check_uptr_overflow
(
base
,
length
-
1
))
return
PSCI_E_DENIED
;
if
(
(
length
==
0
U
)
||
check_uptr_overflow
(
base
,
length
-
1U
))
return
(
u_register_t
)
PSCI_E_DENIED
;
ret
=
psci_plat_pm_ops
->
mem_protect_chk
(
base
,
length
);
return
(
ret
<
0
)
?
PSCI_E_DENIED
:
PSCI_E_SUCCESS
;
return
(
ret
<
0
)
?
(
u_register_t
)
PSCI_E_DENIED
:
(
u_register_t
)
PSCI_E_SUCCESS
;
}
This diff is collapsed.
Click to expand it.
lib/psci/psci_off.c
View file @
60e062fb
/*
* Copyright (c) 2013-201
7
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -40,14 +40,15 @@ static void psci_set_power_off_state(psci_power_state_t *state_info)
******************************************************************************/
int
psci_do_cpu_off
(
unsigned
int
end_pwrlvl
)
{
int
rc
=
PSCI_E_SUCCESS
,
idx
=
plat_my_core_pos
();
int
rc
=
PSCI_E_SUCCESS
;
int
idx
=
(
int
)
plat_my_core_pos
();
psci_power_state_t
state_info
;
/*
* This function must only be called on platforms where the
* CPU_OFF platform hooks have been implemented.
*/
assert
(
psci_plat_pm_ops
->
pwr_domain_off
);
assert
(
psci_plat_pm_ops
->
pwr_domain_off
!=
NULL
);
/* Construct the psci_power_state for CPU_OFF */
psci_set_power_off_state
(
&
state_info
);
...
...
@@ -57,17 +58,16 @@ int psci_do_cpu_off(unsigned int end_pwrlvl)
* level so that by the time all locks are taken, the system topology
* is snapshot and state management can be done safely.
*/
psci_acquire_pwr_domain_locks
(
end_pwrlvl
,
idx
);
psci_acquire_pwr_domain_locks
(
end_pwrlvl
,
idx
);
/*
* Call the cpu off handler registered by the Secure Payload Dispatcher
* to let it do any bookkeeping. Assume that the SPD always reports an
* E_DENIED error if SP refuse to power down
*/
if
(
psci_spd_pm
&&
psci_spd_pm
->
svc_off
)
{
if
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_off
!=
NULL
)
)
{
rc
=
psci_spd_pm
->
svc_off
(
0
);
if
(
rc
)
if
(
rc
!=
0
)
goto
exit
;
}
...
...
@@ -120,8 +120,7 @@ exit:
* Release the locks corresponding to each power level in the
* reverse order to which they were acquired.
*/
psci_release_pwr_domain_locks
(
end_pwrlvl
,
idx
);
psci_release_pwr_domain_locks
(
end_pwrlvl
,
idx
);
/*
* Check if all actions needed to safely power down this cpu have
...
...
@@ -154,7 +153,7 @@ exit:
PMF_NO_CACHE_MAINT
);
#endif
if
(
psci_plat_pm_ops
->
pwr_domain_pwr_down_wfi
)
{
if
(
psci_plat_pm_ops
->
pwr_domain_pwr_down_wfi
!=
NULL
)
{
/* This function must not return */
psci_plat_pm_ops
->
pwr_domain_pwr_down_wfi
(
&
state_info
);
}
else
{
...
...
This diff is collapsed.
Click to expand it.
lib/psci/psci_on.c
View file @
60e062fb
/*
* Copyright (c) 2013-201
7
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -15,6 +15,19 @@
#include <stddef.h>
#include "psci_private.h"
/*
* Helper functions for the CPU level spinlocks
*/
static
inline
void
psci_spin_lock_cpu
(
int
idx
)
{
spin_lock
(
&
psci_cpu_pd_nodes
[
idx
].
cpu_lock
);
}
static
inline
void
psci_spin_unlock_cpu
(
int
idx
)
{
spin_unlock
(
&
psci_cpu_pd_nodes
[
idx
].
cpu_lock
);
}
/*******************************************************************************
* This function checks whether a cpu which has been requested to be turned on
* is OFF to begin with.
...
...
@@ -42,22 +55,22 @@ static int cpu_on_validate_state(aff_info_state_t aff_state)
* platform handler as it can return error.
******************************************************************************/
int
psci_cpu_on_start
(
u_register_t
target_cpu
,
entry_point_info_t
*
ep
)
const
entry_point_info_t
*
ep
)
{
int
rc
;
unsigned
int
target_idx
=
plat_core_pos_by_mpidr
(
target_cpu
);
aff_info_state_t
target_aff_state
;
int
target_idx
=
plat_core_pos_by_mpidr
(
target_cpu
);
/* Calling function must supply valid input arguments */
assert
(
(
int
)
target_idx
>=
0
);
assert
(
target_idx
>=
0
);
assert
(
ep
!=
NULL
);
/*
* This function must only be called on platforms where the
* CPU_ON platform hooks have been implemented.
*/
assert
(
psci_plat_pm_ops
->
pwr_domain_on
&&
psci_plat_pm_ops
->
pwr_domain_on_finish
);
assert
(
(
psci_plat_pm_ops
->
pwr_domain_on
!=
NULL
)
&&
(
psci_plat_pm_ops
->
pwr_domain_on_finish
!=
NULL
)
);
/* Protect against multiple CPUs trying to turn ON the same target CPU */
psci_spin_lock_cpu
(
target_idx
);
...
...
@@ -78,7 +91,8 @@ int psci_cpu_on_start(u_register_t target_cpu,
* target CPUs shutdown was not seen by the current CPU's cluster. And
* so the cache may contain stale data for the target CPU.
*/
flush_cpu_data_by_index
(
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
flush_cpu_data_by_index
((
unsigned
int
)
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
rc
=
cpu_on_validate_state
(
psci_get_aff_info_state_by_idx
(
target_idx
));
if
(
rc
!=
PSCI_E_SUCCESS
)
goto
exit
;
...
...
@@ -88,7 +102,7 @@ int psci_cpu_on_start(u_register_t target_cpu,
* to let it do any bookeeping. If the handler encounters an error, it's
* expected to assert within
*/
if
(
psci_spd_pm
&&
psci_spd_pm
->
svc_on
)
if
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_on
!=
NULL
)
)
psci_spd_pm
->
svc_on
(
target_cpu
);
/*
...
...
@@ -97,7 +111,8 @@ int psci_cpu_on_start(u_register_t target_cpu,
* turned OFF.
*/
psci_set_aff_info_state_by_idx
(
target_idx
,
AFF_STATE_ON_PENDING
);
flush_cpu_data_by_index
(
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
flush_cpu_data_by_index
((
unsigned
int
)
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
/*
* The cache line invalidation by the target CPU after setting the
...
...
@@ -109,9 +124,11 @@ int psci_cpu_on_start(u_register_t target_cpu,
if
(
target_aff_state
!=
AFF_STATE_ON_PENDING
)
{
assert
(
target_aff_state
==
AFF_STATE_OFF
);
psci_set_aff_info_state_by_idx
(
target_idx
,
AFF_STATE_ON_PENDING
);
flush_cpu_data_by_index
(
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
flush_cpu_data_by_index
((
unsigned
int
)
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
assert
(
psci_get_aff_info_state_by_idx
(
target_idx
)
==
AFF_STATE_ON_PENDING
);
assert
(
psci_get_aff_info_state_by_idx
(
target_idx
)
==
AFF_STATE_ON_PENDING
);
}
/*
...
...
@@ -123,15 +140,16 @@ int psci_cpu_on_start(u_register_t target_cpu,
* steps to power on.
*/
rc
=
psci_plat_pm_ops
->
pwr_domain_on
(
target_cpu
);
assert
(
rc
==
PSCI_E_SUCCESS
||
rc
==
PSCI_E_INTERN_FAIL
);
assert
(
(
rc
==
PSCI_E_SUCCESS
)
||
(
rc
==
PSCI_E_INTERN_FAIL
)
)
;
if
(
rc
==
PSCI_E_SUCCESS
)
/* Store the re-entry information for the non-secure world. */
cm_init_context_by_index
(
target_idx
,
ep
);
cm_init_context_by_index
(
(
unsigned
int
)
target_idx
,
ep
);
else
{
/* Restore the state on error. */
psci_set_aff_info_state_by_idx
(
target_idx
,
AFF_STATE_OFF
);
flush_cpu_data_by_index
(
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
flush_cpu_data_by_index
((
unsigned
int
)
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
}
exit:
...
...
@@ -144,8 +162,7 @@ exit:
* are called by the common finisher routine in psci_common.c. The `state_info`
* is the psci_power_state from which this CPU has woken up from.
******************************************************************************/
void
psci_cpu_on_finish
(
unsigned
int
cpu_idx
,
psci_power_state_t
*
state_info
)
void
psci_cpu_on_finish
(
int
cpu_idx
,
const
psci_power_state_t
*
state_info
)
{
/*
* Plat. management: Perform the platform specific actions
...
...
@@ -186,7 +203,7 @@ void psci_cpu_on_finish(unsigned int cpu_idx,
* Dispatcher to let it do any bookeeping. If the handler encounters an
* error, it's expected to assert within
*/
if
(
psci_spd_pm
&&
psci_spd_pm
->
svc_on_finish
)
if
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_on_finish
!=
NULL
)
)
psci_spd_pm
->
svc_on_finish
(
0
);
PUBLISH_EVENT
(
psci_cpu_on_finish
);
...
...
This diff is collapsed.
Click to expand it.
lib/psci/psci_private.h
View file @
60e062fb
...
...
@@ -4,70 +4,17 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
PSCI_PRIVATE_H
__
#define
__
PSCI_PRIVATE_H
__
#ifndef PSCI_PRIVATE_H
#define PSCI_PRIVATE_H
#include <arch.h>
#include <arch_helpers.h>
#include <bakery_lock.h>
#include <bl_common.h>
#include <cpu_data.h>
#include <psci.h>
#include <spinlock.h>
#if HW_ASSISTED_COHERENCY
/*
* On systems with hardware-assisted coherency, make PSCI cache operations NOP,
* as PSCI participants are cache-coherent, and there's no need for explicit
* cache maintenance operations or barriers to coordinate their state.
*/
#define psci_flush_dcache_range(addr, size)
#define psci_flush_cpu_data(member)
#define psci_inv_cpu_data(member)
#define psci_dsbish()
/*
* On systems where participant CPUs are cache-coherent, we can use spinlocks
* instead of bakery locks.
*/
#define DEFINE_PSCI_LOCK(_name) spinlock_t _name
#define DECLARE_PSCI_LOCK(_name) extern DEFINE_PSCI_LOCK(_name)
#define psci_lock_get(non_cpu_pd_node) \
spin_lock(&psci_locks[(non_cpu_pd_node)->lock_index])
#define psci_lock_release(non_cpu_pd_node) \
spin_unlock(&psci_locks[(non_cpu_pd_node)->lock_index])
#else
/*
* If not all PSCI participants are cache-coherent, perform cache maintenance
* and issue barriers wherever required to coordinate state.
*/
#define psci_flush_dcache_range(addr, size) flush_dcache_range(addr, size)
#define psci_flush_cpu_data(member) flush_cpu_data(member)
#define psci_inv_cpu_data(member) inv_cpu_data(member)
#define psci_dsbish() dsbish()
/*
* Use bakery locks for state coordination as not all PSCI participants are
* cache coherent.
*/
#define DEFINE_PSCI_LOCK(_name) DEFINE_BAKERY_LOCK(_name)
#define DECLARE_PSCI_LOCK(_name) DECLARE_BAKERY_LOCK(_name)
#define psci_lock_get(non_cpu_pd_node) \
bakery_lock_get(&psci_locks[(non_cpu_pd_node)->lock_index])
#define psci_lock_release(non_cpu_pd_node) \
bakery_lock_release(&psci_locks[(non_cpu_pd_node)->lock_index])
#endif
#define psci_lock_init(_non_cpu_pd_node, _idx) \
((_non_cpu_pd_node)[(_idx)].lock_index = (_idx))
/*
* The PSCI capability which are provided by the generic code but does not
* depend on the platform or spd capabilities.
...
...
@@ -94,37 +41,63 @@
define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64))
/*
* Helper macros to get/set the fields of PSCI per-cpu data.
*/
#define psci_set_aff_info_state(_aff_state) \
set_cpu_data(psci_svc_cpu_data.aff_info_state, _aff_state)
#define psci_get_aff_info_state() \
get_cpu_data(psci_svc_cpu_data.aff_info_state)
#define psci_get_aff_info_state_by_idx(_idx) \
get_cpu_data_by_index(_idx, psci_svc_cpu_data.aff_info_state)
#define psci_set_aff_info_state_by_idx(_idx, _aff_state) \
set_cpu_data_by_index(_idx, psci_svc_cpu_data.aff_info_state,\
_aff_state)
#define psci_get_suspend_pwrlvl() \
get_cpu_data(psci_svc_cpu_data.target_pwrlvl)
#define psci_set_suspend_pwrlvl(_target_lvl) \
set_cpu_data(psci_svc_cpu_data.target_pwrlvl, _target_lvl)
#define psci_set_cpu_local_state(_state) \
set_cpu_data(psci_svc_cpu_data.local_state, _state)
#define psci_get_cpu_local_state() \
get_cpu_data(psci_svc_cpu_data.local_state)
#define psci_get_cpu_local_state_by_idx(_idx) \
get_cpu_data_by_index(_idx, psci_svc_cpu_data.local_state)
/*
* Helper macros for the CPU level spinlocks
* Helper functions to get/set the fields of PSCI per-cpu data.
*/
#define psci_spin_lock_cpu(_idx) spin_lock(&psci_cpu_pd_nodes[_idx].cpu_lock)
#define psci_spin_unlock_cpu(_idx) spin_unlock(&psci_cpu_pd_nodes[_idx].cpu_lock)
/* Helper macro to identify a CPU standby request in PSCI Suspend call */
#define is_cpu_standby_req(_is_power_down_state, _retn_lvl) \
(((!(_is_power_down_state)) && ((_retn_lvl) == 0)) ? 1 : 0)
static
inline
void
psci_set_aff_info_state
(
aff_info_state_t
aff_state
)
{
set_cpu_data
(
psci_svc_cpu_data
.
aff_info_state
,
aff_state
);
}
static
inline
aff_info_state_t
psci_get_aff_info_state
(
void
)
{
return
get_cpu_data
(
psci_svc_cpu_data
.
aff_info_state
);
}
static
inline
aff_info_state_t
psci_get_aff_info_state_by_idx
(
int
idx
)
{
return
get_cpu_data_by_index
((
unsigned
int
)
idx
,
psci_svc_cpu_data
.
aff_info_state
);
}
static
inline
void
psci_set_aff_info_state_by_idx
(
int
idx
,
aff_info_state_t
aff_state
)
{
set_cpu_data_by_index
((
unsigned
int
)
idx
,
psci_svc_cpu_data
.
aff_info_state
,
aff_state
);
}
static
inline
unsigned
int
psci_get_suspend_pwrlvl
(
void
)
{
return
get_cpu_data
(
psci_svc_cpu_data
.
target_pwrlvl
);
}
static
inline
void
psci_set_suspend_pwrlvl
(
unsigned
int
target_lvl
)
{
set_cpu_data
(
psci_svc_cpu_data
.
target_pwrlvl
,
target_lvl
);
}
static
inline
void
psci_set_cpu_local_state
(
plat_local_state_t
state
)
{
set_cpu_data
(
psci_svc_cpu_data
.
local_state
,
state
);
}
static
inline
plat_local_state_t
psci_get_cpu_local_state
(
void
)
{
return
get_cpu_data
(
psci_svc_cpu_data
.
local_state
);
}
static
inline
plat_local_state_t
psci_get_cpu_local_state_by_idx
(
int
idx
)
{
return
get_cpu_data_by_index
((
unsigned
int
)
idx
,
psci_svc_cpu_data
.
local_state
);
}
/* Helper function to identify a CPU standby request in PSCI Suspend call */
static
inline
int
is_cpu_standby_req
(
unsigned
int
is_power_down_state
,
unsigned
int
retn_lvl
)
{
return
((
is_power_down_state
==
0U
)
&&
(
retn_lvl
==
0U
))
?
1
:
0
;
}
/*******************************************************************************
* The following two data structures implement the power domain tree. The tree
...
...
@@ -138,7 +111,7 @@ typedef struct non_cpu_pwr_domain_node {
* Index of the first CPU power domain node level 0 which has this node
* as its parent.
*/
unsigned
int
cpu_start_idx
;
int
cpu_start_idx
;
/*
* Number of CPU power domains which are siblings of the domain indexed
...
...
@@ -179,6 +152,95 @@ typedef struct cpu_pwr_domain_node {
spinlock_t
cpu_lock
;
}
cpu_pd_node_t
;
/*******************************************************************************
* The following are helpers and declarations of locks.
******************************************************************************/
#if HW_ASSISTED_COHERENCY
/*
* On systems where participant CPUs are cache-coherent, we can use spinlocks
* instead of bakery locks.
*/
#define DEFINE_PSCI_LOCK(_name) spinlock_t _name
#define DECLARE_PSCI_LOCK(_name) extern DEFINE_PSCI_LOCK(_name)
/* One lock is required per non-CPU power domain node */
DECLARE_PSCI_LOCK
(
psci_locks
[
PSCI_NUM_NON_CPU_PWR_DOMAINS
]);
/*
* On systems with hardware-assisted coherency, make PSCI cache operations NOP,
* as PSCI participants are cache-coherent, and there's no need for explicit
* cache maintenance operations or barriers to coordinate their state.
*/
static
inline
void
psci_flush_dcache_range
(
uintptr_t
__unused
addr
,
size_t
__unused
size
)
{
/* Empty */
}
#define psci_flush_cpu_data(member)
#define psci_inv_cpu_data(member)
static
inline
void
psci_dsbish
(
void
)
{
/* Empty */
}
static
inline
void
psci_lock_get
(
non_cpu_pd_node_t
*
non_cpu_pd_node
)
{
spin_lock
(
&
psci_locks
[
non_cpu_pd_node
->
lock_index
]);
}
static
inline
void
psci_lock_release
(
non_cpu_pd_node_t
*
non_cpu_pd_node
)
{
spin_unlock
(
&
psci_locks
[
non_cpu_pd_node
->
lock_index
]);
}
#else
/* if HW_ASSISTED_COHERENCY == 0 */
/*
* Use bakery locks for state coordination as not all PSCI participants are
* cache coherent.
*/
#define DEFINE_PSCI_LOCK(_name) DEFINE_BAKERY_LOCK(_name)
#define DECLARE_PSCI_LOCK(_name) DECLARE_BAKERY_LOCK(_name)
/* One lock is required per non-CPU power domain node */
DECLARE_PSCI_LOCK
(
psci_locks
[
PSCI_NUM_NON_CPU_PWR_DOMAINS
]);
/*
* If not all PSCI participants are cache-coherent, perform cache maintenance
* and issue barriers wherever required to coordinate state.
*/
static
inline
void
psci_flush_dcache_range
(
uintptr_t
addr
,
size_t
size
)
{
flush_dcache_range
(
addr
,
size
);
}
#define psci_flush_cpu_data(member) flush_cpu_data(member)
#define psci_inv_cpu_data(member) inv_cpu_data(member)
static
inline
void
psci_dsbish
(
void
)
{
dsbish
();
}
static
inline
void
psci_lock_get
(
non_cpu_pd_node_t
*
non_cpu_pd_node
)
{
bakery_lock_get
(
&
psci_locks
[
non_cpu_pd_node
->
lock_index
]);
}
static
inline
void
psci_lock_release
(
non_cpu_pd_node_t
*
non_cpu_pd_node
)
{
bakery_lock_release
(
&
psci_locks
[
non_cpu_pd_node
->
lock_index
]);
}
#endif
/* HW_ASSISTED_COHERENCY */
static
inline
void
psci_lock_init
(
non_cpu_pd_node_t
*
non_cpu_pd_node
,
unsigned
char
idx
)
{
non_cpu_pd_node
[
idx
].
lock_index
=
idx
;
}
/*******************************************************************************
* Data prototypes
******************************************************************************/
...
...
@@ -187,9 +249,6 @@ extern non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS];
extern
cpu_pd_node_t
psci_cpu_pd_nodes
[
PLATFORM_CORE_COUNT
];
extern
unsigned
int
psci_caps
;
/* One lock is required per non-CPU power domain node */
DECLARE_PSCI_LOCK
(
psci_locks
[
PSCI_NUM_NON_CPU_PWR_DOMAINS
]);
/*******************************************************************************
* SPD's power management hooks registered with PSCI
******************************************************************************/
...
...
@@ -208,15 +267,13 @@ void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
psci_power_state_t
*
target_state
);
int
psci_validate_entry_point
(
entry_point_info_t
*
ep
,
uintptr_t
entrypoint
,
u_register_t
context_id
);
void
psci_get_parent_pwr_domain_nodes
(
unsigned
int
cpu_idx
,
void
psci_get_parent_pwr_domain_nodes
(
int
cpu_idx
,
unsigned
int
end_lvl
,
unsigned
int
node_index
[]
);
unsigned
int
*
node_index
);
void
psci_do_state_coordination
(
unsigned
int
end_pwrlvl
,
psci_power_state_t
*
state_info
);
void
psci_acquire_pwr_domain_locks
(
unsigned
int
end_pwrlvl
,
unsigned
int
cpu_idx
);
void
psci_release_pwr_domain_locks
(
unsigned
int
end_pwrlvl
,
unsigned
int
cpu_idx
);
void
psci_acquire_pwr_domain_locks
(
unsigned
int
end_pwrlvl
,
int
cpu_idx
);
void
psci_release_pwr_domain_locks
(
unsigned
int
end_pwrlvl
,
int
cpu_idx
);
int
psci_validate_suspend_req
(
const
psci_power_state_t
*
state_info
,
unsigned
int
is_power_down_state
);
unsigned
int
psci_find_max_off_lvl
(
const
psci_power_state_t
*
state_info
);
...
...
@@ -236,22 +293,20 @@ void prepare_cpu_pwr_dwn(unsigned int power_level);
/* Private exported functions from psci_on.c */
int
psci_cpu_on_start
(
u_register_t
target_cpu
,
entry_point_info_t
*
ep
);
const
entry_point_info_t
*
ep
);
void
psci_cpu_on_finish
(
unsigned
int
cpu_idx
,
psci_power_state_t
*
state_info
);
void
psci_cpu_on_finish
(
int
cpu_idx
,
const
psci_power_state_t
*
state_info
);
/* Private exported functions from psci_off.c */
int
psci_do_cpu_off
(
unsigned
int
end_pwrlvl
);
/* Private exported functions from psci_suspend.c */
void
psci_cpu_suspend_start
(
entry_point_info_t
*
ep
,
void
psci_cpu_suspend_start
(
const
entry_point_info_t
*
ep
,
unsigned
int
end_pwrlvl
,
psci_power_state_t
*
state_info
,
unsigned
int
is_power_down_state
);
void
psci_cpu_suspend_finish
(
unsigned
int
cpu_idx
,
psci_power_state_t
*
state_info
);
void
psci_cpu_suspend_finish
(
int
cpu_idx
,
const
psci_power_state_t
*
state_info
);
/* Private exported functions from psci_helpers.S */
void
psci_do_pwrdown_cache_maintenance
(
unsigned
int
pwr_level
);
...
...
@@ -260,7 +315,7 @@ void psci_do_pwrup_cache_maintenance(void);
/* Private exported functions from psci_system_off.c */
void
__dead2
psci_system_off
(
void
);
void
__dead2
psci_system_reset
(
void
);
in
t
psci_system_reset2
(
uint32_t
reset_type
,
u_register_t
cookie
);
u_register_
t
psci_system_reset2
(
uint32_t
reset_type
,
u_register_t
cookie
);
/* Private exported functions from psci_stat.c */
void
psci_stats_update_pwr_down
(
unsigned
int
end_pwrlvl
,
...
...
@@ -273,7 +328,7 @@ u_register_t psci_stat_count(u_register_t target_cpu,
unsigned
int
power_state
);
/* Private exported functions from psci_mem_protect.c */
in
t
psci_mem_protect
(
unsigned
int
enable
);
in
t
psci_mem_chk_range
(
uintptr_t
base
,
u_register_t
length
);
u_register_
t
psci_mem_protect
(
unsigned
int
enable
);
u_register_
t
psci_mem_chk_range
(
uintptr_t
base
,
u_register_t
length
);
#endif
/*
__
PSCI_PRIVATE_H
__
*/
#endif
/* PSCI_PRIVATE_H */
This diff is collapsed.
Click to expand it.
lib/psci/psci_setup.c
View file @
60e062fb
/*
* Copyright (c) 2013-201
7
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -32,9 +32,9 @@ unsigned int psci_caps;
* Function which initializes the 'psci_non_cpu_pd_nodes' or the
* 'psci_cpu_pd_nodes' corresponding to the power level.
******************************************************************************/
static
void
psci_init_pwr_domain_node
(
unsigned
int
node_idx
,
static
void
psci_init_pwr_domain_node
(
unsigned
char
node_idx
,
unsigned
int
parent_idx
,
unsigned
int
level
)
unsigned
char
level
)
{
if
(
level
>
PSCI_CPU_PWR_LVL
)
{
psci_non_cpu_pd_nodes
[
node_idx
].
level
=
level
;
...
...
@@ -82,15 +82,15 @@ static void psci_init_pwr_domain_node(unsigned int node_idx,
*******************************************************************************/
static
void
psci_update_pwrlvl_limits
(
void
)
{
int
j
;
int
j
,
cpu_idx
;
unsigned
int
nodes_idx
[
PLAT_MAX_PWR_LVL
]
=
{
0
};
unsigned
int
temp_index
[
PLAT_MAX_PWR_LVL
]
,
cpu_idx
;
unsigned
int
temp_index
[
PLAT_MAX_PWR_LVL
];
for
(
cpu_idx
=
0
;
cpu_idx
<
PLATFORM_CORE_COUNT
;
cpu_idx
++
)
{
psci_get_parent_pwr_domain_nodes
(
cpu_idx
,
PLAT_MAX_PWR_LVL
,
(
unsigned
int
)
PLAT_MAX_PWR_LVL
,
temp_index
);
for
(
j
=
PLAT_MAX_PWR_LVL
-
1
;
j
>=
0
;
j
--
)
{
for
(
j
=
(
int
)
PLAT_MAX_PWR_LVL
-
1
;
j
>=
0
;
j
--
)
{
if
(
temp_index
[
j
]
!=
nodes_idx
[
j
])
{
nodes_idx
[
j
]
=
temp_index
[
j
];
psci_non_cpu_pd_nodes
[
nodes_idx
[
j
]].
cpu_start_idx
...
...
@@ -109,9 +109,10 @@ static void psci_update_pwrlvl_limits(void)
******************************************************************************/
static
void
populate_power_domain_tree
(
const
unsigned
char
*
topology
)
{
unsigned
int
i
,
j
=
0
,
num_nodes_at_lvl
=
1
,
num_nodes_at_next_lvl
;
unsigned
int
node_index
=
0
,
parent_node_index
=
0
,
num_children
;
int
level
=
PLAT_MAX_PWR_LVL
;
unsigned
int
i
,
j
=
0U
,
num_nodes_at_lvl
=
1U
,
num_nodes_at_next_lvl
;
unsigned
int
node_index
=
0U
,
num_children
;
int
parent_node_index
=
0
;
int
level
=
(
int
)
PLAT_MAX_PWR_LVL
;
/*
* For each level the inputs are:
...
...
@@ -122,8 +123,8 @@ static void populate_power_domain_tree(const unsigned char *topology)
* - Index of first free entry in psci_non_cpu_pd_nodes[] or
* psci_cpu_pd_nodes[] i.e. node_index depending upon the level.
*/
while
(
level
>=
PSCI_CPU_PWR_LVL
)
{
num_nodes_at_next_lvl
=
0
;
while
(
level
>=
(
int
)
PSCI_CPU_PWR_LVL
)
{
num_nodes_at_next_lvl
=
0
U
;
/*
* For each entry (parent node) at this level in the plat_array:
* - Find the number of children
...
...
@@ -132,16 +133,16 @@ static void populate_power_domain_tree(const unsigned char *topology)
* - Increment parent_node_index to point to the next parent
* - Accumulate the number of children at next level.
*/
for
(
i
=
0
;
i
<
num_nodes_at_lvl
;
i
++
)
{
for
(
i
=
0
U
;
i
<
num_nodes_at_lvl
;
i
++
)
{
assert
(
parent_node_index
<=
PSCI_NUM_NON_CPU_PWR_DOMAINS
);
num_children
=
topology
[
parent_node_index
];
for
(
j
=
node_index
;
j
<
node_index
+
num_children
;
j
++
)
psci_init_pwr_domain_node
(
j
,
j
<
(
node_index
+
num_children
)
;
j
++
)
psci_init_pwr_domain_node
(
(
unsigned
char
)
j
,
parent_node_index
-
1
,
level
);
(
unsigned
char
)
level
);
node_index
=
j
;
num_nodes_at_next_lvl
+=
num_children
;
...
...
@@ -152,12 +153,12 @@ static void populate_power_domain_tree(const unsigned char *topology)
level
--
;
/* Reset the index for the cpu power domain array */
if
(
level
==
PSCI_CPU_PWR_LVL
)
if
(
level
==
(
int
)
PSCI_CPU_PWR_LVL
)
node_index
=
0
;
}
/* Validate the sanity of array exported by the platform */
assert
(
j
==
PLATFORM_CORE_COUNT
);
assert
(
(
int
)
j
==
PLATFORM_CORE_COUNT
);
}
/*******************************************************************************
...
...
@@ -213,8 +214,9 @@ int psci_setup(const psci_lib_args_t *lib_args)
*/
psci_set_pwr_domains_to_run
(
PLAT_MAX_PWR_LVL
);
plat_setup_psci_ops
((
uintptr_t
)
lib_args
->
mailbox_ep
,
&
psci_plat_pm_ops
);
assert
(
psci_plat_pm_ops
);
(
void
)
plat_setup_psci_ops
((
uintptr_t
)
lib_args
->
mailbox_ep
,
&
psci_plat_pm_ops
);
assert
(
psci_plat_pm_ops
!=
NULL
);
/*
* Flush `psci_plat_pm_ops` as it will be accessed by secondary CPUs
...
...
@@ -226,29 +228,29 @@ int psci_setup(const psci_lib_args_t *lib_args)
/* Initialize the psci capability */
psci_caps
=
PSCI_GENERIC_CAP
;
if
(
psci_plat_pm_ops
->
pwr_domain_off
)
if
(
psci_plat_pm_ops
->
pwr_domain_off
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_CPU_OFF
);
if
(
psci_plat_pm_ops
->
pwr_domain_on
&&
psci_plat_pm_ops
->
pwr_domain_on_finish
)
if
(
(
psci_plat_pm_ops
->
pwr_domain_on
!=
NULL
)
&&
(
psci_plat_pm_ops
->
pwr_domain_on_finish
!=
NULL
)
)
psci_caps
|=
define_psci_cap
(
PSCI_CPU_ON_AARCH64
);
if
(
psci_plat_pm_ops
->
pwr_domain_suspend
&&
psci_plat_pm_ops
->
pwr_domain_suspend_finish
)
{
if
(
(
psci_plat_pm_ops
->
pwr_domain_suspend
!=
NULL
)
&&
(
psci_plat_pm_ops
->
pwr_domain_suspend_finish
!=
NULL
)
)
{
psci_caps
|=
define_psci_cap
(
PSCI_CPU_SUSPEND_AARCH64
);
if
(
psci_plat_pm_ops
->
get_sys_suspend_power_state
)
if
(
psci_plat_pm_ops
->
get_sys_suspend_power_state
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_SYSTEM_SUSPEND_AARCH64
);
}
if
(
psci_plat_pm_ops
->
system_off
)
if
(
psci_plat_pm_ops
->
system_off
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_SYSTEM_OFF
);
if
(
psci_plat_pm_ops
->
system_reset
)
if
(
psci_plat_pm_ops
->
system_reset
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_SYSTEM_RESET
);
if
(
psci_plat_pm_ops
->
get_node_hw_state
)
if
(
psci_plat_pm_ops
->
get_node_hw_state
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_NODE_HW_STATE_AARCH64
);
if
(
psci_plat_pm_ops
->
read_mem_protect
&&
psci_plat_pm_ops
->
write_mem_protect
)
if
(
(
psci_plat_pm_ops
->
read_mem_protect
!=
NULL
)
&&
(
psci_plat_pm_ops
->
write_mem_protect
!=
NULL
)
)
psci_caps
|=
define_psci_cap
(
PSCI_MEM_PROTECT
);
if
(
psci_plat_pm_ops
->
mem_protect_chk
)
if
(
psci_plat_pm_ops
->
mem_protect_chk
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_MEM_CHK_RANGE_AARCH64
);
if
(
psci_plat_pm_ops
->
system_reset2
)
if
(
psci_plat_pm_ops
->
system_reset2
!=
NULL
)
psci_caps
|=
define_psci_cap
(
PSCI_SYSTEM_RESET2_AARCH64
);
#if ENABLE_PSCI_STAT
...
...
@@ -266,7 +268,7 @@ int psci_setup(const psci_lib_args_t *lib_args)
******************************************************************************/
void
psci_arch_setup
(
void
)
{
#if ARM_ARCH_MAJOR > 7 || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
#if
(
ARM_ARCH_MAJOR > 7
)
|| defined(ARMV7_SUPPORTS_GENERIC_TIMER)
/* Program the counter frequency */
write_cntfrq_el0
(
plat_get_syscnt_freq2
());
#endif
...
...
This diff is collapsed.
Click to expand it.
lib/psci/psci_stat.c
View file @
60e062fb
/*
* Copyright (c) 2016-201
7
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -11,7 +11,7 @@
#include "psci_private.h"
#ifndef PLAT_MAX_PWR_LVL_STATES
#define PLAT_MAX_PWR_LVL_STATES
2
#define PLAT_MAX_PWR_LVL_STATES
2U
#endif
/* Following structure is used for PSCI STAT */
...
...
@@ -25,7 +25,7 @@ typedef struct psci_stat {
* that goes to power down in non cpu power domains.
*/
static
int
last_cpu_in_non_cpu_pd
[
PSCI_NUM_NON_CPU_PWR_DOMAINS
]
=
{
[
0
...
PSCI_NUM_NON_CPU_PWR_DOMAINS
-
1
]
=
-
1
};
[
0
...
PSCI_NUM_NON_CPU_PWR_DOMAINS
-
1
]
=
-
1
};
/*
* Following are used to store PSCI STAT values for
...
...
@@ -41,21 +41,21 @@ static psci_stat_t psci_non_cpu_stat[PSCI_NUM_NON_CPU_PWR_DOMAINS]
* local power state and power domain level. If the platform implements the
* `get_pwr_lvl_state_idx` pm hook, then that will be used to return the index.
*/
static
int
get_stat_idx
(
plat_local_state_t
local_state
,
int
pwr_lvl
)
static
int
get_stat_idx
(
plat_local_state_t
local_state
,
unsigned
int
pwr_lvl
)
{
int
idx
;
if
(
psci_plat_pm_ops
->
get_pwr_lvl_state_idx
==
NULL
)
{
assert
(
PLAT_MAX_PWR_LVL_STATES
==
2
);
if
(
is_local_state_retn
(
local_state
))
assert
(
PLAT_MAX_PWR_LVL_STATES
==
2
U
);
if
(
is_local_state_retn
(
local_state
)
!=
0
)
return
0
;
assert
(
is_local_state_off
(
local_state
));
assert
(
is_local_state_off
(
local_state
)
!=
0
);
return
1
;
}
idx
=
psci_plat_pm_ops
->
get_pwr_lvl_state_idx
(
local_state
,
pwr_lvl
);
assert
((
idx
>=
0
)
&&
(
idx
<
PLAT_MAX_PWR_LVL_STATES
));
assert
((
idx
>=
0
)
&&
(
idx
<
(
int
)
PLAT_MAX_PWR_LVL_STATES
));
return
idx
;
}
...
...
@@ -73,17 +73,18 @@ static int get_stat_idx(plat_local_state_t local_state, int pwr_lvl)
void
psci_stats_update_pwr_down
(
unsigned
int
end_pwrlvl
,
const
psci_power_state_t
*
state_info
)
{
unsigned
int
lvl
,
parent_idx
,
cpu_idx
=
plat_my_core_pos
();
unsigned
int
lvl
,
parent_idx
;
int
cpu_idx
=
(
int
)
plat_my_core_pos
();
assert
(
end_pwrlvl
<=
PLAT_MAX_PWR_LVL
);
assert
(
state_info
);
assert
(
state_info
!=
NULL
);
parent_idx
=
psci_cpu_pd_nodes
[
cpu_idx
].
parent_node
;
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
U
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
/* Break early if the target power state is RUN */
if
(
is_local_state_run
(
state_info
->
pwr_domain_state
[
lvl
]))
if
(
is_local_state_run
(
state_info
->
pwr_domain_state
[
lvl
])
!=
0
)
break
;
/*
...
...
@@ -105,13 +106,14 @@ void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
void
psci_stats_update_pwr_up
(
unsigned
int
end_pwrlvl
,
const
psci_power_state_t
*
state_info
)
{
unsigned
int
lvl
,
parent_idx
,
cpu_idx
=
plat_my_core_pos
();
unsigned
int
lvl
,
parent_idx
;
int
cpu_idx
=
(
int
)
plat_my_core_pos
();
int
stat_idx
;
plat_local_state_t
local_state
;
u_register_t
residency
;
assert
(
end_pwrlvl
<=
PLAT_MAX_PWR_LVL
);
assert
(
state_info
);
assert
(
state_info
!=
NULL
);
/* Get the index into the stats array */
local_state
=
state_info
->
pwr_domain_state
[
PSCI_CPU_PWR_LVL
];
...
...
@@ -134,9 +136,9 @@ void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
if
(
last_cpu_in_non_cpu_pd
[
parent_idx
]
==
-
1
)
return
;
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
U
;
lvl
<=
end_pwrlvl
;
lvl
++
)
{
local_state
=
state_info
->
pwr_domain_state
[
lvl
];
if
(
is_local_state_run
(
local_state
))
{
if
(
is_local_state_run
(
local_state
)
!=
0
)
{
/* Break early */
break
;
}
...
...
@@ -145,7 +147,7 @@ void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
/* Call into platform interface to calculate residency. */
residency
=
plat_psci_stat_get_residency
(
lvl
,
state_info
,
last_cpu_in_non_cpu_pd
[
parent_idx
]);
last_cpu_in_non_cpu_pd
[
parent_idx
]);
/* Initialize back to reset value */
last_cpu_in_non_cpu_pd
[
parent_idx
]
=
-
1
;
...
...
@@ -171,17 +173,18 @@ static int psci_get_stat(u_register_t target_cpu, unsigned int power_state,
psci_stat_t
*
psci_stat
)
{
int
rc
;
unsigned
int
pwrlvl
,
lvl
,
parent_idx
,
stat_idx
,
target_idx
;
unsigned
int
pwrlvl
,
lvl
,
parent_idx
,
target_idx
;
int
stat_idx
;
psci_power_state_t
state_info
=
{
{
PSCI_LOCAL_STATE_RUN
}
};
plat_local_state_t
local_state
;
/* Validate the target_cpu parameter and determine the cpu index */
target_idx
=
plat_core_pos_by_mpidr
(
target_cpu
);
if
(
target_idx
==
-
1
)
target_idx
=
(
unsigned
int
)
plat_core_pos_by_mpidr
(
target_cpu
);
if
(
target_idx
==
(
unsigned
int
)
-
1
)
return
PSCI_E_INVALID_PARAMS
;
/* Validate the power_state parameter */
if
(
!
psci_plat_pm_ops
->
translate_power_state_by_mpidr
)
if
(
psci_plat_pm_ops
->
translate_power_state_by_mpidr
==
NULL
)
rc
=
psci_validate_power_state
(
power_state
,
&
state_info
);
else
rc
=
psci_plat_pm_ops
->
translate_power_state_by_mpidr
(
...
...
@@ -204,7 +207,7 @@ static int psci_get_stat(u_register_t target_cpu, unsigned int power_state,
if
(
pwrlvl
>
PSCI_CPU_PWR_LVL
)
{
/* Get the power domain index */
parent_idx
=
psci_cpu_pd_nodes
[
target_idx
].
parent_node
;
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
;
lvl
<
pwrlvl
;
lvl
++
)
for
(
lvl
=
PSCI_CPU_PWR_LVL
+
1
U
;
lvl
<
pwrlvl
;
lvl
++
)
parent_idx
=
psci_non_cpu_pd_nodes
[
parent_idx
].
parent_node
;
/* Get the non cpu power domain stats */
...
...
This diff is collapsed.
Click to expand it.
lib/psci/psci_suspend.c
View file @
60e062fb
/*
* Copyright (c) 2013-201
7
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -23,7 +23,7 @@
* This function does generic and platform specific operations after a wake-up
* from standby/retention states at multiple power levels.
******************************************************************************/
static
void
psci_suspend_to_standby_finisher
(
unsigned
int
cpu_idx
,
static
void
psci_suspend_to_standby_finisher
(
int
cpu_idx
,
unsigned
int
end_pwrlvl
)
{
psci_power_state_t
state_info
;
...
...
@@ -64,8 +64,8 @@ static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
* operations.
******************************************************************************/
static
void
psci_suspend_to_pwrdown_start
(
unsigned
int
end_pwrlvl
,
entry_point_info_t
*
ep
,
psci_power_state_t
*
state_info
)
const
entry_point_info_t
*
ep
,
const
psci_power_state_t
*
state_info
)
{
unsigned
int
max_off_lvl
=
psci_find_max_off_lvl
(
state_info
);
...
...
@@ -85,7 +85,7 @@ static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
* Dispatcher to let it do any book-keeping. If the handler encounters an
* error, it's expected to assert within
*/
if
(
psci_spd_pm
&&
psci_spd_pm
->
svc_suspend
)
if
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_suspend
!=
NULL
)
)
psci_spd_pm
->
svc_suspend
(
max_off_lvl
);
#if !HW_ASSISTED_COHERENCY
...
...
@@ -95,7 +95,7 @@ static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
* HW_ASSISTED_COHERENCY = 0 platforms that can safely perform these
* actions with data caches enabled.
*/
if
(
psci_plat_pm_ops
->
pwr_domain_suspend_pwrdown_early
)
if
(
psci_plat_pm_ops
->
pwr_domain_suspend_pwrdown_early
!=
NULL
)
psci_plat_pm_ops
->
pwr_domain_suspend_pwrdown_early
(
state_info
);
#endif
...
...
@@ -147,20 +147,20 @@ static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
* the state transition has been done, no further error is expected and it is
* not possible to undo any of the actions taken beyond that point.
******************************************************************************/
void
psci_cpu_suspend_start
(
entry_point_info_t
*
ep
,
void
psci_cpu_suspend_start
(
const
entry_point_info_t
*
ep
,
unsigned
int
end_pwrlvl
,
psci_power_state_t
*
state_info
,
unsigned
int
is_power_down_state
)
{
int
skip_wfi
=
0
;
unsigned
int
idx
=
plat_my_core_pos
();
int
idx
=
(
int
)
plat_my_core_pos
();
/*
* This function must only be called on platforms where the
* CPU_SUSPEND platform hooks have been implemented.
*/
assert
(
psci_plat_pm_ops
->
pwr_domain_suspend
&&
psci_plat_pm_ops
->
pwr_domain_suspend_finish
);
assert
(
(
psci_plat_pm_ops
->
pwr_domain_suspend
!=
NULL
)
&&
(
psci_plat_pm_ops
->
pwr_domain_suspend_finish
!=
NULL
)
);
/*
* This function acquires the lock corresponding to each power
...
...
@@ -175,7 +175,7 @@ void psci_cpu_suspend_start(entry_point_info_t *ep,
* introduced by lock contention to increase the chances of early
* detection that a wake-up interrupt has fired.
*/
if
(
read_isr_el1
())
{
if
(
read_isr_el1
()
!=
0U
)
{
skip_wfi
=
1
;
goto
exit
;
}
...
...
@@ -192,7 +192,7 @@ void psci_cpu_suspend_start(entry_point_info_t *ep,
psci_stats_update_pwr_down
(
end_pwrlvl
,
state_info
);
#endif
if
(
is_power_down_state
)
if
(
is_power_down_state
!=
0U
)
psci_suspend_to_pwrdown_start
(
end_pwrlvl
,
ep
,
state_info
);
/*
...
...
@@ -214,10 +214,10 @@ exit:
*/
psci_release_pwr_domain_locks
(
end_pwrlvl
,
idx
);
if
(
skip_wfi
)
if
(
skip_wfi
==
1
)
return
;
if
(
is_power_down_state
)
{
if
(
is_power_down_state
!=
0U
)
{
#if ENABLE_RUNTIME_INSTRUMENTATION
/*
...
...
@@ -232,7 +232,7 @@ exit:
#endif
/* The function calls below must not return */
if
(
psci_plat_pm_ops
->
pwr_domain_pwr_down_wfi
)
if
(
psci_plat_pm_ops
->
pwr_domain_pwr_down_wfi
!=
NULL
)
psci_plat_pm_ops
->
pwr_domain_pwr_down_wfi
(
state_info
);
else
psci_power_down_wfi
();
...
...
@@ -269,15 +269,15 @@ exit:
* are called by the common finisher routine in psci_common.c. The `state_info`
* is the psci_power_state from which this CPU has woken up from.
******************************************************************************/
void
psci_cpu_suspend_finish
(
unsigned
int
cpu_idx
,
psci_power_state_t
*
state_info
)
void
psci_cpu_suspend_finish
(
int
cpu_idx
,
const
psci_power_state_t
*
state_info
)
{
unsigned
int
counter_freq
;
unsigned
int
max_off_lvl
;
/* Ensure we have been woken up from a suspended state */
assert
(
psci_get_aff_info_state
()
==
AFF_STATE_ON
&&
is_local_state_off
(
\
state_info
->
pwr_domain_state
[
PSCI_CPU_PWR_LVL
]));
assert
((
psci_get_aff_info_state
()
==
AFF_STATE_ON
)
&&
(
is_local_state_off
(
state_info
->
pwr_domain_state
[
PSCI_CPU_PWR_LVL
])
!=
0
));
/*
* Plat. management: Perform the platform specific actions
...
...
@@ -302,9 +302,9 @@ void psci_cpu_suspend_finish(unsigned int cpu_idx,
* Dispatcher to let it do any bookeeping. If the handler encounters an
* error, it's expected to assert within
*/
if
(
psci_spd_pm
&&
psci_spd_pm
->
svc_suspend_finish
)
{
if
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_suspend_finish
!=
NULL
)
)
{
max_off_lvl
=
psci_find_max_off_lvl
(
state_info
);
assert
(
max_off_lvl
!=
PSCI_INVALID_PWR_LVL
);
assert
(
max_off_lvl
!=
PSCI_INVALID_PWR_LVL
);
psci_spd_pm
->
svc_suspend_finish
(
max_off_lvl
);
}
...
...
This diff is collapsed.
Click to expand it.
lib/psci/psci_system_off.c
View file @
60e062fb
/*
* Copyright (c) 2014-201
7
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-201
8
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -16,14 +16,14 @@ void __dead2 psci_system_off(void)
{
psci_print_power_domain_map
();
assert
(
psci_plat_pm_ops
->
system_off
);
assert
(
psci_plat_pm_ops
->
system_off
!=
NULL
);
/* Notify the Secure Payload Dispatcher */
if
(
psci_spd_pm
&&
psci_spd_pm
->
svc_system_off
)
{
if
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_system_off
!=
NULL
)
)
{
psci_spd_pm
->
svc_system_off
();
}
console_flush
();
(
void
)
console_flush
();
/* Call the platform specific hook */
psci_plat_pm_ops
->
system_off
();
...
...
@@ -35,14 +35,14 @@ void __dead2 psci_system_reset(void)
{
psci_print_power_domain_map
();
assert
(
psci_plat_pm_ops
->
system_reset
);
assert
(
psci_plat_pm_ops
->
system_reset
!=
NULL
);
/* Notify the Secure Payload Dispatcher */
if
(
psci_spd_pm
&&
psci_spd_pm
->
svc_system_reset
)
{
if
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_system_reset
!=
NULL
)
)
{
psci_spd_pm
->
svc_system_reset
();
}
console_flush
();
(
void
)
console_flush
();
/* Call the platform specific hook */
psci_plat_pm_ops
->
system_reset
();
...
...
@@ -50,32 +50,34 @@ void __dead2 psci_system_reset(void)
/* This function does not return. We should never get here */
}
in
t
psci_system_reset2
(
uint32_t
reset_type
,
u_register_t
cookie
)
u_register_
t
psci_system_reset2
(
uint32_t
reset_type
,
u_register_t
cookie
)
{
int
is_vendor
;
unsigned
int
is_vendor
;
psci_print_power_domain_map
();
assert
(
psci_plat_pm_ops
->
system_reset2
);
assert
(
psci_plat_pm_ops
->
system_reset2
!=
NULL
);
is_vendor
=
(
reset_type
>>
PSCI_RESET2_TYPE_VENDOR_SHIFT
)
&
1
;
if
(
!
is_vendor
)
{
is_vendor
=
(
reset_type
>>
PSCI_RESET2_TYPE_VENDOR_SHIFT
)
&
1
U
;
if
(
is_vendor
==
0U
)
{
/*
* Only WARM_RESET is allowed for architectural type resets.
*/
if
(
reset_type
!=
PSCI_RESET2_SYSTEM_WARM_RESET
)
return
PSCI_E_INVALID_PARAMS
;
if
(
psci_plat_pm_ops
->
write_mem_protect
&&
psci_plat_pm_ops
->
write_mem_protect
(
0
)
<
0
)
{
return
PSCI_E_NOT_SUPPORTED
;
return
(
u_register_t
)
PSCI_E_INVALID_PARAMS
;
if
(
(
psci_plat_pm_ops
->
write_mem_protect
!=
NULL
)
&&
(
psci_plat_pm_ops
->
write_mem_protect
(
0
)
<
0
)
)
{
return
(
u_register_t
)
PSCI_E_NOT_SUPPORTED
;
}
}
/* Notify the Secure Payload Dispatcher */
if
(
psci_spd_pm
&&
psci_spd_pm
->
svc_system_reset
)
{
if
(
(
psci_spd_pm
!=
NULL
)
&&
(
psci_spd_pm
->
svc_system_reset
!=
NULL
)
)
{
psci_spd_pm
->
svc_system_reset
();
}
console_flush
();
(
void
)
console_flush
();
return
psci_plat_pm_ops
->
system_reset2
(
is_vendor
,
reset_type
,
cookie
);
return
(
u_register_t
)
psci_plat_pm_ops
->
system_reset2
((
int
)
is_vendor
,
reset_type
,
cookie
);
}
This diff is collapsed.
Click to expand it.
plat/allwinner/common/include/platform_def.h
View file @
60e062fb
...
...
@@ -4,12 +4,13 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef
__
PLATFORM_DEF_H
__
#define
__
PLATFORM_DEF_H
__
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
#include <common_def.h>
#include <sunxi_mmap.h>
#include <tbbr/tbbr_img_def.h>
#include <utils_def.h>
#define BL31_BASE SUNXI_SRAM_A2_BASE
#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
...
...
@@ -23,11 +24,11 @@
#define MAX_MMAP_REGIONS (4 + PLATFORM_MMAP_REGIONS)
#define MAX_XLAT_TABLES 2
#define PLAT_MAX_PWR_LVL_STATES
2
#define PLAT_MAX_RET_STATE
1
#define PLAT_MAX_OFF_STATE
2
#define PLAT_MAX_PWR_LVL_STATES
U(2)
#define PLAT_MAX_RET_STATE
U(1)
#define PLAT_MAX_OFF_STATE
U(2)
#define PLAT_MAX_PWR_LVL
2
#define PLAT_MAX_PWR_LVL
U(2)
#define PLAT_NUM_PWR_DOMAINS (1 + \
PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
...
...
@@ -48,4 +49,4 @@
#endif
#endif
#endif
/*
__
PLATFORM_DEF_H
__
*/
#endif
/* PLATFORM_DEF_H */
This diff is collapsed.
Click to expand it.
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help