1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (c) 2021-2024, Arm Limited.
4 * Copyright (c) 2023-2025, Linaro Limited
5 */
6 #ifndef __KERNEL_THREAD_SPMC_H
7 #define __KERNEL_THREAD_SPMC_H
8
9 #include <compiler.h>
10 #include <ffa.h>
11 #include <kernel/panic.h>
12 #include <kernel/thread.h>
13 #include <mm/mobj.h>
14 #include <sys/queue.h>
15 #include <tee_api_types.h>
16 #include <types_ext.h>
17
18 /* The FF-A ID of Secure World components should be between these limits */
19 #define FFA_SWD_ID_MIN 0x8000
20 #define FFA_SWD_ID_MAX UINT16_MAX
21
22 #define SPMC_CORE_SEL1_MAX_SHM_COUNT 64
23
24 struct ffa_rxtx {
25 void *rx;
26 void *tx;
27 unsigned int size;
28 unsigned int spinlock;
29 uint32_t ffa_vers;
30 bool tx_is_mine;
31 };
32
33 void spmc_handle_spm_id_get(struct thread_smc_1_2_regs *args);
34 void spmc_handle_rxtx_map(struct thread_smc_1_2_regs *args,
35 struct ffa_rxtx *buf);
36 void spmc_handle_rxtx_unmap(struct thread_smc_1_2_regs *args,
37 struct ffa_rxtx *buf);
38 void spmc_handle_rx_release(struct thread_smc_1_2_regs *args,
39 struct ffa_rxtx *buf);
40 uint32_t spmc_exchange_version(uint32_t vers, struct ffa_rxtx *rxtx);
41
42 void spmc_set_args(struct thread_smc_1_2_regs *args, uint32_t fid,
43 uint32_t src_dst, uint32_t w2, uint32_t w3, uint32_t w4,
44 uint32_t w5);
45 void spmc_handle_partition_info_get(struct thread_smc_1_2_regs *args,
46 struct ffa_rxtx *rxtx);
47 TEE_Result spmc_fill_partition_entry(uint32_t ffa_vers, void *buf, size_t blen,
48 size_t idx, uint16_t endpoint_id,
49 uint16_t execution_context,
50 uint32_t part_props,
51 const uint32_t uuid_words[4]);
52 int spmc_read_mem_transaction(uint32_t ffa_vers, void *buf, size_t blen,
53 struct ffa_mem_transaction_x *trans);
54
55 bool spmc_is_reserved_id(uint16_t id);
56
57 struct spmc_lsp_desc {
58 void (*direct_req)(struct thread_smc_1_2_regs *args);
59 uint16_t sp_id;
60 uint32_t properties;
61 uint32_t uuid_words[4];
62 const char *name;
63 STAILQ_ENTRY(spmc_lsp_desc) link;
64 };
65
66 struct spmc_lsp_desc *spmc_find_lsp_by_sp_id(uint16_t sp_id);
67
68 TEE_Result spmc_register_lsp(struct spmc_lsp_desc *desc);
69
70 #if defined(CFG_CORE_SEL1_SPMC)
71 void thread_spmc_set_async_notif_intid(int intid);
72 #else
73 static inline void __noreturn
thread_spmc_set_async_notif_intid(int intid __unused)74 thread_spmc_set_async_notif_intid(int intid __unused)
75 {
76 panic();
77 }
78
79 struct mobj_ffa *thread_spmc_populate_mobj_from_rx(uint64_t cookie,
80 enum mobj_use_case use_case);
81 void thread_spmc_relinquish(uint64_t memory_region_handle);
82 #endif
83
84 #if defined(CFG_CORE_DYN_PROTMEM) && defined(CFG_CORE_FFA)
85 TEE_Result thread_spmc_get_protmem_config(enum mobj_use_case use_case,
86 void *buf, size_t *buf_sz,
87 size_t *min_mem_sz,
88 size_t *min_mem_align);
89 #else
90 static inline TEE_Result
thread_spmc_get_protmem_config(enum mobj_use_case use_case __unused,void * buf __unused,size_t * buf_sz __unused,size_t * min_mem_sz __unused,size_t * min_mem_align __unused)91 thread_spmc_get_protmem_config(enum mobj_use_case use_case __unused,
92 void *buf __unused, size_t *buf_sz __unused,
93 size_t *min_mem_sz __unused,
94 size_t *min_mem_align __unused)
95 {
96 return TEE_ERROR_NOT_SUPPORTED;
97 }
98 #endif /*CFG_CORE_DYN_PROTMEM*/
99
100 #endif /* __KERNEL_THREAD_SPMC_H */
101