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