1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2022 Intel Corporation. All rights reserved.
4  *
5  * Author: Jaroslaw Stelter <jaroslaw.stelter@intel.com>
6  *         Pawel Dobrowolski <pawelx.dobrowolski@intel.com>
7  */
8 
9 /*
10  * Library manager implementation for SOF is using module adapter API for
11  * loadable native and external libraries. Depends of information received from
12  * it manages memory and locate accordingly to available space.
13  *
14  * Driver                   IPC4                       Library                     MEMORY    ENTITY
15  *                         Handler                     Manager                               VERIF.
16  *   |                       |                            |                          |         |
17  *   | IPC4_GLB_LOAD_LIBRARY |                            |                          |         |
18  *   | --------------------> | lib_manager_load_library() |                          |         |
19  *   |                       | -------------------------> |   Prepare DMA transfer   |         |
20  *   |                       |                            | -------                  |         |
21  *   |                       |                            |        |                 |         |
22  *   |                       |                            | <------                  |         |
23  *   |                       |                            | -----------------------> |         |
24  *   |                       |                            |                          |         |
25  *   |                       |                            |   (IF AUTH_API_ENABLED)  |         |
26  *   |                       |                            |  Verify Manifest         |         |
27  *   |                       |                            | -------------------------|-------> |
28  *   |                       |                            |  results                 |         |
29  *   |                       |                            | <------------------------|-------- |
30  *   |                       |                            |   (IF AUTH_API_ENABLED)  |         |
31  *   |                       |                            |                          |         |
32  *   |                       |                            | Parse Manifest           |         |
33  *   |                       |                            | Prepare Storage Memory   |         |
34  *   |                       |                            | -------                  |         |
35  *   |                       |                            |        |                 |         |
36  *   |                       |                            | <------                  |         |
37  *   |                       |                            |                          |         |
38  *   |                       |                            | Copy Library Data        |         |
39  *   |                       |                            | -----------------------> |         |
40  *   |                       |                            |                          |         |
41  *   |                       |                            |   (IF AUTH_API_ENABLED)  |         |
42  *   |                       |                            |  Verify Manifest         |         |
43  *   |                       |                            | -------------------------|-------> |
44  *   |                       |                            |  results                 |         |
45  *   |                       |                            | <------------------------|-------- |
46  *   |                       |                            |   (IF AUTH_API_ENABLED)  |         |
47  *   |                       |                            |                          |         |
48  *   |                       |                            | Update Library           |         |
49  *   |                       |                            | descriptors table        |         |
50  *   |                       |                            | -------                  |         |
51  *   |                       |                            |        |                 |         |
52  *   |                       |                            | <------                  |         |
53  *   |                       |       return status        |                          |         |
54  *   |                       | <------------------------- |                          |         |
55  *   | Complete IPC request  |                            |                          |         |
56  *   | <-------------------  |                            |                          |         |
57  *
58  * Driver                   IPC4                       Library                     MEMORY    ENTITY
59  *                         Handler                     Manager                               VERIF.
60  */
61 
62 #ifndef __SOF_LIB_MANAGER_H__
63 #define __SOF_LIB_MANAGER_H__
64 
65 #include <stdint.h>
66 #include <rimage/manifest.h>
67 
68 #define LIB_MANAGER_MAX_LIBS				16
69 #define LIB_MANAGER_LIB_ID_SHIFT			12
70 #define LIB_MANAGER_LIB_NOTIX_MAX_COUNT		4
71 
72 #define LIB_MANAGER_GET_LIB_ID(module_id) ((module_id) >> LIB_MANAGER_LIB_ID_SHIFT)
73 #define LIB_MANAGER_GET_MODULE_INDEX(module_id) ((module_id) & 0xFFF)
74 
75 #ifdef CONFIG_LIBRARY_MANAGER
76 struct ipc_lib_msg {
77 	struct ipc_msg *msg;
78 	struct list_item list;
79 };
80 
81 struct ext_library {
82 	struct k_spinlock lock;	/* last locking CPU record */
83 	struct sof_man_fw_desc *desc[LIB_MANAGER_MAX_LIBS];
84 	uint32_t mods_exec_load_cnt;
85 	struct ipc_lib_msg *lib_notif_pool;
86 	uint32_t lib_notif_count;
87 };
88 
89 /* lib manager context, used by lib_notification */
90 extern struct tr_ctx lib_manager_tr;
91 
ext_lib_get(void)92 static inline struct ext_library *ext_lib_get(void)
93 {
94 	return sof_get()->ext_library;
95 }
96 #endif
97 
98 /*
99  * \brief Initialize library manager
100  */
101 void lib_manager_init(void);
102 
103 /*
104  * \brief Register module on driver list
105  *
106  * param[in] desc - library manifest descriptor
107  * param[in] module_id - used to get manifest offset for module
108  *
109  * Creates new comp_driver_info and initialize it for module from library
110  * Adds new module to sof_get()->comp_drivers list
111  */
112 int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id);
113 
114 /*
115  * \brief Get library module manifest descriptor
116  *
117  * param[in] module_id - used to get text manifest offset
118  *
119  * Gets firmware manifest descriptor using module_id to locate it
120  */
121 struct sof_man_fw_desc *lib_manager_get_library_module_desc(int module_id);
122 
123 /*
124  * \brief Allocate module
125  *
126  * param[in] drv - component driver
127  * param[in] ipc_config - audio component base configuration from IPC at creation
128  * param[in] ipc_specific_config - ipc4 base configuration
129  *
130  * Function is responsible to allocate module in available free memory and assigning proper address.
131  * (WIP) These feature will contain module validation and proper memory management.
132  */
133 uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
134 				     struct comp_ipc_config *ipc_config,
135 				     const void *ipc_specific_config);
136 
137 /*
138  * \brief Free module
139  *
140  * param[in] drv - component driver
141  * param[in] ipc_config - audio component base configuration from IPC at creation
142  * param[in] ipc_specific_config - ipc4 base configuration
143  *
144  * Function is responsible to free module resources in HP memory.
145  */
146 int lib_manager_free_module(const struct comp_driver *drv,
147 			    struct comp_ipc_config *ipc_config);
148 /*
149  * \brief Load library
150  *
151  * param[in] dma_id - channel used to transfer binary from host
152  * param[in] lib_id
153  *
154  * Function will load library manifest into temporary buffer.
155  * Then it will read library parameters, allocate memory for library and load it into
156  * destination memory region.
157  */
158 int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id);
159 
160 /*
161  * \brief Initialize message
162  *
163  * param[in] header - IPC header provided by caller
164  * param[in] size   - size of data buffer for messege to be send
165  *
166  * Function search lib_notif_pool for free message handler.
167  * If not found allocates new message handle and returns it to
168  * caller.
169  */
170 struct ipc_msg *lib_notif_msg_init(uint32_t header, uint32_t size);
171 
172 /*
173  * \brief  Send message
174  *
175  * param[in] msg - IPC message handler
176  *
177  * Function sends IPC message and calls lib_notif_msg_clean() to
178  * free unused message handlers. Only single message handle will
179  * be kept in list while at least one loadable module is loaded.
180  */
181 void lib_notif_msg_send(struct ipc_msg *msg);
182 
183 /*
184  * \brief  Clean unused message handles
185  *
186  * param[in] leave_one_handle - remove all unused or keep one
187  *
188  * Function search lib_notif_pool list for unused message handles.
189  * Remove them keeping one if leave_one_handle == true.
190  */
191 void lib_notif_msg_clean(bool leave_one_handle);
192 
193 #endif /* __SOF_LIB_MANAGER_H__ */
194