2c25873d3de2aeab8e075fac78901041bf6fd774
[processor-sdk/open-amp.git] / lib / system / generic / bm_env.c
1 /*
2  * Copyright (c) 2014, Mentor Graphics Corporation
3  * All rights reserved.
4  * Copyright (c) 2015 Xilinx, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  *    this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *    this list of conditions and the following disclaimer in the documentation
13  *    and/or other materials provided with the distribution.
14  * 3. Neither the name of Mentor Graphics Corporation nor the names of its
15  *    contributors may be used to endorse or promote products derived from this
16  *    software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
31 /**************************************************************************
32  * FILE NAME
33  *
34  *       bm_env.c
35  *
36  *
37  * DESCRIPTION
38  *
39  *       This file is Bare Metal Implementation of env layer for OpenAMP.
40  *
41  *
42  **************************************************************************/
44 #include "openamp/env.h"
45 #include "machine.h"
46 #include "machine_system.h"
48 #include <stdlib.h>
49 #include <string.h>
51 static void acquire_spin_lock(void *plock);
52 static void release_spin_lock(void *plock);
54 /* Max supprted ISR counts */
55 #define ISR_COUNT                       4
56 /**
57  * Structure to keep track of registered ISR's.
58  */
59 struct isr_info {
60         int vector;
61         int priority;
62         int type;
63         void *data;
64         void (*isr)(int vector, void *data);
65 };
66 struct isr_info isr_table[ISR_COUNT];
67 int Intr_Count = 0;
68 /* Flag to show status of global interrupts. 0 for disabled and 1 for enabled. This
69  * is added to prevent recursive global interrupts enablement/disablement.
70  */
71 int Intr_Enable_Flag = 1;
73 /**
74  * env_init
75  *
76  * Initializes OS/BM environment.
77  *
78  */
79 int env_init()
80 {
81         return 0;
82 }
84 /**
85  * env_deinit
86  *
87  * Uninitializes OS/BM environment.
88  *
89  * @returns - execution status
90  */
92 int env_deinit()
93 {
94         return 0;
95 }
97 /**
98  * env_allocate_memory - implementation
99  *
100  * @param size
101  */
102 void *env_allocate_memory(unsigned int size)
104         return (malloc(size));
107 /**
108  * env_free_memory - implementation
109  *
110  * @param ptr
111  */
112 void env_free_memory(void *ptr)
114         if (ptr != NULL) {
115                 free(ptr);
116         }
119 /**
120  *
121  * env_memset - implementation
122  *
123  * @param ptr
124  * @param value
125  * @param size
126  */
127 void env_memset(void *ptr, int value, unsigned long size)
129         memset(ptr, value, size);
132 /**
133  *
134  * env_memcpy - implementation
135  *
136  * @param dst
137  * @param src
138  * @param len
139  */
140 void env_memcpy(void *dst, void const *src, unsigned long len)
142         memcpy(dst, src, len);
145 /**
146  *
147  * env_strcmp - implementation
148  *
149  * @param dst
150  * @param src
151  */
153 int env_strcmp(const char *dst, const char *src)
155         return (strcmp(dst, src));
158 /**
159  *
160  * env_strncpy - implementation
161  *
162  * @param dest
163  * @param src
164  * @param len
165  */
166 void env_strncpy(char *dest, const char *src, unsigned long len)
168         strncpy(dest, src, len);
171 /**
172  *
173  * env_strncmp - implementation
174  *
175  * @param dest
176  * @param src
177  * @param len
178  */
179 int env_strncmp(char *dest, const char *src, unsigned long len)
181         return (strncmp(dest, src, len));
184 /**
185  *
186  * env_mb - implementation
187  *
188  */
189 void env_mb()
191         MEM_BARRIER();
194 /**
195  * osalr_mb - implementation
196  */
197 void env_rmb()
199         MEM_BARRIER();
202 /**
203  * env_wmb - implementation
204  */
205 void env_wmb()
207         MEM_BARRIER();
210 /**
211  * env_map_vatopa - implementation
212  *
213  * @param address
214  */
215 unsigned long env_map_vatopa(void *address)
217         return platform_vatopa(address);
220 /**
221  * env_map_patova - implementation
222  *
223  * @param address
224  */
225 void *env_map_patova(unsigned long address)
227         return platform_patova(address);
230 /**
231  * env_create_mutex
232  *
233  * Creates a mutex with the given initial count.
234  *
235  */
236 int env_create_mutex(void **lock, int count)
238         return 0;
241 /**
242  * env_delete_mutex
243  *
244  * Deletes the given lock
245  *
246  */
247 void env_delete_mutex(void *lock)
251 /**
252  * env_lock_mutex
253  *
254  * Tries to acquire the lock, if lock is not available then call to
255  * this function will suspend.
256  */
257 void env_lock_mutex(void *lock)
259         env_disable_interrupts();
262 /**
263  * env_unlock_mutex
264  *
265  * Releases the given lock.
266  */
268 void env_unlock_mutex(void *lock)
270         env_restore_interrupts();
273 /**
274  * env_create_sync_lock
275  *
276  * Creates a synchronization lock primitive. It is used
277  * when signal has to be sent from the interrupt context to main
278  * thread context.
279  */
280 int env_create_sync_lock(void **lock, int state)
282         int *slock;
284         slock = (int *)malloc(sizeof(int));
285         if (slock) {
286                 *slock = state;
287                 *lock = slock;
288         } else {
289                 *lock = NULL;
290                 return -1;
291         }
293         return 0;
296 /**
297  * env_delete_sync_lock
298  *
299  * Deletes the given lock
300  *
301  */
302 void env_delete_sync_lock(void *lock)
304         if (lock)
305                 free(lock);
308 /**
309  * env_acquire_sync_lock
310  *
311  * Tries to acquire the lock, if lock is not available then call to
312  * this function waits for lock to become available.
313  */
314 void env_acquire_sync_lock(void *lock)
316         acquire_spin_lock(lock);
319 /**
320  * env_release_sync_lock
321  *
322  * Releases the given lock.
323  */
325 void env_release_sync_lock(void *lock)
327         release_spin_lock(lock);
330 /**
331  * env_sleep_msec
332  *
333  * Suspends the calling thread for given time , in msecs.
334  */
336 void env_sleep_msec(int num_msec)
341 /**
342  * env_disable_interrupts
343  *
344  * Disables system interrupts
345  *
346  */
347 void env_disable_interrupts()
349         if (Intr_Enable_Flag == 1) {
350                 disable_global_interrupts();
351                 Intr_Enable_Flag = 0;
352         }
355 /**
356  * env_restore_interrupts
357  *
358  * Enables system interrupts
359  *
360  */
361 void env_restore_interrupts()
363         if (Intr_Enable_Flag == 0) {
364                 restore_global_interrupts();
365                 Intr_Enable_Flag = 1;
366         }
369 /**
370  * env_register_isr
371  *
372  * Registers interrupt handler for the given interrupt vector.
373  *
374  * @param vector - interrupt vector number
375  * @param isr    - interrupt handler
376  */
377 void env_register_isr(int vector, void *data,
378                       void (*isr) (int vector, void *data))
380         env_disable_interrupts();
382         if (Intr_Count < ISR_COUNT) {
383                 /* Save interrupt data */
384                 isr_table[Intr_Count].vector = vector;
385                 isr_table[Intr_Count].data = data;
386                 isr_table[Intr_Count++].isr = isr;
387         }
389         env_restore_interrupts();
392 void env_update_isr(int vector, void *data,
393                     void (*isr) (int vector, void *data))
395         int idx;
396         struct isr_info *info;
398         env_disable_interrupts();
400         for (idx = 0; idx < ISR_COUNT; idx++) {
401                 info = &isr_table[idx];
402                 if (info->vector == vector) {
403                         info->data = data;
404                         info->isr = isr;
405                         break;
406                 }
407         }
409         env_restore_interrupts();
412 /**
413  * env_enable_interrupt
414  *
415  * Enables the given interrupt
416  *
417  * @param vector   - interrupt vector number
418  * @param priority - interrupt priority
419  * @param polarity - interrupt polarity
420  */
422 void env_enable_interrupt(unsigned int vector, unsigned int priority,
423                           unsigned int polarity)
425         int idx;
427         env_disable_interrupts();
429         for (idx = 0; idx < ISR_COUNT; idx++) {
430                 if (isr_table[idx].vector == vector) {
431                         isr_table[idx].priority = priority;
432                         isr_table[idx].type = polarity;
433                         platform_interrupt_enable(vector, polarity, priority);
434                         break;
435                 }
436         }
438         env_restore_interrupts();
441 /**
442  * env_disable_interrupt
443  *
444  * Disables the given interrupt
445  *
446  * @param vector   - interrupt vector number
447  */
449 void env_disable_interrupt(unsigned int vector)
451         platform_interrupt_disable(vector);
454 /**
455  * env_map_memory
456  *
457  * Enables memory mapping for given memory region.
458  *
459  * @param pa   - physical address of memory
460  * @param va   - logical address of memory
461  * @param size - memory size
462  * param flags - flags for cache/uncached  and access type
463  */
465 void env_map_memory(unsigned int pa, unsigned int va, unsigned int size,
466                     unsigned int flags)
468         platform_map_mem_region(va, pa, size, flags);
471 /**
472  * env_disable_cache
473  *
474  * Disables system caches.
475  *
476  */
478 void env_disable_cache()
480         platform_cache_all_flush_invalidate();
481         platform_cache_disable();
484 /**
485  * 
486  * env_get_timestamp
487  *
488  * Returns a 64 bit time stamp.
489  *
490  *
491  */
492 unsigned long long env_get_timestamp(void)
495         /* TODO: Provide implementation for baremetal */
496         return 0;
499 /*========================================================= */
500 /* Util data / functions for BM */
502 void bm_env_isr(int vector)
504         int idx;
505         struct isr_info *info;
507         env_disable_interrupt(vector);
508         for (idx = 0; idx < ISR_COUNT; idx++) {
509                 info = &isr_table[idx];
510                 if (info->vector == vector) {
511                         info->isr(info->vector, info->data);
512                         env_enable_interrupt(info->vector, info->priority,
513                                              info->type);
514                         break;
515                 }
516         }
519 /**
520  *
521  * acquire_spin_lock
522  *
523  */
524 static void acquire_spin_lock(void *plock)
526         const int lockVal = 0;
527         volatile unsigned int retVal;
529         do {
530                 retVal = xchg(plock, lockVal);
531         } while (retVal == lockVal);
534 /**
535  * release_spin_lock
536  */
537 static void release_spin_lock(void *plock)
539         MEM_BARRIER();
541         xchg(plock, 1);