1 /*
2  * Copyright (c) 2014, Mentor Graphics Corporation
3  * Copyright (c) 2015 Xilinx, Inc.
4  * Copyright (c) 2016 Freescale Semiconductor, Inc.
5  * Copyright 2016-2022 NXP
6  * Copyright 2021 ACRIOS Systems s.r.o.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  *    this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  *    this list of conditions and the following disclaimer in the documentation
16  *    and/or other materials provided with the distribution.
17  * 3. Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /**************************************************************************
35  * FILE NAME
36  *
37  *       rpmsg_env.h
38  *
39  * COMPONENT
40  *
41  *         OpenAMP stack.
42  *
43  * DESCRIPTION
44  *
45  *       This file defines abstraction layer for OpenAMP stack. The implementor
46  *       must provide definition of all the functions.
47  *
48  * DATA STRUCTURES
49  *
50  *        none
51  *
52  * FUNCTIONS
53  *
54  *       env_allocate_memory
55  *       env_free_memory
56  *       env_memset
57  *       env_memcpy
58  *       env_strncpy
59  *       env_print
60  *       env_map_vatopa
61  *       env_map_patova
62  *       env_mb
63  *       env_rmb
64  *       env_wmb
65  *       env_create_mutex
66  *       env_delete_mutex
67  *       env_lock_mutex
68  *       env_unlock_mutex
69  *       env_sleep_msec
70  *       env_disable_interrupt
71  *       env_enable_interrupt
72  *       env_create_queue
73  *       env_delete_queue
74  *       env_put_queue
75  *       env_get_queue
76  *       env_wait_for_link_up
77  *       env_tx_callback
78  *
79  **************************************************************************/
80 #ifndef RPMSG_ENV_H_
81 #define RPMSG_ENV_H_
82 
83 #include <stdint.h>
84 #include "rpmsg_default_config.h"
85 #include "rpmsg_env_specific.h"
86 #include "rpmsg_platform.h"
87 
88 /*!
89  * env_init
90  *
91  * Initializes OS/BM environment.
92  *
93  * @param env_context        Pointer to preallocated environment context data
94  * @param env_init_data      Initialization data for the environment layer
95  *
96  * @returns - execution status
97  */
98 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
99 int32_t env_init(void **env_context, void *env_init_data);
100 #else
101 int32_t env_init(void);
102 #endif
103 
104 /*!
105  * env_deinit
106  *
107  * Uninitializes OS/BM environment.
108  *
109  * @param env_context   Pointer to environment context data
110  *
111  * @returns - execution status
112  */
113 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
114 int32_t env_deinit(void *env_context);
115 #else
116 int32_t env_deinit(void);
117 #endif
118 
119 /*!
120  * -------------------------------------------------------------------------
121  *
122  * Dynamic memory management functions. The parameters
123  * are similar to standard c functions.
124  *
125  *-------------------------------------------------------------------------
126  **/
127 
128 /*!
129  * env_allocate_memory
130  *
131  * Allocates memory with the given size.
132  *
133  * @param size - size of memory to allocate
134  *
135  * @return - pointer to allocated memory
136  */
137 void *env_allocate_memory(uint32_t size);
138 
139 /*!
140  * env_free_memory
141  *
142  * Frees memory pointed by the given parameter.
143  *
144  * @param ptr - pointer to memory to free
145  */
146 void env_free_memory(void *ptr);
147 
148 /*!
149  * -------------------------------------------------------------------------
150  *
151  * RTL Functions
152  *
153  *-------------------------------------------------------------------------
154  */
155 
156 void env_memset(void *ptr, int32_t value, uint32_t size);
157 void env_memcpy(void *dst, void const *src, uint32_t len);
158 int32_t env_strcmp(const char *dst, const char *src);
159 void env_strncpy(char *dest, const char *src, uint32_t len);
160 int32_t env_strncmp(char *dest, const char *src, uint32_t len);
161 #ifdef MCUXPRESSO_SDK
162 /* MCUXpresso_SDK's PRINTF used in SDK examples */
163 #include "fsl_debug_console.h"
164 #if defined SDK_DEBUGCONSOLE && (SDK_DEBUGCONSOLE != DEBUGCONSOLE_DISABLE)
165 #define env_print(...) (void)PRINTF(__VA_ARGS__)
166 #else
167 #define env_print(...)
168 #endif
169 #else
170 /* When RPMsg_Lite being used outside of MCUXpresso_SDK use your own env_print
171    implemenetation to avoid conflict with Misra 21.6 rule */
172 #include <stdio.h>
173 #define env_print(...) (void)printf(__VA_ARGS__)
174 #endif /* MCUXPRESSO_SDK */
175 
176 /*!
177  *-----------------------------------------------------------------------------
178  *
179  *  Functions to convert physical address to virtual address and vice versa.
180  *
181  *-----------------------------------------------------------------------------
182  */
183 
184 /*!
185  * env_map_vatopa
186  *
187  * Converts logical address to physical address
188  *
189  * @param env       Pointer to environment context data
190  * @param address   Pointer to logical address
191  *
192  * @return  - physical address
193  */
194 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
195 uint32_t env_map_vatopa(void *env, void *address);
196 #else
197 uint32_t env_map_vatopa(void *address);
198 #endif
199 
200 /*!
201  * env_map_patova
202  *
203  * Converts physical address to logical address
204  *
205  * @param env_context   Pointer to environment context data
206  * @param address       Pointer to physical address
207  *
208  * @return  - logical address
209  *
210  */
211 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
212 void *env_map_patova(void *env, uint32_t address);
213 #else
214 void *env_map_patova(uint32_t address);
215 #endif
216 
217 /*!
218  *-----------------------------------------------------------------------------
219  *
220  *  Abstractions for memory barrier instructions.
221  *
222  *-----------------------------------------------------------------------------
223  */
224 
225 /*!
226  * env_mb
227  *
228  * Inserts memory barrier.
229  */
230 
231 void env_mb(void);
232 
233 /*!
234  * env_rmb
235  *
236  * Inserts read memory barrier
237  */
238 
239 void env_rmb(void);
240 
241 /*!
242  * env_wmb
243  *
244  * Inserts write memory barrier
245  */
246 
247 void env_wmb(void);
248 
249 /*!
250  *-----------------------------------------------------------------------------
251  *
252  *  Abstractions for OS lock primitives.
253  *
254  *-----------------------------------------------------------------------------
255  */
256 
257 /*!
258  * env_create_mutex
259  *
260  * Creates a mutex with given initial count.
261  *
262  * @param lock -  pointer to created mutex
263  * @param count - initial count 0 or 1
264  * @param context - context for mutex
265  *
266  * @return - status of function execution
267  */
268 #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
269 int32_t env_create_mutex(void **lock, int32_t count, void *context);
270 #else
271 int32_t env_create_mutex(void **lock, int32_t count);
272 #endif
273 
274 /*!
275  * env_delete_mutex
276  *
277  * Deletes the given lock.
278  *
279  * @param lock - mutex to delete
280  */
281 
282 void env_delete_mutex(void *lock);
283 
284 /*!
285  * env_lock_mutex
286  *
287  * Tries to acquire the lock, if lock is not available then call to
288  * this function will suspend.
289  *
290  * @param lock - mutex to lock
291  *
292  */
293 
294 void env_lock_mutex(void *lock);
295 
296 /*!
297  * env_unlock_mutex
298  *
299  * Releases the given lock.
300  *
301  * @param lock - mutex to unlock
302  */
303 
304 void env_unlock_mutex(void *lock);
305 
306 /*!
307  * env_create_sync_lock
308  *
309  * Creates a synchronization lock primitive. It is used
310  * when signal has to be sent from the interrupt context to main
311  * thread context.
312  *
313  * @param lock  - pointer to created sync lock object
314  * @param state - initial state , lock or unlocked
315  * @param context - context for lock
316  *
317  * @returns - status of function execution
318  */
319 #define LOCKED   0
320 #define UNLOCKED 1
321 
322 #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
323 int32_t env_create_sync_lock(void **lock, int32_t state, void *context);
324 #else
325 int32_t env_create_sync_lock(void **lock, int32_t state);
326 #endif
327 
328 /*!
329  * env_create_sync_lock
330  *
331  * Deletes given sync lock object.
332  *
333  * @param lock  - sync lock to delete.
334  *
335  */
336 
337 void env_delete_sync_lock(void *lock);
338 
339 /*!
340  * env_acquire_sync_lock
341  *
342  * Tries to acquire the sync lock.
343  *
344  * @param lock  - sync lock to acquire.
345  */
346 void env_acquire_sync_lock(void *lock);
347 
348 /*!
349  * env_release_sync_lock
350  *
351  * Releases synchronization lock.
352  *
353  * @param lock  - sync lock to release.
354  */
355 void env_release_sync_lock(void *lock);
356 
357 /*!
358  * env_sleep_msec
359  *
360  * Suspends the calling thread for given time in msecs.
361  *
362  * @param num_msec -  delay in msecs
363  */
364 void env_sleep_msec(uint32_t num_msec);
365 
366 /*!
367  * env_register_isr
368  *
369  * Registers interrupt handler data for the given interrupt vector.
370  *
371  * @param env           Pointer to environment context data
372  * @param vector_id     Virtual interrupt vector number
373  * @param data          Interrupt handler data (virtqueue)
374  */
375 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
376 void env_register_isr(void *env, uint32_t vector_id, void *data);
377 #else
378 void env_register_isr(uint32_t vector_id, void *data);
379 #endif
380 
381 /*!
382  * env_unregister_isr
383  *
384  * Unregisters interrupt handler data for the given interrupt vector.
385  *
386  * @param env           Pointer to environment context data
387  * @param vector_id     Virtual interrupt vector number
388  */
389 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
390 void env_unregister_isr(void *env, uint32_t vector_id);
391 #else
392 void env_unregister_isr(uint32_t vector_id);
393 #endif
394 
395 /*!
396  * env_enable_interrupt
397  *
398  * Enables the given interrupt
399  *
400  * @param env           Pointer to environment context data
401  * @param vector_id     Virtual interrupt vector number
402  */
403 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
404 void env_enable_interrupt(void *env, uint32_t vector_id);
405 #else
406 void env_enable_interrupt(uint32_t vector_id);
407 #endif
408 
409 /*!
410  * env_disable_interrupt
411  *
412  * Disables the given interrupt.
413  *
414  * @param env           Pointer to environment context data
415  * @param vector_id     Virtual interrupt vector number
416  */
417 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
418 void env_disable_interrupt(void *env, uint32_t vector_id);
419 #else
420 void env_disable_interrupt(uint32_t vector_id);
421 #endif
422 
423 /*!
424  * env_map_memory
425  *
426  * Enables memory mapping for given memory region.
427  *
428  * @param pa   - physical address of memory
429  * @param va   - logical address of memory
430  * @param size - memory size
431  * param flags - flags for cache/uncached  and access type
432  *
433  * Currently only first byte of flag parameter is used and bits mapping is defined as follow;
434  *
435  * Cache bits
436  * 0x0000_0001 = No cache
437  * 0x0000_0010 = Write back
438  * 0x0000_0100 = Write through
439  * 0x0000_x000 = Not used
440  *
441  * Memory types
442  *
443  * 0x0001_xxxx = Memory Mapped
444  * 0x0010_xxxx = IO Mapped
445  * 0x0100_xxxx = Shared
446  * 0x1000_xxxx = TLB
447  */
448 
449 /* Macros for caching scheme used by the shared memory */
450 #define UNCACHED (1 << 0)
451 #define WB_CACHE (1 << 1)
452 #define WT_CACHE (1 << 2)
453 
454 /* Memory Types */
455 #define MEM_MAPPED (1 << 4)
456 #define IO_MAPPED  (1 << 5)
457 #define SHARED_MEM (1 << 6)
458 #define TLB_MEM    (1 << 7)
459 
460 void env_map_memory(uint32_t pa, uint32_t va, uint32_t size, uint32_t flags);
461 
462 /*!
463  * env_get_timestamp
464  *
465  * Returns a 64 bit time stamp.
466  *
467  *
468  */
469 uint64_t env_get_timestamp(void);
470 
471 /*!
472  * env_disable_cache
473  *
474  * Disables system caches.
475  *
476  */
477 
478 void env_disable_cache(void);
479 
480 typedef void LOCK;
481 
482 /*!
483  * env_create_queue
484  *
485  * Creates a message queue.
486  *
487  * @param queue      Pointer to created queue
488  * @param length     Maximum number of elements in the queue
489  * @param item_size  Queue element size in bytes
490  * @param queue_static_storage Pointer to queue static storage buffer
491  * @param queue_static_context Pointer to queue static context
492  *
493  * @return - status of function execution
494  */
495 #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
496 int32_t env_create_queue(void **queue,
497                          int32_t length,
498                          int32_t element_size,
499                          uint8_t *queue_static_storage,
500                          rpmsg_static_queue_ctxt *queue_static_context);
501 #else
502 int32_t env_create_queue(void **queue, int32_t length, int32_t element_size);
503 #endif
504 
505 /*!
506  * env_delete_queue
507  *
508  * Deletes the message queue.
509  *
510  * @param queue   Queue to delete
511  */
512 
513 void env_delete_queue(void *queue);
514 
515 /*!
516  * env_put_queue
517  *
518  * Put an element in a queue.
519  *
520  * @param queue       Queue to put element in
521  * @param msg         Pointer to the message to be put into the queue
522  * @param timeout_ms  Timeout in ms
523  *
524  * @return - status of function execution
525  */
526 
527 int32_t env_put_queue(void *queue, void *msg, uintptr_t timeout_ms);
528 
529 /*!
530  * env_get_queue
531  *
532  * Get an element out of a queue.
533  *
534  * @param queue       Queue to get element from
535  * @param msg         Pointer to a memory to save the message
536  * @param timeout_ms  Timeout in ms
537  *
538  * @return - status of function execution
539  */
540 
541 int32_t env_get_queue(void *queue, void *msg, uintptr_t timeout_ms);
542 
543 /*!
544  * env_get_current_queue_size
545  *
546  * Get current queue size.
547  *
548  * @param queue    Queue pointer
549  *
550  * @return - Number of queued items in the queue
551  */
552 
553 int32_t env_get_current_queue_size(void *queue);
554 
555 /*!
556  * env_isr
557  *
558  * Invoke RPMSG/IRQ callback
559  *
560  * @param env           Pointer to environment context data
561  * @param vector        RPMSG IRQ vector ID.
562  */
563 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
564 void env_isr(void *env, uint32_t vector);
565 #else
566 void env_isr(uint32_t vector);
567 #endif
568 
569 #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
570 /*!
571  * env_get_platform_context
572  *
573  * Get the platform layer context from the environment platform context
574  *
575  * @param env     Pointer to environment context data
576  *
577  * @return        Pointer to platform context data
578  */
579 void *env_get_platform_context(void *env_context);
580 
581 /*!
582  * env_init_interrupt
583  *
584  * Initialize the ISR data for given virtqueue interrupt
585  *
586  * @param env       Pointer to environment context data
587  * @param vq_id     Virtqueue ID
588  * @param isr_data  Pointer to initial ISR data
589  *
590  * @return        Execution status, 0 on success
591  */
592 int32_t env_init_interrupt(void *env, int32_t vq_id, void *isr_data);
593 
594 /*!
595  * env_deinit_interrupt
596  *
597  * Deinitialize the ISR data for given virtqueue interrupt
598  *
599  * @param env       Pointer to environment context data
600  * @param vq_id     Virtqueue ID
601  *
602  * @return        Execution status, 0 on success
603  */
604 int32_t env_deinit_interrupt(void *env, int32_t vq_id);
605 #endif
606 
607 /*!
608  * env_wait_for_link_up
609  *
610  * Env. specific implementation of rpmsg_lite_wait_for_link_up function with the usage
611  * of RTOS sync. primitives to avoid busy loop. Returns once the link is up.
612  *
613  * @param link_state  Pointer to the link_state parameter of the rpmsg_lite_instance structure
614  * @param link_id     Link ID used to define the rpmsg-lite instance, see rpmsg_platform.h
615  * @param timeout_ms  Timeout in ms
616  *
617  * @return RL_TRUE when link up, RL_FALSE when timeout.
618  *
619  */
620 uint32_t env_wait_for_link_up(volatile uint32_t *link_state, uint32_t link_id, uint32_t timeout_ms);
621 
622 /*!
623  * env_tx_callback
624  *
625  * Called from rpmsg_lite_tx_callback() to allow unblocking of env_wait_for_link_up()
626  *
627  * @param link_id     Link ID used to define the rpmsg-lite instance, see rpmsg_platform.h
628  */
629 void env_tx_callback(uint32_t link_id);
630 
631 #endif /* RPMSG_ENV_H_ */
632