diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index f95ef41..fae5ee4 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -53,18 +53,27 @@ ******************************************************************************/ static uint32_t next_image_type = NON_SECURE; +/* + * Implement the ARM Standard Service function to get arguments for a + * particular service. + */ +uintptr_t get_arm_std_svc_args(unsigned int svc_mask) +{ + /* Setup the arguments for PSCI Library */ + DEFINE_STATIC_PSCI_LIB_ARGS_V1(psci_args, bl31_warm_entrypoint); + + /* PSCI is the only ARM Standard Service implemented */ + assert(svc_mask == PSCI_FID_MASK); + + return (uintptr_t)&psci_args; +} + /******************************************************************************* * Simple function to initialise all BL31 helper libraries. ******************************************************************************/ void bl31_lib_init(void) { cm_init(); - - /* - * Initialize the PSCI library here. This also does EL3 architectural - * setup. - */ - psci_setup((uintptr_t)bl31_warm_entrypoint); } /******************************************************************************* @@ -86,7 +95,7 @@ /* Initialise helper libraries */ bl31_lib_init(); - /* Initialize the runtime services e.g. psci */ + /* Initialize the runtime services e.g. psci. */ INFO("BL31: Initializing runtime services\n"); runtime_svc_init(); diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c index 31cab3d..02663a2 100644 --- a/bl32/sp_min/sp_min_main.c +++ b/bl32/sp_min/sp_min_main.c @@ -151,24 +151,33 @@ } /****************************************************************************** + * Implement the ARM Standard Service function to get arguments for a + * particular service. + *****************************************************************************/ +uintptr_t get_arm_std_svc_args(unsigned int svc_mask) +{ + /* Setup the arguments for PSCI Library */ + DEFINE_STATIC_PSCI_LIB_ARGS_V1(psci_args, sp_min_warm_entrypoint); + + /* PSCI is the only ARM Standard Service implemented */ + assert(svc_mask == PSCI_FID_MASK); + + return (uintptr_t)&psci_args; +} + +/****************************************************************************** * The SP_MIN main function. Do the platform and PSCI Library setup. Also * initialize the runtime service framework. *****************************************************************************/ void sp_min_main(void) { - /* Perform platform setup in TSP MIN */ + NOTICE("SP_MIN: %s\n", version_string); + NOTICE("SP_MIN: %s\n", build_message); + + /* Perform the SP_MIN platform setup */ sp_min_platform_setup(); - /* - * Initialize the PSCI library and perform the remaining generic - * architectural setup from PSCI. - */ - psci_setup((uintptr_t)sp_min_warm_entrypoint); - - /* - * Initialize the runtime services e.g. psci - * This is where the monitor mode will be initialized - */ + /* Initialize the runtime services e.g. psci */ INFO("SP_MIN: Initializing runtime services\n"); runtime_svc_init(); diff --git a/include/common/bl_common.h b/include/common/bl_common.h index 9fa2a81..12d5036 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -103,6 +103,7 @@ #define PARAM_BL31 0x03 #define PARAM_BL_LOAD_INFO 0x04 #define PARAM_BL_PARAMS 0x05 +#define PARAM_PSCI_LIB_ARGS 0x06 #define IMAGE_ATTRIB_SKIP_LOADING 0x02 #define IMAGE_ATTRIB_PLAT_SETUP 0x04 diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h index 02cbbf3..34de4c2 100644 --- a/include/lib/psci/psci.h +++ b/include/lib/psci/psci.h @@ -32,6 +32,7 @@ #define __PSCI_H__ #include +#include #include /* for PLAT_NUM_PWR_DOMAINS */ #if ENABLE_PLAT_COMPAT #include @@ -356,10 +357,45 @@ */ void psci_entrypoint(void) __deprecated; -/******************************************************************************* - * Forward declarations - ******************************************************************************/ -struct entry_point_info; +/* + * Function prototype for the warmboot entrypoint function which will be + * programmed in the mailbox by the platform. + */ +typedef void (*mailbox_entrypoint_t)(void); + +/****************************************************************************** + * Structure to pass PSCI Library arguments. + *****************************************************************************/ +typedef struct psci_lib_args { + /* The version information of PSCI Library Interface */ + param_header_t h; + /* The warm boot entrypoint function */ + mailbox_entrypoint_t mailbox_ep; +} psci_lib_args_t; + +/* Helper macro to set the psci_lib_args_t structure at runtime */ +#define SET_PSCI_LIB_ARGS_V1(_p, _entry) do { \ + SET_PARAM_HEAD(_p, PARAM_PSCI_LIB_ARGS, VERSION_1, 0); \ + (_p)->mailbox_ep = (_entry); \ + } while (0) + +/* Helper macro to define the psci_lib_args_t statically */ +#define DEFINE_STATIC_PSCI_LIB_ARGS_V1(_name, _entry) \ + static const psci_lib_args_t (_name) = { \ + .h.type = (uint8_t)PARAM_PSCI_LIB_ARGS, \ + .h.version = (uint8_t)VERSION_1, \ + .h.size = (uint16_t)sizeof(_name), \ + .h.attr = 0, \ + .mailbox_ep = (_entry) \ + } + +/* Helper macro to verify the pointer to psci_lib_args_t structure */ +#define VERIFY_PSCI_LIB_ARGS_V1(_p) ((_p) \ + && ((_p)->h.type == PARAM_PSCI_LIB_ARGS) \ + && ((_p)->h.version == VERSION_1) \ + && ((_p)->h.size == sizeof(*(_p))) \ + && ((_p)->h.attr == 0) \ + && ((_p)->mailbox_ep)) /****************************************************************************** * PSCI Library Interfaces @@ -372,11 +408,11 @@ void *cookie, void *handle, u_register_t flags); -int psci_setup(uintptr_t mailbox_ep); +int psci_setup(const psci_lib_args_t *lib_args); void psci_warmboot_entrypoint(void); void psci_register_spd_pm_hook(const spd_pm_ops_t *pm); void psci_prepare_next_non_secure_ctx( - struct entry_point_info *next_image_info); + entry_point_info_t *next_image_info); #endif /*__ASSEMBLY__*/ diff --git a/include/services/std_svc.h b/include/services/std_svc.h index 0feb2ea..38ce8bb 100644 --- a/include/services/std_svc.h +++ b/include/services/std_svc.h @@ -42,4 +42,13 @@ #define STD_SVC_VERSION_MAJOR 0x0 #define STD_SVC_VERSION_MINOR 0x1 +/* + * Get the ARM Standard Service argument from EL3 Runtime. + * This function must be implemented by EL3 Runtime and the + * `svc_mask` identifies the service. `svc_mask` is a bit + * mask identifying the range of SMC function IDs available + * to the service. + */ +uintptr_t get_arm_std_svc_args(unsigned int svc_mask); + #endif /* __STD_SVC_H__ */ diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c index 263ab68..cb8b77d 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -206,10 +206,12 @@ * | CPU 0 | CPU 1 | CPU 2 | CPU 3 | * ------------------------------------------------ ******************************************************************************/ -int psci_setup(uintptr_t mailbox_ep) +int psci_setup(const psci_lib_args_t *lib_args) { const unsigned char *topology_tree; + assert(VERIFY_PSCI_LIB_ARGS_V1(lib_args)); + /* Do the Architectural initialization */ psci_arch_setup(); @@ -234,8 +236,7 @@ */ psci_set_pwr_domains_to_run(PLAT_MAX_PWR_LVL); - assert(mailbox_ep); - plat_setup_psci_ops(mailbox_ep, &psci_plat_pm_ops); + plat_setup_psci_ops((uintptr_t)lib_args->mailbox_ep, &psci_plat_pm_ops); assert(psci_plat_pm_ops); /* diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c index 06647e0..e096601 100644 --- a/services/std_svc/std_svc_setup.c +++ b/services/std_svc/std_svc_setup.c @@ -28,6 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -41,6 +42,21 @@ 0x108d905b, 0xf863, 0x47e8, 0xae, 0x2d, 0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2); +/* Setup Standard Services */ +static int32_t std_svc_setup(void) +{ + uintptr_t svc_arg; + + svc_arg = get_arm_std_svc_args(PSCI_FID_MASK); + assert(svc_arg); + + /* + * PSCI is the only specification implemented as a Standard Service. + * The `psci_setup()` also does EL3 architectural setup. + */ + return psci_setup((const psci_lib_args_t *)svc_arg); +} + /* * Top-level Standard Service SMC handler. This handler will in turn dispatch * calls to PSCI SMC handler @@ -93,6 +109,6 @@ OEN_STD_START, OEN_STD_END, SMC_TYPE_FAST, - NULL, + std_svc_setup, std_svc_smc_handler );