zynqmp_r5: remove IPI handler
[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         char *name;
64         int shared;
65         void *data;
66         void (*isr)(int vector, void *data);
67 };
68 struct isr_info isr_table[ISR_COUNT];
69 int Intr_Count = 0;
70 /* Flag to show status of global interrupts. 0 for disabled and 1 for enabled. This
71  * is added to prevent recursive global interrupts enablement/disablement.
72  */
73 int Intr_Enable_Flag = 1;
75 /**
76  * env_init
77  *
78  * Initializes OS/BM environment.
79  *
80  */
81 int env_init()
82 {
83         return 0;
84 }
86 /**
87  * env_deinit
88  *
89  * Uninitializes OS/BM environment.
90  *
91  * @returns - execution status
92  */
94 int env_deinit()
95 {
96         return 0;
97 }
99 /**
100  * env_allocate_memory - implementation
101  *
102  * @param size
103  */
104 void *env_allocate_memory(unsigned int size)
106         return (malloc(size));
109 /**
110  * env_free_memory - implementation
111  *
112  * @param ptr
113  */
114 void env_free_memory(void *ptr)
116         if (ptr != NULL) {
117                 free(ptr);
118         }
121 /**
122  *
123  * env_memset - implementation
124  *
125  * @param ptr
126  * @param value
127  * @param size
128  */
129 void env_memset(void *ptr, int value, unsigned long size)
131         memset(ptr, value, size);
134 /**
135  *
136  * env_memcpy - implementation
137  *
138  * @param dst
139  * @param src
140  * @param len
141  */
142 void env_memcpy(void *dst, void const *src, unsigned long len)
144         memcpy(dst, src, len);
147 /**
148  *
149  * env_strcmp - implementation
150  *
151  * @param dst
152  * @param src
153  */
155 int env_strcmp(const char *dst, const char *src)
157         return (strcmp(dst, src));
160 /**
161  *
162  * env_strncpy - implementation
163  *
164  * @param dest
165  * @param src
166  * @param len
167  */
168 void env_strncpy(char *dest, const char *src, unsigned long len)
170         strncpy(dest, src, len);
173 /**
174  *
175  * env_strncmp - implementation
176  *
177  * @param dest
178  * @param src
179  * @param len
180  */
181 int env_strncmp(char *dest, const char *src, unsigned long len)
183         return (strncmp(dest, src, len));
186 /**
187  *
188  * env_mb - implementation
189  *
190  */
191 void env_mb()
193         MEM_BARRIER();
196 /**
197  * osalr_mb - implementation
198  */
199 void env_rmb()
201         MEM_BARRIER();
204 /**
205  * env_wmb - implementation
206  */
207 void env_wmb()
209         MEM_BARRIER();
212 /**
213  * env_map_vatopa - implementation
214  *
215  * @param address
216  */
217 unsigned long env_map_vatopa(void *address)
219         return platform_vatopa(address);
222 /**
223  * env_map_patova - implementation
224  *
225  * @param address
226  */
227 void *env_map_patova(unsigned long address)
229         return platform_patova(address);
232 /**
233  * env_create_mutex
234  *
235  * Creates a mutex with the given initial count.
236  *
237  */
238 int env_create_mutex(void **lock, int count)
240         return 0;
243 /**
244  * env_delete_mutex
245  *
246  * Deletes the given lock
247  *
248  */
249 void env_delete_mutex(void *lock)
253 /**
254  * env_lock_mutex
255  *
256  * Tries to acquire the lock, if lock is not available then call to
257  * this function will suspend.
258  */
259 void env_lock_mutex(void *lock)
261         env_disable_interrupts();
264 /**
265  * env_unlock_mutex
266  *
267  * Releases the given lock.
268  */
270 void env_unlock_mutex(void *lock)
272         env_restore_interrupts();
275 /**
276  * env_create_sync_lock
277  *
278  * Creates a synchronization lock primitive. It is used
279  * when signal has to be sent from the interrupt context to main
280  * thread context.
281  */
282 int env_create_sync_lock(void **lock, int state)
284         int *slock;
286         slock = (int *)malloc(sizeof(int));
287         if (slock) {
288                 *slock = state;
289                 *lock = slock;
290         } else {
291                 *lock = NULL;
292                 return -1;
293         }
295         return 0;
298 /**
299  * env_delete_sync_lock
300  *
301  * Deletes the given lock
302  *
303  */
304 void env_delete_sync_lock(void *lock)
306         if (lock)
307                 free(lock);
310 /**
311  * env_acquire_sync_lock
312  *
313  * Tries to acquire the lock, if lock is not available then call to
314  * this function waits for lock to become available.
315  */
316 void env_acquire_sync_lock(void *lock)
318         acquire_spin_lock(lock);
321 /**
322  * env_release_sync_lock
323  *
324  * Releases the given lock.
325  */
327 void env_release_sync_lock(void *lock)
329         release_spin_lock(lock);
332 /**
333  * env_sleep_msec
334  *
335  * Suspends the calling thread for given time , in msecs.
336  */
338 void env_sleep_msec(int num_msec)
343 /**
344  * env_disable_interrupts
345  *
346  * Disables system interrupts
347  *
348  */
349 void env_disable_interrupts()
351         if (Intr_Enable_Flag == 1) {
352                 disable_global_interrupts();
353                 Intr_Enable_Flag = 0;
354         }
357 /**
358  * env_restore_interrupts
359  *
360  * Enables system interrupts
361  *
362  */
363 void env_restore_interrupts()
365         if (Intr_Enable_Flag == 0) {
366                 restore_global_interrupts();
367                 Intr_Enable_Flag = 1;
368         }
371 /**
372  * env_register_isr_shared
373  *
374  * Registers interrupt handler for the given interrupt vector.
375  *
376  * @param vector - interrupt vector number
377  * @param isr    - interrupt handler
378  * @param name   - interrupt name
379  * @param shared - if the interrupt is shared or not
380  */
381 void env_register_isr_shared(int vector, void *data,
382                       void (*isr) (int vector, void *data),
383                       char *name,
384                       int shared)
386         env_disable_interrupts();
388         if (Intr_Count < ISR_COUNT) {
389                 /* Save interrupt data */
390                 isr_table[Intr_Count].vector = vector;
391                 isr_table[Intr_Count].data = data;
392                 isr_table[Intr_Count].name = name;
393                 isr_table[Intr_Count].shared = shared;
394                 isr_table[Intr_Count++].isr = isr;
395         }
397         env_restore_interrupts();
399 /**
400  * env_register_isr
401  *
402  * Registers interrupt handler for the given interrupt vector.
403  *
404  * @param vector - interrupt vector number
405  * @param isr    - interrupt handler
406  */
407 void env_register_isr(int vector, void *data,
408                       void (*isr) (int vector, void *data))
410         env_register_isr_shared(vector, data, isr, 0, 0);
413 void env_update_isr(int vector, void *data,
414                     void (*isr) (int vector, void *data),
415                     char *name,
416                     int shared)
418         int idx;
419         struct isr_info *info;
421         env_disable_interrupts();
423         for (idx = 0; idx < ISR_COUNT; idx++) {
424                 info = &isr_table[idx];
425                 if (info->vector == vector) {
426                         if (name && strcmp(info->name, name)) {
427                                 continue;
428                         }
429                         info->data = data;
430                         info->isr = isr;
431                         info->shared = shared;
432                         break;
433                 }
434         }
436         env_restore_interrupts();
439 /**
440  * env_enable_interrupt
441  *
442  * Enables the given interrupt
443  *
444  * @param vector   - interrupt vector number
445  * @param priority - interrupt priority
446  * @param polarity - interrupt polarity
447  */
449 void env_enable_interrupt(unsigned int vector, unsigned int priority,
450                           unsigned int polarity)
452         int idx;
454         env_disable_interrupts();
456         for (idx = 0; idx < ISR_COUNT; idx++) {
457                 if (isr_table[idx].vector == vector) {
458                         isr_table[idx].priority = priority;
459                         isr_table[idx].type = polarity;
460                         platform_interrupt_enable(vector, polarity, priority);
461                         break;
462                 }
463         }
465         env_restore_interrupts();
468 /**
469  * env_disable_interrupt
470  *
471  * Disables the given interrupt
472  *
473  * @param vector   - interrupt vector number
474  */
476 void env_disable_interrupt(unsigned int vector)
478         platform_interrupt_disable(vector);
481 /**
482  * env_map_memory
483  *
484  * Enables memory mapping for given memory region.
485  *
486  * @param pa   - physical address of memory
487  * @param va   - logical address of memory
488  * @param size - memory size
489  * param flags - flags for cache/uncached  and access type
490  */
492 void env_map_memory(unsigned int pa, unsigned int va, unsigned int size,
493                     unsigned int flags)
495         platform_map_mem_region(va, pa, size, flags);
498 /**
499  * env_disable_cache
500  *
501  * Disables system caches.
502  *
503  */
505 void env_disable_cache()
507         platform_cache_all_flush_invalidate();
508         platform_cache_disable();
511 /**
512  * 
513  * env_get_timestamp
514  *
515  * Returns a 64 bit time stamp.
516  *
517  *
518  */
519 unsigned long long env_get_timestamp(void)
522         /* TODO: Provide implementation for baremetal */
523         return 0;
526 /*========================================================= */
527 /* Util data / functions for BM */
529 void bm_env_isr(int vector)
531         int idx;
532         struct isr_info *info;
534         env_disable_interrupt(vector);
535         for (idx = 0; idx < ISR_COUNT; idx++) {
536                 info = &isr_table[idx];
537                 if (info->vector == vector) {
538                         info->isr(info->vector, info->data);
539                         env_enable_interrupt(info->vector, info->priority,
540                                              info->type);
541                         if (!info->shared)
542                                 break;
543                 }
544         }
547 /**
548  *
549  * acquire_spin_lock
550  *
551  */
552 static void acquire_spin_lock(void *plock)
554         const int lockVal = 0;
555         volatile unsigned int retVal;
557         do {
558                 retVal = xchg(plock, lockVal);
559         } while (retVal == lockVal);
562 /**
563  * release_spin_lock
564  */
565 static void release_spin_lock(void *plock)
567         MEM_BARRIER();
569         xchg(plock, 1);