1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
4 //
5 // Author: Jakub Dabek <jakub.dabek@linux.intel.com>
6 // Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com>
7
8 #include <errno.h>
9 #include <rtos/alloc.h>
10 #include <rtos/timer.h>
11 #include <sof/lib/mm_heap.h>
12 #include <sof/ipc/topology.h>
13 #include <sof/ipc/msg.h>
14 #include <sof/ipc/driver.h>
15 #include <sof/schedule/edf_schedule.h>
16 #include <sof/schedule/ll_schedule.h>
17 #include <sof/schedule/schedule.h>
18 #include <rtos/spinlock.h>
19 #include <sof/audio/component_ext.h>
20 #include <rtos/clk.h>
21 #include <sof/lib/notifier.h>
22 #include <rtos/wait.h>
23 #include <arch/lib/cpu.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <stddef.h>
27 #include <setjmp.h>
28 #include <stdint.h>
29 #include <cmocka.h>
30
31 #define WEAK __attribute__((weak))
32
33 /* global contexts */
34 WEAK struct ipc *_ipc;
35 #ifndef __ZEPHYR__
36 WEAK struct timer *platform_timer;
37 #endif
38 WEAK struct schedulers *schedulers;
39 WEAK struct sof sof;
40 WEAK struct tr_ctx buffer_tr;
41 WEAK struct tr_ctx comp_tr;
42 WEAK struct tr_ctx ipc_tr;
43
rballoc_align(uint32_t flags,uint32_t caps,size_t bytes,uint32_t alignment)44 void WEAK *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes,
45 uint32_t alignment)
46 {
47 (void)flags;
48 (void)caps;
49
50 return calloc(bytes, 1);
51 }
52
rzalloc(enum mem_zone zone,uint32_t flags,uint32_t caps,size_t bytes)53 void WEAK *rzalloc(enum mem_zone zone, uint32_t flags, uint32_t caps,
54 size_t bytes)
55 {
56 (void)zone;
57 (void)flags;
58 (void)caps;
59
60 return calloc(bytes, 1);
61 }
62
rbrealloc_align(void * ptr,uint32_t flags,uint32_t caps,size_t bytes,size_t old_bytes,uint32_t alignment)63 void WEAK *rbrealloc_align(void *ptr, uint32_t flags, uint32_t caps,
64 size_t bytes, size_t old_bytes, uint32_t alignment)
65 {
66 (void)flags;
67 (void)caps;
68 (void)old_bytes;
69
70 return realloc(ptr, bytes);
71 }
72
rfree(void * ptr)73 void WEAK rfree(void *ptr)
74 {
75 free(ptr);
76 }
77
memcpy_s(void * dest,size_t dest_size,const void * src,size_t count)78 int WEAK memcpy_s(void *dest, size_t dest_size,
79 const void *src, size_t count)
80 {
81 if (!dest || !src)
82 return -EINVAL;
83
84 if ((dest >= src && (char *)dest < ((char *)src + count)) ||
85 (src >= dest && (char *)src < ((char *)dest + dest_size)))
86 return -EINVAL;
87
88 if (count > dest_size)
89 return -EINVAL;
90
91 memcpy(dest, src, count);
92
93 return 0;
94 }
95
memset_s(void * dest,size_t size1,int c,size_t size2)96 int WEAK memset_s(void *dest, size_t size1,
97 int c, size_t size2)
98 {
99 if (!dest)
100 return -EINVAL;
101
102 memset(dest, c, size1);
103
104 return 0;
105 }
106
rstrlen(const char * s)107 int WEAK rstrlen(const char *s)
108 {
109 return strlen(s);
110 }
111
__panic(uint32_t p,char * filename,uint32_t linenum)112 void WEAK __panic(uint32_t p, char *filename, uint32_t linenum)
113 {
114 fail_msg("panic: %s:%d (code 0x%x)\n", filename, linenum, p);
115 exit(EXIT_FAILURE);
116 }
117
118 #if CONFIG_TRACE
trace_log_filtered(bool send_atomic,const void * log_entry,const struct tr_ctx * ctx,uint32_t lvl,uint32_t id_1,uint32_t id_2,int arg_count,va_list args)119 void WEAK trace_log_filtered(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx,
120 uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count,
121 va_list args)
122 {
123 (void) send_atomic;
124 (void) log_entry;
125 (void) ctx;
126 (void) lvl;
127 (void) id_1;
128 (void) id_2;
129 (void) arg_count;
130 (void) args;
131 }
132
_log_sofdict(log_func_t sofdict_logf,bool atomic,const void * log_entry,const struct tr_ctx * ctx,const uint32_t lvl,uint32_t id_1,uint32_t id_2,int arg_count,...)133 void WEAK _log_sofdict(log_func_t sofdict_logf, bool atomic, const void *log_entry,
134 const struct tr_ctx *ctx, const uint32_t lvl,
135 uint32_t id_1, uint32_t id_2, int arg_count, ...)
136 {
137 }
138
trace_flush_dma_to_mbox(void)139 void WEAK trace_flush_dma_to_mbox(void)
140 {
141 }
142 #endif
143
144 #if CONFIG_LIBRARY
145 volatile void *task_context_get(void);
146 #endif
task_context_get(void)147 volatile void * WEAK task_context_get(void)
148 {
149 return NULL;
150 }
151
152 #ifndef __ZEPHYR__
_k_spin_lock_irq(struct k_spinlock * lock)153 uint32_t WEAK _k_spin_lock_irq(struct k_spinlock *lock)
154 {
155 (void)lock;
156
157 return 0;
158 }
159
_k_spin_unlock_irq(struct k_spinlock * lock,uint32_t flags,int line)160 void WEAK _k_spin_unlock_irq(struct k_spinlock *lock, uint32_t flags, int line)
161 {
162 (void)lock;
163 (void)flags;
164 (void)line;
165 }
166 #endif
167
platform_timer_get(struct timer * timer)168 uint64_t WEAK platform_timer_get(struct timer *timer)
169 {
170 (void)timer;
171
172 return 0;
173 }
174
175 #if !CONFIG_LIBRARY
arch_timer_get_system(struct timer * timer)176 uint64_t WEAK arch_timer_get_system(struct timer *timer)
177 {
178 (void)timer;
179
180 return 0;
181 }
182 #endif
183
184 #if CONFIG_LIBRARY
185 void WEAK arch_dump_regs_a(void *dump_buf);
186 #endif
arch_dump_regs_a(void * dump_buf)187 void WEAK arch_dump_regs_a(void *dump_buf)
188 {
189 (void)dump_buf;
190 }
191
heap_trace_all(int force)192 void WEAK heap_trace_all(int force)
193 {
194 (void)force;
195 }
196
ipc_msg_send(struct ipc_msg * msg,void * data,bool high_priority)197 void WEAK ipc_msg_send(struct ipc_msg *msg, void *data, bool high_priority)
198 {
199 (void)msg;
200 (void)data;
201 (void)high_priority;
202 }
203
platform_ipc_init(struct ipc * ipc)204 int WEAK platform_ipc_init(struct ipc *ipc)
205 {
206 return 0;
207 }
208
ipc_platform_do_cmd(struct ipc * ipc)209 enum task_state WEAK ipc_platform_do_cmd(struct ipc *ipc)
210 {
211 return 0;
212 }
213
ipc_platform_complete_cmd(struct ipc * ipc)214 void WEAK ipc_platform_complete_cmd(struct ipc *ipc)
215 {
216 }
217
218 #if !CONFIG_LIBRARY
ipc_platform_send_msg(const struct ipc_msg * msg)219 int WEAK ipc_platform_send_msg(const struct ipc_msg *msg)
220 {
221 return 0;
222 }
223
wait_delay(uint64_t number_of_clks)224 void WEAK wait_delay(uint64_t number_of_clks)
225 {
226 }
227
wait_delay_ms(uint64_t ms)228 void WEAK wait_delay_ms(uint64_t ms)
229 {
230 }
231
wait_delay_us(uint64_t us)232 void WEAK wait_delay_us(uint64_t us)
233 {
234 }
235
xthal_icache_region_invalidate(void * addr,unsigned size)236 void WEAK xthal_icache_region_invalidate(void *addr, unsigned size)
237 {
238 }
239
xthal_dcache_region_invalidate(void * addr,unsigned size)240 void WEAK xthal_dcache_region_invalidate(void *addr, unsigned size)
241 {
242 }
243
xthal_dcache_region_writeback(void * addr,unsigned size)244 void WEAK xthal_dcache_region_writeback(void *addr, unsigned size)
245 {
246 }
247
xthal_dcache_region_writeback_inv(void * addr,unsigned size)248 void WEAK xthal_dcache_region_writeback_inv(void *addr, unsigned size)
249 {
250 }
251 #endif
252
sof_get(void)253 struct sof * WEAK sof_get(void)
254 {
255 return &sof;
256 }
257
arch_schedulers_get(void)258 struct schedulers ** WEAK arch_schedulers_get(void)
259 {
260 return &schedulers;
261 }
262
schedule_task_init(struct task * task,const struct sof_uuid_entry * uid,uint16_t type,uint16_t priority,enum task_state (* run)(void * data),void * data,uint16_t core,uint32_t flags)263 int WEAK schedule_task_init(struct task *task,
264 const struct sof_uuid_entry *uid, uint16_t type,
265 uint16_t priority, enum task_state (*run)(void *data),
266 void *data, uint16_t core, uint32_t flags)
267 {
268 (void)task;
269 (void)uid;
270 (void)type;
271 (void)priority;
272 (void)run;
273 (void)data;
274 (void)core;
275 (void)flags;
276
277 return 0;
278 }
279
schedule_task_init_ll(struct task * task,const struct sof_uuid_entry * uid,uint16_t type,uint16_t priority,enum task_state (* run)(void * data),void * data,uint16_t core,uint32_t flags)280 int WEAK schedule_task_init_ll(struct task *task,
281 const struct sof_uuid_entry *uid, uint16_t type,
282 uint16_t priority, enum task_state (*run)(void *data),
283 void *data, uint16_t core, uint32_t flags)
284 {
285 return 0;
286 }
287
platform_host_timestamp(struct comp_dev * host,struct sof_ipc_stream_posn * posn)288 void WEAK platform_host_timestamp(struct comp_dev *host,
289 struct sof_ipc_stream_posn *posn)
290 {
291 (void)host;
292 (void)posn;
293 }
294
platform_dai_timestamp(struct comp_dev * dai,struct sof_ipc_stream_posn * posn)295 void WEAK platform_dai_timestamp(struct comp_dev *dai,
296 struct sof_ipc_stream_posn *posn)
297 {
298 (void)dai;
299 (void)posn;
300 }
301
ipc_get_comp_by_id(struct ipc * ipc,uint32_t id)302 struct ipc_comp_dev * WEAK ipc_get_comp_by_id(struct ipc *ipc, uint32_t id)
303 {
304 (void)ipc;
305 (void)id;
306
307 return NULL;
308 }
309
ipc_get_comp_by_ppl_id(struct ipc * ipc,uint16_t type,uint32_t ppl_id)310 struct ipc_comp_dev *WEAK ipc_get_comp_by_ppl_id(struct ipc *ipc, uint16_t type,
311 uint32_t ppl_id)
312 {
313 (void)ipc;
314 (void)type;
315 (void)ppl_id;
316
317 return NULL;
318 }
319
crc32(uint32_t base,const void * data,uint32_t bytes)320 uint32_t WEAK crc32(uint32_t base, const void *data, uint32_t bytes)
321 {
322 return 0;
323 }
324
comp_set_state(struct comp_dev * dev,int cmd)325 int WEAK comp_set_state(struct comp_dev *dev, int cmd)
326 {
327 return 0;
328 }
329
330 #ifndef __ZEPHYR__
clock_ms_to_ticks(int clock,uint64_t ms)331 uint64_t WEAK clock_ms_to_ticks(int clock, uint64_t ms)
332 {
333 (void)clock;
334 (void)ms;
335
336 return 0;
337 }
338
clock_us_to_ticks(int clock,uint64_t us)339 uint64_t WEAK clock_us_to_ticks(int clock, uint64_t us)
340 {
341 (void)clock;
342 (void)us;
343
344 return 0;
345 }
346
clock_ns_to_ticks(int clock,uint64_t us)347 uint64_t WEAK clock_ns_to_ticks(int clock, uint64_t us)
348 {
349 (void)clock;
350 (void)us;
351
352 return 0;
353 }
354 #endif /* __ZEPHYR__ */
355
356 #if CONFIG_MULTICORE && !CONFIG_LIBRARY
357
idc_send_msg(struct idc_msg * msg,uint32_t mode)358 int WEAK idc_send_msg(struct idc_msg *msg, uint32_t mode)
359 {
360 (void)msg;
361 (void)mode;
362
363 return 0;
364 }
365
arch_cpu_is_core_enabled(int id)366 int WEAK arch_cpu_is_core_enabled(int id)
367 {
368 return 0;
369 }
370
371 #endif
372
373 #if CONFIG_LIBRARY
374 /* enable trace by default in testbench */
375 int WEAK test_bench_trace = 1;
376 int WEAK debug;
377
378 /* ... but not always in unit tests */
379 #if CONFIG_TRACE
380 /* look up subsystem class name from table */
get_trace_class(uint32_t trace_class)381 char * WEAK get_trace_class(uint32_t trace_class)
382 {
383 (void)trace_class;
384 /* todo: trace class is deprecated,
385 * uuid should be used only
386 */
387 return "unknown";
388 }
389 #endif
390
get_library_mailbox(void)391 uint8_t * WEAK get_library_mailbox(void)
392 {
393 return NULL;
394 }
395 #endif
396
397 /*
398 * GCC xtensa requires us to fake some of the standard C library calls
399 * as this is "bare metal" support (i.e. with no host OS implementation
400 * methods for these calls).
401 *
402 * None of these IO calls are used in the Mocks for testing.
403 */
404 #if !CONFIG_LIBRARY && !__XCC__
405 void _exit(int status);
406 unsigned int _getpid_r(void);
407 int _kill_r(int id, int sig);
408 void _sbrk_r(int id);
409 int _fstat_r(int fd, void *buf);
410 int _open_r(const char *pathname, int flags);
411 int _write_r(int fd, char *buf, int count);
412 int _read_r(int fd, char *buf, int count);
413 int _lseek_r(int fd, int count);
414 int _close_r(int fd);
415 int _isatty(int fd);
416
_exit(int status)417 void _exit(int status)
418 {
419 while (1);
420 }
421
_getpid_r(void)422 unsigned int _getpid_r(void)
423 {
424 return 0;
425 }
426
_kill_r(int id,int sig)427 int _kill_r(int id, int sig)
428 {
429 return 0;
430 }
431
_sbrk_r(int id)432 void _sbrk_r(int id)
433 {
434 }
435
_fstat_r(int fd,void * buf)436 int _fstat_r(int fd, void *buf)
437 {
438 return 0;
439 }
440
_open_r(const char * pathname,int flags)441 int _open_r(const char *pathname, int flags)
442 {
443 return 0;
444 }
445
_write_r(int fd,char * buf,int count)446 int _write_r(int fd, char *buf, int count)
447 {
448 return 0;
449 }
450
_read_r(int fd,char * buf,int count)451 int _read_r(int fd, char *buf, int count)
452 {
453 return 0;
454 }
455
_lseek_r(int fd,int count)456 int _lseek_r(int fd, int count)
457 {
458 return 0;
459 }
460
_close_r(int fd)461 int _close_r(int fd)
462 {
463 return 0;
464 }
465
_isatty(int fd)466 int _isatty(int fd)
467 {
468 return 0;
469 }
470
471 /* TODO: work around some linker warnings. Both will need fixed for qemu. */
472 int _start = 0;
473 int *__errno _PARAMS ((void));
474
475 /*
476 * TODO: Math support for GCC xtensa requires a little more work to use the
477 * newlib versions. This is just to build test only today !
478 */
479 double __floatsidf(int i);
480 double __divdf3(double a, double b);
481 int __ledf2(double a, double b);
482 int __eqdf2(double a, double b);
483
__floatsidf(int i)484 double __floatsidf(int i)
485 {
486 return i;
487 }
488
__divdf3(double a,double b)489 double __divdf3(double a, double b)
490 {
491 return a / b;
492 }
493
__ledf2(double a,double b)494 int WEAK __ledf2(double a, double b)
495 {
496 return a <= b ? 0 : 1;
497 }
498
__eqdf2(double a,double b)499 int WEAK __eqdf2(double a, double b)
500 {
501 return a == b ? 0 : 1;
502 }
503 #endif
504