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