1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2020 Intel Corporation. All rights reserved.
4 //
5 // Author: Jaroslaw Stelter <jaroslaw.stelter@linux.intel.com>
6
7 /*
8 * SOF System Agent - register IADK Loadable Library in SOF infrastructure.
9 */
10
11 #include <errno.h>
12 #include <stdbool.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 #include <rtos/string.h>
16 #include <utilities/array.h>
17 #include <adsp_error_code.h>
18 #include <logger.h>
19 #include <system_service.h>
20 #include <system_agent_interface.h>
21 #include <module_initial_settings_concrete.h>
22 #include <iadk_module_adapter.h>
23 #include <system_agent.h>
24
25 using namespace intel_adsp;
26 using namespace intel_adsp::system;
27 using namespace dsp_fw;
28
operator new(size_t size,intel_adsp::ModuleHandle * placeholder)29 void* operator new(size_t size, intel_adsp::ModuleHandle *placeholder) throw()
30 {
31 return placeholder;
32 }
33
34 extern "C" {
35
36 void SystemServiceLogMessage (AdspLogPriority log_priority, uint32_t log_entry,
37 AdspLogHandle const* log_handle, uint32_t param1,
38 uint32_t param2, uint32_t param3, uint32_t param4);
39
40 AdspErrorCode SystemServiceSafeMemcpy(void *RESTRICT dst, size_t maxlen,
41 const void *RESTRICT src, size_t len);
42
43 AdspErrorCode SystemServiceSafeMemmove(void *dst, size_t maxlen,
44 const void *src, size_t len);
45
46 void* SystemServiceVecMemset(void *dst, int c, size_t len);
47
48 AdspErrorCode SystemServiceCreateNotification(NotificationParams *params,
49 uint8_t *notification_buffer,
50 uint32_t notification_buffer_size,
51 AdspNotificationHandle *handle);
52
53 AdspErrorCode SystemServiceSendNotificationMessage(NotificationTarget notification_target,
54 AdspNotificationHandle message,
55 uint32_t actual_payload_size);
56
57 AdspErrorCode SystemServiceGetInterface(AdspIfaceId id, SystemServiceIface **iface);
58 }
59
60 namespace intel_adsp
61 {
62 namespace system
63 {
64
65 /* Structure storing handles to system service operations */
66 AdspSystemService SystemAgent::system_service_ = {
67 SystemServiceLogMessage,
68 SystemServiceSafeMemcpy,
69 SystemServiceSafeMemmove,
70 SystemServiceVecMemset,
71 SystemServiceCreateNotification,
72 SystemServiceSendNotificationMessage,
73 SystemServiceGetInterface,
74 };
75
SystemAgent(uint32_t module_id,uint32_t instance_id,uint32_t core_id,uint32_t log_handle)76 SystemAgent::SystemAgent(uint32_t module_id,
77 uint32_t instance_id,
78 uint32_t core_id,
79 uint32_t log_handle) :
80 log_handle_(log_handle),
81 core_id_(core_id),
82 module_id_(module_id),
83 instance_id_(instance_id),
84 module_handle_(NULL),
85 module_size_(0)
86 {}
87
CheckIn(ProcessingModuleInterface & processing_module,ModuleHandle & module_handle,LogHandle * & log_handle)88 void SystemAgent::CheckIn(ProcessingModuleInterface& processing_module,
89 ModuleHandle &module_handle,
90 LogHandle *&log_handle)
91 {
92 module_handle_ = &module_handle;
93 /* Initializes the ModuleAdapter into the ModuleHandle */
94 IadkModuleAdapter* module_adapter =
95 new (module_handle_)IadkModuleAdapter(processing_module,
96 NULL,
97 module_id_,
98 instance_id_,
99 core_id_,
100 module_size_
101 );
102 log_handle = reinterpret_cast<LogHandle*>(log_handle_);
103 }
104
CheckIn(ProcessingModuleFactoryInterface & module_factory,ModulePlaceholder * module_placeholder,size_t processing_module_size,uint32_t core_id,const void * obfuscated_mod_cfg,void * obfuscated_parent_ppl,void ** obfuscated_modinst_p)105 int SystemAgent::CheckIn(ProcessingModuleFactoryInterface& module_factory,
106 ModulePlaceholder *module_placeholder,
107 size_t processing_module_size,
108 uint32_t core_id,
109 const void *obfuscated_mod_cfg,
110 void *obfuscated_parent_ppl,
111 void **obfuscated_modinst_p)
112 {
113 IoPinsInfo pins_info;
114 const dsp_fw::DwordArray& cfg_ipc_msg =
115 *reinterpret_cast<const dsp_fw::DwordArray*>(obfuscated_mod_cfg);
116 ModuleInitialSettingsConcrete settings(cfg_ipc_msg);
117
118 ProcessingModulePrerequisites prerequisites;
119 module_factory.GetPrerequisites(prerequisites);
120
121 /* Note: If module has no output pins, it requires HungryRTSink */
122 /* to terminate parent Pipeline */
123 const bool hungry_rt_sink_required = prerequisites.output_pins_count == 0;
124 if (hungry_rt_sink_required) prerequisites.output_pins_count = 1;
125
126 if ((prerequisites.input_pins_count < 1) ||
127 (prerequisites.input_pins_count > INPUT_PIN_COUNT) ||
128 (prerequisites.output_pins_count < 1) ||
129 (prerequisites.output_pins_count > OUTPUT_PIN_COUNT))
130 return -1;
131
132 /* Deduce BaseModuleCfgExt if it was not part of the INIT_INSTANCE IPC message */
133 settings.DeduceBaseModuleCfgExt(prerequisites.input_pins_count,
134 prerequisites.output_pins_count);
135
136 module_factory.Create(*this, module_placeholder, ModuleInitialSettings(settings), pins_info);
137 IadkModuleAdapter& module_adapter = *reinterpret_cast<IadkModuleAdapter*>(module_handle_);
138 *obfuscated_modinst_p = &module_adapter;
139 reinterpret_cast<intel_adsp::ProcessingModuleInterface*>(module_placeholder)->Init();
140 return 0;
141 }
142
143 } /* namespace system */
144 } /* namespace intel_adsp */
145
146 #ifdef __cplusplus
147 extern "C" {
148 #endif
149 /* The create_instance_f is a function call type known in IADK module. The module entry_point
150 * points to this type of function which starts module creation.
151 */
152 typedef int (*create_instance_f)(uint32_t module_id, uint32_t instance_id, uint32_t core_id,
153 void *mod_cfg, void *parent_ppl, void **mod_ptr);
154
system_agent_start(uint32_t entry_point,uint32_t module_id,uint32_t instance_id,uint32_t core_id,uint32_t log_handle,void * mod_cfg)155 void* system_agent_start(uint32_t entry_point, uint32_t module_id, uint32_t instance_id,
156 uint32_t core_id, uint32_t log_handle, void* mod_cfg)
157 {
158 uint32_t ret;
159 SystemAgent system_agent(module_id, instance_id, core_id, log_handle);
160 void* system_agent_p = reinterpret_cast<void*>(&system_agent);
161
162 create_instance_f ci = (create_instance_f)(entry_point);
163 ret = ci(module_id, instance_id, core_id, mod_cfg, NULL, &system_agent_p);
164
165 return system_agent_p;
166 }
167
168 #ifdef __cplusplus
169 }
170 #endif
171
172 extern "C" void __cxa_pure_virtual() __attribute__((weak));
173
__cxa_pure_virtual()174 void __cxa_pure_virtual()
175 {
176 }
177
178