1890b5088SRaghu Krishnamurthy /*
2890b5088SRaghu Krishnamurthy * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
3890b5088SRaghu Krishnamurthy * SPDX-License-Identifier: BSD-3-Clause
4890b5088SRaghu Krishnamurthy */
5890b5088SRaghu Krishnamurthy #ifndef EL3_SPMD_LOGICAL_SP_H
6890b5088SRaghu Krishnamurthy #define EL3_SPMD_LOGICAL_SP_H
7890b5088SRaghu Krishnamurthy
8890b5088SRaghu Krishnamurthy #include <common/bl_common.h>
9890b5088SRaghu Krishnamurthy #include <lib/cassert.h>
10890b5088SRaghu Krishnamurthy #include <services/ffa_svc.h>
11890b5088SRaghu Krishnamurthy
12890b5088SRaghu Krishnamurthy /*******************************************************************************
13890b5088SRaghu Krishnamurthy * Structure definition, typedefs & constants for the SPMD Logical Partitions.
14890b5088SRaghu Krishnamurthy ******************************************************************************/
15890b5088SRaghu Krishnamurthy /* Prototype for SPMD logical partition initializing function. */
16890b5088SRaghu Krishnamurthy typedef int32_t (*ffa_spmd_lp_init_t)(void);
17890b5088SRaghu Krishnamurthy
18890b5088SRaghu Krishnamurthy /* SPMD Logical Partition Descriptor. */
19890b5088SRaghu Krishnamurthy struct spmd_lp_desc {
20890b5088SRaghu Krishnamurthy ffa_spmd_lp_init_t init;
21890b5088SRaghu Krishnamurthy uint16_t sp_id;
22890b5088SRaghu Krishnamurthy uint32_t properties;
23890b5088SRaghu Krishnamurthy uint32_t uuid[4]; /* Little Endian. */
24890b5088SRaghu Krishnamurthy const char *debug_name;
25890b5088SRaghu Krishnamurthy };
26890b5088SRaghu Krishnamurthy
2766bdfd6eSRaghu Krishnamurthy struct ffa_value {
2866bdfd6eSRaghu Krishnamurthy uint64_t func;
2966bdfd6eSRaghu Krishnamurthy uint64_t arg1;
3066bdfd6eSRaghu Krishnamurthy uint64_t arg2;
3166bdfd6eSRaghu Krishnamurthy uint64_t arg3;
3266bdfd6eSRaghu Krishnamurthy uint64_t arg4;
3366bdfd6eSRaghu Krishnamurthy uint64_t arg5;
3466bdfd6eSRaghu Krishnamurthy uint64_t arg6;
3566bdfd6eSRaghu Krishnamurthy uint64_t arg7;
360b850e9eSRaghu Krishnamurthy uint64_t arg8;
370b850e9eSRaghu Krishnamurthy uint64_t arg9;
380b850e9eSRaghu Krishnamurthy uint64_t arg10;
390b850e9eSRaghu Krishnamurthy uint64_t arg11;
400b850e9eSRaghu Krishnamurthy uint64_t arg12;
410b850e9eSRaghu Krishnamurthy uint64_t arg13;
420b850e9eSRaghu Krishnamurthy uint64_t arg14;
430b850e9eSRaghu Krishnamurthy uint64_t arg15;
440b850e9eSRaghu Krishnamurthy uint64_t arg16;
450b850e9eSRaghu Krishnamurthy uint64_t arg17;
4666bdfd6eSRaghu Krishnamurthy };
4766bdfd6eSRaghu Krishnamurthy
48890b5088SRaghu Krishnamurthy /* Convenience macro to declare a SPMD logical partition descriptor. */
49890b5088SRaghu Krishnamurthy #define DECLARE_SPMD_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties) \
50890b5088SRaghu Krishnamurthy static const struct spmd_lp_desc __partition_desc_ ## _name \
51890b5088SRaghu Krishnamurthy __section(".spmd_lp_descs") __used = { \
52890b5088SRaghu Krishnamurthy .debug_name = #_name, \
53890b5088SRaghu Krishnamurthy .init = (_init), \
54890b5088SRaghu Krishnamurthy .sp_id = (_sp_id), \
55890b5088SRaghu Krishnamurthy .uuid = _uuid, \
56890b5088SRaghu Krishnamurthy .properties = (_properties), \
57890b5088SRaghu Krishnamurthy }
58890b5088SRaghu Krishnamurthy
59890b5088SRaghu Krishnamurthy IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_START__, SPMD_LP_DESCS_START);
60890b5088SRaghu Krishnamurthy IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_END__, SPMD_LP_DESCS_END);
61890b5088SRaghu Krishnamurthy
62890b5088SRaghu Krishnamurthy #define SPMD_LP_DESCS_COUNT ((SPMD_LP_DESCS_END - SPMD_LP_DESCS_START) \
63890b5088SRaghu Krishnamurthy / sizeof(struct spmd_lp_desc))
64890b5088SRaghu Krishnamurthy CASSERT(sizeof(struct spmd_lp_desc) == 40, assert_spmd_lp_desc_size_mismatch);
65890b5088SRaghu Krishnamurthy
66890b5088SRaghu Krishnamurthy /*
67890b5088SRaghu Krishnamurthy * Reserve 63 IDs for SPMD Logical Partitions. Currently, 0xFFC0 to 0xFFFE
68890b5088SRaghu Krishnamurthy * is reserved.
69890b5088SRaghu Krishnamurthy */
70890b5088SRaghu Krishnamurthy #define SPMD_LP_ID_END (SPMD_DIRECT_MSG_ENDPOINT_ID - 1)
71890b5088SRaghu Krishnamurthy #define SPMD_LP_ID_START (SPMD_LP_ID_END - 62)
72890b5088SRaghu Krishnamurthy
7395f7f6d8SRaghu Krishnamurthy /*
7495f7f6d8SRaghu Krishnamurthy * TODO: Arbitrary number. Can make this platform specific in the future,
7595f7f6d8SRaghu Krishnamurthy * no known use cases for more LPs at this point.
7695f7f6d8SRaghu Krishnamurthy */
7795f7f6d8SRaghu Krishnamurthy #define EL3_SPMD_MAX_NUM_LP U(5)
7895f7f6d8SRaghu Krishnamurthy
is_spmd_lp_id(unsigned int id)79890b5088SRaghu Krishnamurthy static inline bool is_spmd_lp_id(unsigned int id)
80890b5088SRaghu Krishnamurthy {
8166bdfd6eSRaghu Krishnamurthy #if ENABLE_SPMD_LP
82890b5088SRaghu Krishnamurthy return (id >= SPMD_LP_ID_START && id <= SPMD_LP_ID_END);
8366bdfd6eSRaghu Krishnamurthy #else
8466bdfd6eSRaghu Krishnamurthy return false;
8566bdfd6eSRaghu Krishnamurthy #endif
8666bdfd6eSRaghu Krishnamurthy }
8766bdfd6eSRaghu Krishnamurthy
is_ffa_error(struct ffa_value * retval)8866bdfd6eSRaghu Krishnamurthy static inline bool is_ffa_error(struct ffa_value *retval)
8966bdfd6eSRaghu Krishnamurthy {
9066bdfd6eSRaghu Krishnamurthy return retval->func == FFA_ERROR;
9166bdfd6eSRaghu Krishnamurthy }
9266bdfd6eSRaghu Krishnamurthy
is_ffa_success(struct ffa_value * retval)930b850e9eSRaghu Krishnamurthy static inline bool is_ffa_success(struct ffa_value *retval)
940b850e9eSRaghu Krishnamurthy {
950b850e9eSRaghu Krishnamurthy return (retval->func == FFA_SUCCESS_SMC32) ||
960b850e9eSRaghu Krishnamurthy (retval->func == FFA_SUCCESS_SMC64);
970b850e9eSRaghu Krishnamurthy }
980b850e9eSRaghu Krishnamurthy
is_ffa_direct_msg_resp(struct ffa_value * retval)9966bdfd6eSRaghu Krishnamurthy static inline bool is_ffa_direct_msg_resp(struct ffa_value *retval)
10066bdfd6eSRaghu Krishnamurthy {
10166bdfd6eSRaghu Krishnamurthy return (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
10266bdfd6eSRaghu Krishnamurthy (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC64);
103890b5088SRaghu Krishnamurthy }
104890b5088SRaghu Krishnamurthy
ffa_partition_info_regs_get_last_idx(struct ffa_value * args)1050b850e9eSRaghu Krishnamurthy static inline uint16_t ffa_partition_info_regs_get_last_idx(
106*b04343f3SRaghu Krishnamurthy struct ffa_value *args)
1070b850e9eSRaghu Krishnamurthy {
108*b04343f3SRaghu Krishnamurthy return (uint16_t)(args->arg2 & 0xFFFFU);
1090b850e9eSRaghu Krishnamurthy }
1100b850e9eSRaghu Krishnamurthy
ffa_partition_info_regs_get_curr_idx(struct ffa_value * args)1110b850e9eSRaghu Krishnamurthy static inline uint16_t ffa_partition_info_regs_get_curr_idx(
112*b04343f3SRaghu Krishnamurthy struct ffa_value *args)
1130b850e9eSRaghu Krishnamurthy {
114*b04343f3SRaghu Krishnamurthy return (uint16_t)((args->arg2 >> 16) & 0xFFFFU);
1150b850e9eSRaghu Krishnamurthy }
1160b850e9eSRaghu Krishnamurthy
ffa_partition_info_regs_get_tag(struct ffa_value * args)117*b04343f3SRaghu Krishnamurthy static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value *args)
1180b850e9eSRaghu Krishnamurthy {
119*b04343f3SRaghu Krishnamurthy return (uint16_t)((args->arg2 >> 32) & 0xFFFFU);
1200b850e9eSRaghu Krishnamurthy }
1210b850e9eSRaghu Krishnamurthy
ffa_partition_info_regs_get_desc_size(struct ffa_value * args)1220b850e9eSRaghu Krishnamurthy static inline uint16_t ffa_partition_info_regs_get_desc_size(
123*b04343f3SRaghu Krishnamurthy struct ffa_value *args)
1240b850e9eSRaghu Krishnamurthy {
125*b04343f3SRaghu Krishnamurthy return (uint16_t)(args->arg2 >> 48);
1260b850e9eSRaghu Krishnamurthy }
1270b850e9eSRaghu Krishnamurthy
12895f7f6d8SRaghu Krishnamurthy uint64_t spmd_el3_populate_logical_partition_info(void *handle, uint64_t x1,
12995f7f6d8SRaghu Krishnamurthy uint64_t x2, uint64_t x3);
13095f7f6d8SRaghu Krishnamurthy
1310b850e9eSRaghu Krishnamurthy bool ffa_partition_info_regs_get_part_info(
132*b04343f3SRaghu Krishnamurthy struct ffa_value *args, uint8_t idx,
1330b850e9eSRaghu Krishnamurthy struct ffa_partition_info_v1_1 *partition_info);
1340b850e9eSRaghu Krishnamurthy
1350b850e9eSRaghu Krishnamurthy bool spmd_el3_invoke_partition_info_get(
1360b850e9eSRaghu Krishnamurthy const uint32_t target_uuid[4],
1370b850e9eSRaghu Krishnamurthy const uint16_t start_index,
1380b850e9eSRaghu Krishnamurthy const uint16_t tag,
1390b850e9eSRaghu Krishnamurthy struct ffa_value *retval);
140890b5088SRaghu Krishnamurthy void spmd_logical_sp_set_spmc_initialized(void);
141890b5088SRaghu Krishnamurthy void spmc_logical_sp_set_spmc_failure(void);
142890b5088SRaghu Krishnamurthy
143890b5088SRaghu Krishnamurthy int32_t spmd_logical_sp_init(void);
14466bdfd6eSRaghu Krishnamurthy bool spmd_el3_ffa_msg_direct_req(uint64_t x1,
14566bdfd6eSRaghu Krishnamurthy uint64_t x2,
14666bdfd6eSRaghu Krishnamurthy uint64_t x3,
14766bdfd6eSRaghu Krishnamurthy uint64_t x4,
14866bdfd6eSRaghu Krishnamurthy void *handle,
14966bdfd6eSRaghu Krishnamurthy struct ffa_value *retval);
150890b5088SRaghu Krishnamurthy
151a1a9a950SRaghu Krishnamurthy uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid,
152a1a9a950SRaghu Krishnamurthy u_register_t x1,
153a1a9a950SRaghu Krishnamurthy u_register_t x2,
154a1a9a950SRaghu Krishnamurthy u_register_t x3,
155a1a9a950SRaghu Krishnamurthy u_register_t x4,
156a1a9a950SRaghu Krishnamurthy void *cookie,
157a1a9a950SRaghu Krishnamurthy void *handle,
158a1a9a950SRaghu Krishnamurthy u_register_t flags);
159a1a9a950SRaghu Krishnamurthy
160890b5088SRaghu Krishnamurthy #endif /* EL3_SPMD_LOGICAL_SP_H */
161