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 uint32_t tot_len, uint32_t frag_len,
54 struct ffa_mem_transaction_x *trans);
55
56 bool spmc_is_reserved_id(uint16_t id);
57
58 struct spmc_lsp_desc {
59 void (*direct_req)(struct thread_smc_1_2_regs *args);
60 uint16_t sp_id;
61 uint32_t properties;
62 uint32_t uuid_words[4];
63 const char *name;
64 STAILQ_ENTRY(spmc_lsp_desc) link;
65 };
66
67 struct spmc_lsp_desc *spmc_find_lsp_by_sp_id(uint16_t sp_id);
68
69 TEE_Result spmc_register_lsp(struct spmc_lsp_desc *desc);
70
71 #if defined(CFG_CORE_SEL1_SPMC)
72 void thread_spmc_set_async_notif_intid(int intid);
73 #else
74 static inline void __noreturn
thread_spmc_set_async_notif_intid(int intid __unused)75 thread_spmc_set_async_notif_intid(int intid __unused)
76 {
77 panic();
78 }
79
80 struct mobj_ffa *thread_spmc_populate_mobj_from_rx(uint64_t cookie,
81 enum mobj_use_case use_case);
82 void thread_spmc_relinquish(uint64_t memory_region_handle);
83 #endif
84
85 #if defined(CFG_CORE_DYN_PROTMEM) && defined(CFG_CORE_FFA)
86 TEE_Result thread_spmc_get_protmem_config(enum mobj_use_case use_case,
87 void *buf, size_t *buf_sz,
88 size_t *min_mem_sz,
89 size_t *min_mem_align);
90 #else
91 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)92 thread_spmc_get_protmem_config(enum mobj_use_case use_case __unused,
93 void *buf __unused, size_t *buf_sz __unused,
94 size_t *min_mem_sz __unused,
95 size_t *min_mem_align __unused)
96 {
97 return TEE_ERROR_NOT_SUPPORTED;
98 }
99 #endif /*CFG_CORE_DYN_PROTMEM*/
100
101 #endif /* __KERNEL_THREAD_SPMC_H */
102