aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bl31/bl31_main.c23
-rw-r--r--bl32/sp_min/sp_min_main.c31
-rw-r--r--include/common/bl_common.h1
-rw-r--r--include/lib/psci/psci.h48
-rw-r--r--include/services/std_svc.h9
-rw-r--r--lib/psci/psci_setup.c7
-rw-r--r--services/std_svc/std_svc_setup.c18
7 files changed, 109 insertions, 28 deletions
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index f95ef41a0c..fae5ee4ea9 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -53,18 +53,27 @@ static int32_t (*bl32_init)(void);
******************************************************************************/
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 @@ void bl31_main(void)
/* 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 31cab3df84..02663a29ea 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -151,24 +151,33 @@ static void sp_min_prepare_next_image_entry(void)
}
/******************************************************************************
+ * 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 */
- sp_min_platform_setup();
+ NOTICE("SP_MIN: %s\n", version_string);
+ NOTICE("SP_MIN: %s\n", build_message);
- /*
- * Initialize the PSCI library and perform the remaining generic
- * architectural setup from PSCI.
- */
- psci_setup((uintptr_t)sp_min_warm_entrypoint);
+ /* Perform the SP_MIN platform setup */
+ sp_min_platform_setup();
- /*
- * 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 9fa2a810e4..12d5036c8b 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 02cbbf3555..34de4c28a5 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -32,6 +32,7 @@
#define __PSCI_H__
#include <bakery_lock.h>
+#include <bl_common.h>
#include <platform_def.h> /* for PLAT_NUM_PWR_DOMAINS */
#if ENABLE_PLAT_COMPAT
#include <psci_compat.h>
@@ -356,10 +357,45 @@ void psci_arch_setup(void);
*/
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 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
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 0feb2eae11..38ce8bb47b 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 263ab68f94..cb8b77dbd1 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -206,10 +206,12 @@ static void populate_power_domain_tree(const unsigned char *topology)
* | 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 @@ int psci_setup(uintptr_t mailbox_ep)
*/
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 06647e00ee..e09660146e 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 <assert.h>
#include <debug.h>
#include <psci.h>
#include <runtime_svc.h>
@@ -41,6 +42,21 @@ DEFINE_SVC_UUID(arm_svc_uid,
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 @@ DECLARE_RT_SVC(
OEN_STD_START,
OEN_STD_END,
SMC_TYPE_FAST,
- NULL,
+ std_svc_setup,
std_svc_smc_handler
);