]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/rtos/rtx/TARGET_CORTEX_A/RTX_CM_lib.h
Merge commit '1fe4406f374291ab2e86e95a97341fd9c475fcb8'
[qmk_firmware.git] / tmk_core / tool / mbed / mbed-sdk / libraries / rtos / rtx / TARGET_CORTEX_A / RTX_CM_lib.h
1 /*----------------------------------------------------------------------------
2  *      RL-ARM - RTX
3  *----------------------------------------------------------------------------
4  *      Name:    RTX_CM_LIB.H
5  *      Purpose: RTX Kernel System Configuration
6  *      Rev.:    V4.60
7  *----------------------------------------------------------------------------
8  *
9  * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
10  * All rights reserved.
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are met:
13  *  - Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *  - Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *  - Neither the name of ARM  nor the names of its contributors may be used
19  *    to endorse or promote products derived from this software without
20  *    specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *---------------------------------------------------------------------------*/
34
35 #if   defined (__CC_ARM)
36 #pragma O3
37 #define __USED __attribute__((used))
38 #elif defined (__GNUC__)
39 #pragma GCC optimize ("O3")
40 #define __USED __attribute__((used))
41 #elif defined (__ICCARM__)
42 #define __USED __root
43 #endif
44
45
46 /*----------------------------------------------------------------------------
47  *      Definitions
48  *---------------------------------------------------------------------------*/
49
50 #define _declare_box(pool,size,cnt)  uint32_t pool[(((size)+3)/4)*(cnt) + 3]
51 #define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
52
53 #define OS_TCB_SIZE     48
54 #define OS_TMR_SIZE     8
55
56 #if defined (__CC_ARM) && !defined (__MICROLIB)
57
58 typedef void    *OS_ID;
59 typedef uint32_t OS_TID;
60 typedef uint32_t OS_MUT[3];
61 typedef uint32_t OS_RESULT;
62
63 #define runtask_id()    rt_tsk_self()
64 #define mutex_init(m)   rt_mut_init(m)
65 #define mutex_wait(m)   os_mut_wait(m,0xFFFF)
66 #define mutex_rel(m)    os_mut_release(m)
67
68 extern OS_TID    rt_tsk_self    (void);
69 extern void      rt_mut_init    (OS_ID mutex);
70 extern OS_RESULT rt_mut_release (OS_ID mutex);
71 extern OS_RESULT rt_mut_wait    (OS_ID mutex, uint16_t timeout);
72
73 #define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout)
74 #define os_mut_release(mutex)      _os_mut_release((uint32_t)rt_mut_release,mutex)
75
76 OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex)                   __svc_indirect(0);
77 OS_RESULT _os_mut_wait    (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0);
78
79 #endif
80
81
82 /*----------------------------------------------------------------------------
83  *      Global Variables
84  *---------------------------------------------------------------------------*/
85
86 #if (OS_TIMERS != 0)
87 #define OS_TASK_CNT (OS_TASKCNT + 1)
88 #define OS_PRIV_CNT (OS_PRIVCNT + 2)
89 #define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ))
90 #else
91 #define OS_TASK_CNT  OS_TASKCNT
92 #define OS_PRIV_CNT (OS_PRIVCNT + 1)
93 #define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE))
94 #endif
95
96 uint16_t const os_maxtaskrun = OS_TASK_CNT;
97 uint32_t const os_stackinfo  = (OS_STKCHECK<<24)| (OS_PRIV_CNT<<16) | (OS_STKSIZE*4);
98 uint32_t const os_rrobin     = (OS_ROBIN << 16) | OS_ROBINTOUT;
99 uint32_t const os_trv        = OS_TRV;
100 uint8_t  const os_flags      = OS_RUNPRIV;
101
102 /* Export following defines to uVision debugger. */
103 __USED uint32_t const os_clockrate = OS_TICK;
104 __USED uint32_t const os_timernum  = 0;
105
106 /* Memory pool for TCB allocation    */
107 _declare_box  (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT);
108 uint16_t const mp_tcb_size = sizeof(mp_tcb);
109
110 /* Memory pool for System stack allocation (+os_idle_demon). */
111 _declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1);
112 uint32_t const mp_stk_size = sizeof(mp_stk);
113
114 /* Memory pool for user specified stack allocation (+main, +timer) */
115 uint64_t       os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)];
116 uint32_t const os_stack_sz = sizeof(os_stack_mem);
117
118 #ifndef OS_FIFOSZ
119  #define OS_FIFOSZ      16
120 #endif
121
122 /* Fifo Queue buffer for ISR requests.*/
123 uint32_t       os_fifo[OS_FIFOSZ*2+1];
124 uint8_t  const os_fifo_size = OS_FIFOSZ;
125
126 /* An array of Active task pointers. */
127 void *os_active_TCB[OS_TASK_CNT];
128
129 /* User Timers Resources */
130 #if (OS_TIMERS != 0)
131 extern void osTimerThread (void const *argument);
132 #if defined (__MBED_CMSIS_RTOS_CA9)
133 osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ);
134 #else
135 osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ);
136 #endif
137 osThreadId osThreadId_osTimerThread;
138 osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *);
139 osMessageQId osMessageQId_osTimerMessageQ;
140 #else
141 osThreadDef_t os_thread_def_osTimerThread = { NULL };
142 osThreadId osThreadId_osTimerThread;
143 osMessageQDef(osTimerMessageQ, 0, void *);
144 osMessageQId osMessageQId_osTimerMessageQ;
145 #endif
146
147 /* Legacy RTX User Timers not used */
148 uint32_t       os_tmr = 0;
149 uint32_t const *m_tmr = NULL;
150 uint16_t const mp_tmr_size = 0;
151
152 #if defined (__CC_ARM) && !defined (__MICROLIB)
153  /* A memory space for arm standard library. */
154  static uint32_t std_libspace[OS_TASK_CNT][96/4];
155  static OS_MUT   std_libmutex[OS_MUTEXCNT];
156  static uint32_t nr_mutex;
157  extern void  *__libspace_start;
158 #endif
159
160
161 /*----------------------------------------------------------------------------
162  *      RTX Optimizations (empty functions)
163  *---------------------------------------------------------------------------*/
164
165 #if OS_ROBIN == 0
166  void rt_init_robin (void) {;}
167  void rt_chk_robin  (void) {;}
168 #endif
169
170 #if OS_STKCHECK == 0
171  void rt_stk_check  (void) {;}
172 #endif
173
174
175 /*----------------------------------------------------------------------------
176  *      Standard Library multithreading interface
177  *---------------------------------------------------------------------------*/
178
179 #if defined (__CC_ARM) && !defined (__MICROLIB)
180
181 /*--------------------------- __user_perthread_libspace ---------------------*/
182
183 void *__user_perthread_libspace (void) {
184   /* Provide a separate libspace for each task. */
185   uint32_t idx;
186
187   idx = runtask_id ();
188   if (idx == 0) {
189     /* RTX not running yet. */
190     return (&__libspace_start);
191   }
192   return ((void *)&std_libspace[idx-1]);
193 }
194
195 /*--------------------------- _mutex_initialize -----------------------------*/
196
197 int _mutex_initialize (OS_ID *mutex) {
198   /* Allocate and initialize a system mutex. */
199
200   if (nr_mutex >= OS_MUTEXCNT) {
201     /* If you are here, you need to increase the number OS_MUTEXCNT. */
202     for (;;);
203   }
204   *mutex = &std_libmutex[nr_mutex++];
205   mutex_init (*mutex);
206   return (1);
207 }
208
209
210 /*--------------------------- _mutex_acquire --------------------------------*/
211
212 __attribute__((used)) void _mutex_acquire (OS_ID *mutex) {
213   /* Acquire a system mutex, lock stdlib resources. */
214   if (runtask_id ()) {
215     /* RTX running, acquire a mutex. */
216     mutex_wait (*mutex);
217   }
218 }
219
220
221 /*--------------------------- _mutex_release --------------------------------*/
222
223 __attribute__((used)) void _mutex_release (OS_ID *mutex) {
224   /* Release a system mutex, unlock stdlib resources. */
225   if (runtask_id ()) {
226     /* RTX running, release a mutex. */
227     mutex_rel (*mutex);
228   }
229 }
230
231 #endif
232
233
234 /*----------------------------------------------------------------------------
235  *      RTX Startup
236  *---------------------------------------------------------------------------*/
237
238 /* Main Thread definition */
239 extern int main (void);
240 osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE };
241
242
243 #if defined (__CC_ARM)
244
245 #ifdef __MICROLIB
246 void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF")));
247 #if __TARGET_ARCH_ARM
248 #pragma push
249 #pragma arm
250 #endif
251 void _main_init (void) {
252   osKernelInitialize();
253   osThreadCreate(&os_thread_def_main, NULL);
254   osKernelStart();
255   for (;;);
256 }
257 #if __TARGET_ARCH_ARM
258 #pragma pop
259 #endif
260 #else
261 __asm void __rt_entry (void) {
262
263   IMPORT  __user_setup_stackheap
264   IMPORT  __rt_lib_init
265   IMPORT  os_thread_def_main
266   IMPORT  osKernelInitialize
267   IMPORT  osKernelStart
268   IMPORT  osThreadCreate
269   IMPORT  exit
270
271   BL      __user_setup_stackheap
272   MOV     R1,R2
273   BL      __rt_lib_init
274   BL      osKernelInitialize
275   LDR     R0,=os_thread_def_main
276   MOVS    R1,#0
277   BL      osThreadCreate
278   BL      osKernelStart
279   BL      exit
280
281   ALIGN
282 }
283 #endif
284
285 #elif defined (__GNUC__)
286
287 #ifdef __CS3__
288
289 /* CS3 start_c routine.
290  *
291  * Copyright (c) 2006, 2007 CodeSourcery Inc
292  *
293  * The authors hereby grant permission to use, copy, modify, distribute,
294  * and license this software and its documentation for any purpose, provided
295  * that existing copyright notices are retained in all copies and that this
296  * notice is included verbatim in any distributions. No written agreement,
297  * license, or royalty fee is required for any of the authorized uses.
298  * Modifications to this software may be copyrighted by their authors
299  * and need not follow the licensing terms described here, provided that
300  * the new terms are clearly indicated on the first page of each file where
301  * they apply.
302  */
303
304 #include "cs3.h"
305
306 extern void __libc_init_array (void);
307
308 __attribute ((noreturn)) void __cs3_start_c (void){
309   unsigned regions = __cs3_region_num;
310   const struct __cs3_region *rptr = __cs3_regions;
311
312   /* Initialize memory */
313   for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) {
314     long long *src = (long long *)rptr->init;
315     long long *dst = (long long *)rptr->data;
316     unsigned limit = rptr->init_size;
317     unsigned count;
318
319     if (src != dst)
320       for (count = 0; count != limit; count += sizeof (long long))
321         *dst++ = *src++;
322     else
323       dst = (long long *)((char *)dst + limit);
324     limit = rptr->zero_size;
325     for (count = 0; count != limit; count += sizeof (long long))
326       *dst++ = 0;
327   }
328
329   /* Run initializers.  */
330   __libc_init_array ();
331
332   osKernelInitialize();
333   osThreadCreate(&os_thread_def_main, NULL);
334   osKernelStart();
335   for (;;);
336 }
337
338 #else
339
340 __attribute__((naked)) void software_init_hook (void) {
341   __asm (
342     ".syntax unified\n"
343     ".arm\n"
344     "movs r0,#0\n"
345     "movs r1,#0\n"
346     "mov  r4,r0\n"
347     "mov  r5,r1\n"
348     "ldr  r0,= __libc_fini_array\n"
349     "bl   atexit\n"
350     "bl   __libc_init_array\n"
351     "mov  r0,r4\n"
352     "mov  r1,r5\n"
353     "bl   osKernelInitialize\n"
354     "ldr  r0,=os_thread_def_main\n"
355     "movs r1,#0\n"
356     "bl   osThreadCreate\n"
357     "bl   osKernelStart\n"
358     "bl   exit\n"
359   );
360 }
361
362 #endif
363
364 #elif defined (__ICCARM__)
365
366 extern int  __low_level_init(void);
367 extern void __iar_data_init3(void);
368 extern void exit(int arg);
369
370 __noreturn __stackless void __cmain(void) {
371   int a;
372
373   if (__low_level_init() != 0) {
374     __iar_data_init3();
375   }
376   osKernelInitialize();
377   osThreadCreate(&os_thread_def_main, NULL);
378   a = osKernelStart();
379   exit(a);
380 }
381
382 #endif
383
384
385 /*----------------------------------------------------------------------------
386  * end of file
387  *---------------------------------------------------------------------------*/
388