xref: /aosp_15_r20/external/arm-trusted-firmware/include/lib/psci/psci_lib.h (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #ifndef PSCI_LIB_H
8*54fd6939SJiyong Park #define PSCI_LIB_H
9*54fd6939SJiyong Park 
10*54fd6939SJiyong Park #include <common/ep_info.h>
11*54fd6939SJiyong Park 
12*54fd6939SJiyong Park #ifndef __ASSEMBLER__
13*54fd6939SJiyong Park 
14*54fd6939SJiyong Park #include <cdefs.h>
15*54fd6939SJiyong Park #include <stdint.h>
16*54fd6939SJiyong Park 
17*54fd6939SJiyong Park /*******************************************************************************
18*54fd6939SJiyong Park  * Optional structure populated by the Secure Payload Dispatcher to be given a
19*54fd6939SJiyong Park  * chance to perform any bookkeeping before PSCI executes a power management
20*54fd6939SJiyong Park  * operation. It also allows PSCI to determine certain properties of the SP e.g.
21*54fd6939SJiyong Park  * migrate capability etc.
22*54fd6939SJiyong Park  ******************************************************************************/
23*54fd6939SJiyong Park typedef struct spd_pm_ops {
24*54fd6939SJiyong Park 	void (*svc_on)(u_register_t target_cpu);
25*54fd6939SJiyong Park 	int32_t (*svc_off)(u_register_t __unused unused);
26*54fd6939SJiyong Park 	void (*svc_suspend)(u_register_t max_off_pwrlvl);
27*54fd6939SJiyong Park 	void (*svc_on_finish)(u_register_t __unused unused);
28*54fd6939SJiyong Park 	void (*svc_suspend_finish)(u_register_t max_off_pwrlvl);
29*54fd6939SJiyong Park 	int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu);
30*54fd6939SJiyong Park 	int32_t (*svc_migrate_info)(u_register_t *resident_cpu);
31*54fd6939SJiyong Park 	void (*svc_system_off)(void);
32*54fd6939SJiyong Park 	void (*svc_system_reset)(void);
33*54fd6939SJiyong Park } spd_pm_ops_t;
34*54fd6939SJiyong Park 
35*54fd6939SJiyong Park /*
36*54fd6939SJiyong Park  * Function prototype for the warmboot entrypoint function which will be
37*54fd6939SJiyong Park  * programmed in the mailbox by the platform.
38*54fd6939SJiyong Park  */
39*54fd6939SJiyong Park typedef void (*mailbox_entrypoint_t)(void);
40*54fd6939SJiyong Park 
41*54fd6939SJiyong Park /******************************************************************************
42*54fd6939SJiyong Park  * Structure to pass PSCI Library arguments.
43*54fd6939SJiyong Park  *****************************************************************************/
44*54fd6939SJiyong Park typedef struct psci_lib_args {
45*54fd6939SJiyong Park 	/* The version information of PSCI Library Interface */
46*54fd6939SJiyong Park 	param_header_t		h;
47*54fd6939SJiyong Park 	/* The warm boot entrypoint function */
48*54fd6939SJiyong Park 	mailbox_entrypoint_t	mailbox_ep;
49*54fd6939SJiyong Park } psci_lib_args_t;
50*54fd6939SJiyong Park 
51*54fd6939SJiyong Park /* Helper macro to set the psci_lib_args_t structure at runtime */
52*54fd6939SJiyong Park #define SET_PSCI_LIB_ARGS_V1(_p, _entry)	do {			\
53*54fd6939SJiyong Park 	SET_PARAM_HEAD(_p, PARAM_PSCI_LIB_ARGS, VERSION_1, 0);		\
54*54fd6939SJiyong Park 	(_p)->mailbox_ep = (_entry);					\
55*54fd6939SJiyong Park 	} while (0)
56*54fd6939SJiyong Park 
57*54fd6939SJiyong Park /* Helper macro to define the psci_lib_args_t statically */
58*54fd6939SJiyong Park #define DEFINE_STATIC_PSCI_LIB_ARGS_V1(_name, _entry)		\
59*54fd6939SJiyong Park 	static const psci_lib_args_t (_name) = {		\
60*54fd6939SJiyong Park 		.h.type = (uint8_t)PARAM_PSCI_LIB_ARGS,		\
61*54fd6939SJiyong Park 		.h.version = (uint8_t)VERSION_1,		\
62*54fd6939SJiyong Park 		.h.size = (uint16_t)sizeof(_name),		\
63*54fd6939SJiyong Park 		.h.attr = 0U,					\
64*54fd6939SJiyong Park 		.mailbox_ep = (_entry)				\
65*54fd6939SJiyong Park 	}
66*54fd6939SJiyong Park 
67*54fd6939SJiyong Park /* Helper macro to verify the pointer to psci_lib_args_t structure */
68*54fd6939SJiyong Park #define VERIFY_PSCI_LIB_ARGS_V1(_p)	(((_p) != NULL)		\
69*54fd6939SJiyong Park 		&& ((_p)->h.type == PARAM_PSCI_LIB_ARGS)	\
70*54fd6939SJiyong Park 		&& ((_p)->h.version == VERSION_1)		\
71*54fd6939SJiyong Park 		&& ((_p)->h.size == sizeof(*(_p)))		\
72*54fd6939SJiyong Park 		&& ((_p)->h.attr == 0)				\
73*54fd6939SJiyong Park 		&& ((_p)->mailbox_ep != NULL))
74*54fd6939SJiyong Park 
75*54fd6939SJiyong Park /******************************************************************************
76*54fd6939SJiyong Park  * PSCI Library Interfaces
77*54fd6939SJiyong Park  *****************************************************************************/
78*54fd6939SJiyong Park u_register_t psci_smc_handler(uint32_t smc_fid,
79*54fd6939SJiyong Park 			  u_register_t x1,
80*54fd6939SJiyong Park 			  u_register_t x2,
81*54fd6939SJiyong Park 			  u_register_t x3,
82*54fd6939SJiyong Park 			  u_register_t x4,
83*54fd6939SJiyong Park 			  void *cookie,
84*54fd6939SJiyong Park 			  void *handle,
85*54fd6939SJiyong Park 			  u_register_t flags);
86*54fd6939SJiyong Park int psci_setup(const psci_lib_args_t *lib_args);
87*54fd6939SJiyong Park int psci_secondaries_brought_up(void);
88*54fd6939SJiyong Park void psci_warmboot_entrypoint(void);
89*54fd6939SJiyong Park void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
90*54fd6939SJiyong Park void psci_prepare_next_non_secure_ctx(
91*54fd6939SJiyong Park 			  entry_point_info_t *next_image_info);
92*54fd6939SJiyong Park int psci_stop_other_cores(unsigned int wait_ms,
93*54fd6939SJiyong Park 			  void (*stop_func)(u_register_t mpidr));
94*54fd6939SJiyong Park #endif /* __ASSEMBLER__ */
95*54fd6939SJiyong Park 
96*54fd6939SJiyong Park #endif /* PSCI_LIB_H */
97