xref: /utopia/UTPA2-700.0.x/modules/msos/msos/linux_kernel_V2/MsOS_linux_kernel.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file    MsOS.c
98 /// @brief  MStar OS Wrapper
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101 
102 
103 #if defined(MSOS_TYPE_LINUX_KERNEL)
104 
105 #define _GNU_SOURCE
106 
107 #include <linux/mutex.h>
108 #include <linux/sched.h>
109 #include <linux/slab.h>
110 
111 #include <linux/spinlock.h>
112 #include <linux/kthread.h>
113 #include <linux/delay.h>
114 #include <linux/interrupt.h>
115 #include <linux/jiffies.h>
116 #include <linux/wait.h>
117 #include <linux/types.h>
118 #include <linux/semaphore.h>
119 #include <linux/hrtimer.h>
120 #include <chip_setup.h>
121 //-------------------------------------------------------------------------------------------------
122 // Include Files
123 //-------------------------------------------------------------------------------------------------
124 #include "MsCommon.h"
125 #include "halCHIP.h"
126 #include "halMMIO.h"
127 #include "MsVersion.h"
128 #include "mem.h"
129 
130 //-------------------------------------------------------------------------------------------------
131 // Local Defines
132 //------------------------------------------------------------------------------------------------
133 
134 //-------------------------------------------------------------------------------------------------
135 // Macros
136 //-------------------------------------------------------------------------------------------------
137 #define HAS_FLAG(flag, bit)        ((flag) & (bit))
138 #define SET_FLAG(flag, bit)        ((flag)|= (bit))
139 #define RESET_FLAG(flag, bit)      ((flag)&= (~(bit)))
140 
141 #if 0
142 #define _TimeAbs(stTime, u32IntMs)                                                              \
143 {                                                                                               \
144     clock_gettime(CLOCK_REALTIME, &(stTime));                                                   \
145     if(u32IntMs>0)                                                                              \
146     {                                                                                           \
147         MS_U32                         u32Sec=u32Sec=(u32IntMs)/1000;                           \
148         (stTime).tv_sec+=           u32Sec;                                                     \
149         (stTime).tv_nsec+=          ((u32IntMs)- (1000* u32Sec))* 1000000;                      \
150         if ((stTime).tv_nsec>= 1000000000)                                                      \
151         {                                                                                       \
152             (stTime).tv_sec++;                                                                  \
153             (stTime).tv_nsec-=      1000000000;                                                 \
154         }                                                                                       \
155     }                                                                                           \
156 }
157 #endif
158 
159 #define PTH_RET_CHK(_pf_) _pf_
160 
161 //-------------------------------------------------------------------------------------------------
162 // Global Variables
163 //-------------------------------------------------------------------------------------------------
164 
165 //-------------------------------------------------------------------------------------------------
166 // Local Variables
167 //-------------------------------------------------------------------------------------------------
168 //
169 // Variable-size Memory pool
170 //
171 #if defined(MSOS_TYPE_LINUX_KERNEL)
172 
173 #include "MsTypes.h"
174 #include "MsIRQ.h"
175 #include "MsOS.h"
176 #include "drvIRQ.h"
177 #include "halIRQ.h"
178 #include "utopia.h"
179 
180 // Combine 3-B prefix with s32ID = MSOS_ID_PREFIX | s32Id
181 //  to avoid the kernel object being used before initialzed.
182 #define MSOS_ID_PREFIX              0x76540000
183 #define MSOS_ID_PREFIX_MASK         0xFFFF0000
184 #define MSOS_ID_MASK                0x0000FFFF //~MSOS_ID_PREFIX_MASK
185 
186 #if (defined(CHIP_T3) || \
187      defined(CHIP_T4) || \
188      defined(CHIP_T7) || \
189      defined(CHIP_T12) || \
190      defined(CHIP_A2) || \
191      defined(CHIP_T8) || \
192      defined(CHIP_T9) || \
193      defined(CHIP_U4) || \
194      defined(CHIP_J2) || \
195      defined(CHIP_T13) || \
196      defined(CHIP_A1) || \
197      defined(CHIP_A6) || \
198      defined(CHIP_A7) || \
199      defined(CHIP_A5) || \
200      defined(CHIP_A3) || \
201      defined(CHIP_AMETHYST) || \
202      defined(CHIP_K1) || \
203 	 defined(CHIP_KAISER) || \
204      defined(CHIP_EDISON) || \
205      defined(CHIP_E8) || \
206      defined(CHIP_EAGLE) || \
207      defined(CHIP_EIFFEL) || \
208      defined(CHIP_NIKE) || \
209      defined(CHIP_NADAL) || \
210      defined(CHIP_MADISON) || \
211 	 defined(CHIP_CLIPPERS) || \
212      defined(CHIP_MIAMI)) || \
213 	 defined(CHIP_NAPOLI)
214 #define MIU1_CACHEABLE_START        0xC0000000
215 #define MIU1_CACHEABLE_END          0xD0000000
216 #define MIU1_UNCACHEABLE_START      0xD0000000
217 #define MIU1_UNCACHEABLE_END        0xE0000000
218 #endif
219 
220 #ifndef MIN
221 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
222 #endif // #ifndef MIN
223 
224 #ifndef MS_ASSERT
225 #define MS_ASSERT(_bool_)                                                                                   \
226         {                                                                                                   \
227             if (!(_bool_))                                                                                  \
228             {                                                                                               \
229                 printk("ASSERT FAIL: %s, %s %s %d\n", #_bool_, __FILE__, __PRETTY_FUNCTION__, __LINE__);    \
230                 panic("mstar panic\n");                                                                     \
231             }                                                                                               \
232         }
233 #endif
234 
235 #if 1
236 //
237 // Memory management
238 //
239 #ifdef MSOS_MEMPOOL_MAX
240 #undef MSOS_MEMPOOL_MAX
241 #define MSOS_MEMPOOL_MAX 2
242 #endif // #ifdef MSOS_MEMPOOL_MAX
243 
244 typedef struct
245 {
246     MS_BOOL                         bUsed;
247     cyg_handle_t                    stMemoryPool;
248     cyg_mempool_var                 stMemoryPoolInfo;
249     MS_BOOL bMPool;
250 } MsOS_MemoryPool_Info;
251 
252 static MsOS_MemoryPool_Info     _MsOS_MemoryPool_Info[MSOS_MEMPOOL_MAX];
253 static                          DEFINE_MUTEX(_MsOS_MemoryPool_Mutex);
254 #define MEMORY_MUTEX_LOCK()     mutex_lock(&_MsOS_MemoryPool_Mutex)
255 #define MEMORY_MUTEX_UNLOCK()   mutex_unlock(&_MsOS_MemoryPool_Mutex)
256 #endif
257 
258 //
259 // Task Management
260 //
261 typedef struct
262 {
263     MS_BOOL             bUsed;
264     MS_BOOL             bTerminal;
265     TaskEntry           pTaskEntry;
266     MS_U32              u32TaskEntryData;
267     struct task_struct* pstThreadInfo;
268 } MsOS_Task_Info;
269 
270 static MsOS_Task_Info   _MsOS_Task_Info[MSOS_TASK_MAX];
271 
272 static                          DEFINE_MUTEX(_MsOS_Task_Mutex);
273 #define TASK_MUTEX_LOCK()       mutex_lock(&_MsOS_Task_Mutex)
274 #define TASK_MUTEX_UNLOCK()     mutex_unlock(&_MsOS_Task_Mutex)
275 
276 //
277 // Mutex
278 //
279 typedef struct
280 {
281     MS_BOOL             bUsed;
282     struct mutex        stMutex;
283     MS_U8               u8Name[MAX_MUTEX_NAME_LENGTH];
284 } MsOS_Mutex_Info;
285 
286 static MsOS_Mutex_Info          _MsOS_Mutex_Info[MSOS_MUTEX_MAX];
287 static                          DEFINE_MUTEX(_MsOS_Mutex_Mutex);
288 #define MUTEX_MUTEX_LOCK()      mutex_lock(&_MsOS_Mutex_Mutex)
289 #define MUTEX_MUTEX_UNLOCK()    mutex_unlock(&_MsOS_Mutex_Mutex)
290 
291 
292 //
293 // Semaphore
294 //
295 typedef struct
296 {
297     MS_BOOL                     bUsed;
298     MS_U32                      u32SemaCount;
299     struct semaphore            stSemaphore;
300 } MsOS_Semaphore_Info;
301 
302 static MsOS_Semaphore_Info      _MsOS_Semaphore_Info[MSOS_SEMAPHORE_MAX];
303 static                          DEFINE_SPINLOCK(_MsOS_Semaphore_Mutex);
304 #define SEMA_MUTEX_LOCK(flags)       spin_lock_irqsave(&_MsOS_Semaphore_Mutex, flags)
305 #define SEMA_MUTEX_UNLOCK(flags)     spin_unlock_irqrestore(&_MsOS_Semaphore_Mutex, flags)
306 
307 //
308 // Event Group
309 //
310 typedef struct
311 {
312     MS_BOOL                     bUsed;
313     MS_U32                      u32Waiting;
314     MS_U32                      u32EventGroup;
315     spinlock_t                  stMutexEvent;
316     wait_queue_head_t           stEventWaitQueue;
317     // pthread_cond_t              stSemaphore; // ?????????????
318 } MsOS_EventGroup_Info;
319 
320 static MsOS_EventGroup_Info     _MsOS_EventGroup_Info[MSOS_EVENTGROUP_MAX];
321 static                          DEFINE_SPINLOCK(_MsOS_EventGroup_Mutex);
322 #define EVENT_MUTEX_LOCK(flags)      spin_lock_irqsave(&_MsOS_EventGroup_Mutex,flags)
323 #define EVENT_MUTEX_UNLOCK(flags)    spin_unlock_irqrestore(&_MsOS_EventGroup_Mutex, flags)
324 
325 #if 0
326 //
327 // Queue
328 //
329 typedef struct
330 {
331     MS_BOOL            bUsed;
332     MS_U8*             pu8Head;
333     MS_U8*             pu8Tail;
334     MS_U8*             pu8Write;
335     MS_U8*             pu8Read;
336     pthread_cond_t  SendSem;
337     pthread_mutex_t SendMutex;
338     pthread_cond_t  RecvSem;
339     pthread_mutex_t RecvMutex;
340     MessageType     eMsgType;
341     MS_U32             u32AlignedMsgSize;
342 } MsOS_Queue_Info;
343 
344 static MsOS_Queue_Info  _MsOS_Queue_Info[MSOS_QUEUE_MAX];
345 static pthread_mutex_t  _MsOS_Queue_Mutex;
346 #endif
347 
348 // @FIXME: Leave Timer later
349 //
350 // Timer
351 //
352 typedef struct
353 {
354     MS_BOOL             bUsed;
355     MS_BOOL             bCircle;
356     TimerCb             pTimerCb;
357     struct timer_list   timer;
358     int                 period;
359     int                 first;
360 } MsOS_Timer_Info;
361 static MsOS_Timer_Info  _MsOS_Timer_Info[MSOS_TIMER_MAX];
362 static                          DEFINE_SPINLOCK(_MsOS_Timer_Mutex);
363 #define TIMER_MUTEX_LOCK(flags)      spin_lock_irqsave(&_MsOS_Timer_Mutex, flags)
364 #define TIMER_MUTEX_UNLOCK(flags)    spin_unlock_irqrestore(&_MsOS_Timer_Mutex, flags)
365 #endif
366 
367 //
368 // compatible shm function.
369 //
370 #define MAX_SHM_CLIENT_NUM      320
371 
372 struct SHM_ENTRY {
373     char    name[MAX_CLIENT_NAME_LENGTH+ 1];
374     void*   addr;
375     unsigned int size;
376 };
377 
378 struct SHM_ARRAY {
379 	unsigned int count;
380 	struct SHM_ENTRY shm_entry[MAX_SHM_CLIENT_NUM+1];
381 };
382 
383 struct SHM_ARRAY g_shm_array;
384 
385 static                          DEFINE_MUTEX(_MsOS_SHM_Mutex);
386 #define SHM_MUTEX_LOCK()        mutex_lock(&_MsOS_SHM_Mutex)
387 #define SHM_MUTEX_UNLOCK()      mutex_unlock(&_MsOS_SHM_Mutex)
388 
389 // Intitialization
390 static DEFINE_MUTEX(_MsOS_Init_Mutex);
391 static MS_BOOL g_bMsOSInit = FALSE;
392 
393 //-------------------------------------------------------------------------------------------------
394 // Local Function Prototypes
395 //-------------------------------------------------------------------------------------------------
396 
397 static int _MsOS_LinuxKernelTaskWrapper(void *data);
398 
399 static MSIF_Version _drv_msos_version = {
400     .DDI = { MSOS_DRV_VERSION },
401 };
402 
403 ////////////////////////////////////////////////////////////////////////////////
404 /// @brief \b Function  \b Name: MDrv_MSOS_GetLibVer
405 /// @brief \b Function  \b Description: Show the MSOS driver version
406 /// @param ppVersion    \b Out: Library version string
407 /// @return             \b Result
408 ////////////////////////////////////////////////////////////////////////////////
MDrv_MSOS_GetLibVer(const MSIF_Version ** ppVersion)409 MS_BOOL MDrv_MSOS_GetLibVer(const MSIF_Version **ppVersion)
410 {
411     if (!ppVersion)
412         return FALSE;
413 
414     *ppVersion = &_drv_msos_version;
415     return TRUE;
416 }
417 
418 //-------------------------------------------------------------------------------------------------
419 /// Initialize MsOS
420 /// @return TRUE : succeed
421 /// @return FALSE : fail
422 //-------------------------------------------------------------------------------------------------
MsOS_Init(void)423 MS_BOOL MsOS_Init (void)
424 {
425     MS_U32 u32I;
426     MS_BOOL bRet = FALSE;
427 
428     mutex_lock(&_MsOS_Init_Mutex);
429 
430     if (g_bMsOSInit)
431     {
432         bRet = TRUE;
433         goto ret;
434     }
435 
436     if (FALSE == MsOS_SHM_Init())
437     {
438         printk("[MsOS_Init] MsOS_SHM_Init failed!\n");
439         bRet = FALSE;
440         goto ret;
441     }
442 
443     // Empty all the MsOS structures
444 
445 #if 1
446     //
447     // Memory management
448     //
449     for( u32I=0; u32I<MSOS_MEMPOOL_MAX; u32I++)
450     {
451         _MsOS_MemoryPool_Info[u32I].bUsed = FALSE;
452     }
453 #endif
454 
455     //
456     // Task Management
457     //
458     for( u32I=0; u32I<MSOS_TASK_MAX; u32I++)
459     {
460         _MsOS_Task_Info[u32I].bUsed = FALSE;
461     }
462 
463     //
464     // Mutex
465     //
466     for( u32I=0; u32I<MSOS_MUTEX_MAX; u32I++)
467     {
468         _MsOS_Mutex_Info[u32I].bUsed = FALSE;
469     }
470 
471     //
472     // Semaphore
473     //
474     for( u32I=0; u32I<MSOS_SEMAPHORE_MAX; u32I++)
475     {
476         _MsOS_Semaphore_Info[u32I].bUsed = FALSE;
477     }
478 
479 
480     //
481     // Event Group
482     //
483     for( u32I=0; u32I<MSOS_EVENTGROUP_MAX; u32I++)
484     {
485         _MsOS_EventGroup_Info[u32I].bUsed = FALSE;
486     }
487 
488     //
489     // Queue
490     //
491 /*
492     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Queue_Mutex, &_MsOS_Mutex_Attr));
493     for( u32I=0; u32I<MSOS_QUEUE_MAX; u32I++)
494     {
495         memset(&_MsOS_Queue_Info[u32I].bUsed, 0, sizeof(MsOS_Queue_Info));
496     }
497 */
498 
499     //
500     // Timer
501     //
502     for( u32I=0; u32I<MSOS_TIMER_MAX; u32I++)
503     {
504         _MsOS_Timer_Info[u32I].bUsed = FALSE;
505         _MsOS_Timer_Info[u32I].bCircle = FALSE;
506         _MsOS_Timer_Info[u32I].pTimerCb = NULL;
507         _MsOS_Timer_Info[u32I].period = 0;
508         _MsOS_Timer_Info[u32I].first = 0;
509         memset(&_MsOS_Timer_Info[u32I].timer, 0, sizeof(struct timer_list));
510         //init_timer(&(_MsOS_Timer_Info[u32I].timer));
511     }
512 
513     //
514     // Interrupt
515     //
516     printk("CHIP_InitISR\n");
517     CHIP_InitISR();
518 
519     UtopiaInit();
520 
521     bRet = TRUE;
522     g_bMsOSInit = TRUE;
523 
524 ret:
525     mutex_unlock(&_MsOS_Init_Mutex);
526     return bRet;
527 }
528 #if defined(MSOS_TYPE_LINUX_KERNEL)
529 EXPORT_SYMBOL(MsOS_Init);
530 #endif
531 
532 #if 1
533 //
534 // Memory management
535 //
536 //-------------------------------------------------------------------------------------------------
537 /// Create a variable-size memory pool dynamically
538 /// @param  u32PoolSize         \b IN: pool size in bytes
539 /// @param  u32MinAllocation    \b IN: not used
540 /// @param  pPoolAddr           \b IN: starting address for the memory pool
541 /// @param  eAttribute          \b IN: only E_MSOS_FIFO - suspended in FIFO order
542 /// @param  pPoolName           \b IN: not used
543 /// @return >=0 : assigned memory pool ID
544 /// @return < 0 : fail
545 //-------------------------------------------------------------------------------------------------
MsOS_CreateMemoryPool(MS_U32 u32PoolSize,MS_U32 u32MinAllocation,void * pPoolAddr,MsOSAttribute eAttribute,char * pPoolName)546 MS_S32 MsOS_CreateMemoryPool (MS_U32 u32PoolSize,
547                            MS_U32 u32MinAllocation,
548                            void * pPoolAddr,
549                            MsOSAttribute eAttribute,
550                            char *pPoolName)
551 {
552     MS_S32 s32Id;
553 
554     MEMORY_MUTEX_LOCK();
555     for(s32Id=0;s32Id<MSOS_MEMPOOL_MAX;s32Id++)
556     {
557         if(_MsOS_MemoryPool_Info[s32Id].bUsed == FALSE)
558         {
559             break;
560         }
561     }
562     if(s32Id < MSOS_MEMPOOL_MAX)
563     {
564         _MsOS_MemoryPool_Info[s32Id].bUsed = TRUE;
565     }
566     MEMORY_MUTEX_UNLOCK();
567 
568     if(s32Id >= MSOS_MEMPOOL_MAX)
569     {
570         return -1;
571     }
572 
573     if (pPoolAddr)
574     {
575         _MsOS_MemoryPool_Info[s32Id].bMPool= TRUE;
576         cyg_mempool_var_create( pPoolAddr,
577                                 u32PoolSize,
578                                 &_MsOS_MemoryPool_Info[s32Id].stMemoryPool,
579                                 &_MsOS_MemoryPool_Info[s32Id].stMemoryPoolInfo );
580     }
581     else
582     {
583         _MsOS_MemoryPool_Info[s32Id].bMPool= FALSE;
584     }
585     s32Id |= MSOS_ID_PREFIX;
586     return s32Id;
587 }
588 
589 //-------------------------------------------------------------------------------------------------
590 /// Delete a variable-size memory pool
591 /// @param  s32PoolId   \b IN: pool ID
592 /// @return TRUE : succeed
593 /// @return FALSE : fail
594 //-------------------------------------------------------------------------------------------------
MsOS_DeleteMemoryPool(MS_S32 s32PoolId)595 MS_BOOL MsOS_DeleteMemoryPool (MS_S32 s32PoolId)
596 {
597     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
598     {
599         return FALSE;
600     }
601     else
602     {
603         s32PoolId &= MSOS_ID_MASK;
604     }
605 
606     if ( (s32PoolId >= MSOS_MEMPOOL_MAX) )
607     {
608         if ( s32PoolId == MSOS_MALLOC_ID )
609         {
610             // here ??
611         }
612 
613         printk("Invalid memory pool ID: %td, you must use the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
614         return TRUE;
615 
616     }
617 
618     #if 1
619     if(_MsOS_MemoryPool_Info[s32PoolId].bUsed == FALSE)
620     {
621         printk("ERR: MEMORY POOL WITH MEMORYPOOL_ID: 0x%tX NOT EXIST\n", (ptrdiff_t)s32PoolId);
622         return FALSE;
623     }
624     #endif
625     if (_MsOS_MemoryPool_Info[s32PoolId].bMPool)
626     {
627         cyg_mempool_var_delete(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool);
628     }
629 
630     MEMORY_MUTEX_LOCK();
631     _MsOS_MemoryPool_Info[s32PoolId].bUsed = FALSE;
632     MEMORY_MUTEX_UNLOCK();
633     return TRUE;
634 }
635 
636 //-------------------------------------------------------------------------------------------------
637 /// Get the information of a variable-size memory pool
638 /// @param  s32PoolId   \b IN: memory pool ID
639 /// @param  pPoolAddr   \b OUT: holding the starting address for the memory pool
640 /// @param  pu32PoolSize \b OUT: holding the total size of the memory pool
641 /// @param  pu32FreeSize \b OUT: holding the available free size of the memory pool
642 /// @param  pu32LargestFreeBlockSize  \b OUT: holding the size of the largest free block
643 /// @return TRUE : succeed
644 /// @return FALSE : the pool has not been created
645 //-------------------------------------------------------------------------------------------------
MsOS_InfoMemoryPool(MS_S32 s32PoolId,void ** pPoolAddr,MS_U32 * pu32PoolSize,MS_U32 * pu32FreeSize,MS_U32 * pu32LargestFreeBlockSize)646 MS_BOOL MsOS_InfoMemoryPool (MS_S32 s32PoolId,
647                           void **pPoolAddr,
648                           MS_U32 *pu32PoolSize,
649                           MS_U32 *pu32FreeSize,
650                           MS_U32 *pu32LargestFreeBlockSize)
651 {
652 
653     return FALSE;
654 
655 }
656 
657 //-------------------------------------------------------------------------------------------------
658 /// Allocate a memory block with 16-Byte aligned starting address from the variable-size memory pool
659 /// @param  u32Size     \b IN: request size
660 /// @param  s32PoolId   \b IN: memory pool ID
661 /// @return NULL : not enough available memory
662 /// @return Otherwise : pointer to the allocated memory block
663 //-------------------------------------------------------------------------------------------------
MsOS_AllocateMemory(MS_U32 u32Size,MS_S32 s32PoolId)664 void * MsOS_AllocateMemory (MS_U32 u32Size, MS_S32 s32PoolId)
665 {
666     void  *pAddr;
667 
668     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
669     {
670         return NULL;
671     }
672     else
673     {
674         s32PoolId &= MSOS_ID_MASK;
675     }
676 
677     // Jerry.Tsao: cyg_mempool_var_try_alloc allocates the maximum pool it has when size is zero.
678     if (u32Size == 0)
679     {
680         return NULL;
681     }
682 
683 
684     if ( s32PoolId >= MSOS_MEMPOOL_MAX)
685     {
686 
687         if ( s32PoolId == MSOS_MALLOC_ID )
688         {
689             return malloc(u32Size);
690         }
691 
692         else
693         {
694             printk("ERR: Invalid memory pool ID: %td, you must use the default ID: MSOS_MALLOC_ID ,or the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
695             return NULL;
696         }
697 
698     }
699 
700     if (FALSE== _MsOS_MemoryPool_Info[s32PoolId].bMPool)
701     {
702         return malloc(u32Size);
703     }
704 
705     pAddr = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32Size);
706 
707     //Current eCosPro kernel always allocates 16-B aligned block
708     if (( (MS_VIRT)pAddr & 0xF) || ( (MS_VIRT)pAddr == 0x0))
709     {
710         return NULL;
711     }
712 
713     return ( pAddr );
714 }
715 
716 //-------------------------------------------------------------------------------------------------
717 /// Free a memory block from the variable-size memory pool
718 /// @param  pAddress    \b IN: pointer to previously allocated memory block
719 /// @param  s32PoolId   \b IN: memory pool ID
720 /// @return TRUE : succeed
721 /// @return FALSE : fail
722 //-------------------------------------------------------------------------------------------------
MsOS_FreeMemory(void * pAddress,MS_S32 s32PoolId)723 MS_BOOL MsOS_FreeMemory (void *pAddress, MS_S32 s32PoolId)
724 {
725     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
726     {
727         return FALSE;
728     }
729     else
730     {
731         s32PoolId &= MSOS_ID_MASK;
732     }
733 
734     if (pAddress == NULL)
735     {
736         return FALSE;
737     }
738 
739 
740 
741     if ( s32PoolId >= MSOS_MEMPOOL_MAX )
742     {
743         if ( s32PoolId == MSOS_MALLOC_ID )
744         {
745             free(pAddress);
746             return TRUE;
747         }
748 
749         else
750         {
751             printk("ERR: Invalid memory pool ID: %td, you must use the default ID: MSOS_MALLOC_ID ,or the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
752             return FALSE;
753         }
754 
755     }
756 
757 
758     if (FALSE== _MsOS_MemoryPool_Info[s32PoolId].bMPool)
759     {
760         free(pAddress);
761     }
762     else
763     {
764         cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pAddress);
765     }
766     return TRUE;
767 }
768 
769 #if 0 // Need to reimplement
770 //-------------------------------------------------------------------------------------------------
771 /// Reallocate a block of memory with 4-byte aligned start address from the variable-size memory pool
772 /// @param  pOrgAddress \b IN: points to the beginning of the original memory block
773 /// @param  u32NewSize  \b IN: size of new memory block
774 /// @param  s32PoolId   \b IN: memory pool ID
775 /// @return NULL : not enough available memory to expand the block or u32NewSize == 0 && pOrgAddress != NULL
776 /// @return Otherwise : pointer to the reallocated (and possibly moved) memory block
777 //  @note   reference realloc in malloc.cxx
778 //-------------------------------------------------------------------------------------------------
779 void * MsOS_ReallocateMemory (void *pOrgAddress, MS_U32 u32NewSize, MS_S32 s32PoolId)
780 {
781     void *pNewAddress = NULL;
782     MS_U32 u32OrgSize;
783 
784     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
785     {
786         return NULL;
787     }
788     else
789     {
790         s32PoolId &= MSOS_ID_MASK;
791     }
792 
793     if (FALSE== _MsOS_MemoryPool_Info[s32PoolId].bMPool)
794     {
795         return realloc(pOrgAddress, u32NewSize);
796     }
797 
798     if ( pOrgAddress == NULL)
799     {
800         //malloc
801         pNewAddress = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32NewSize);
802         return pNewAddress;
803     }
804 
805     if ( u32NewSize == 0)
806     {
807         //free
808         cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pOrgAddress);
809         return NULL;
810     }
811 
812     //mvarimpl.inl
813     struct memdq {
814         struct memdq *prev, *next;
815         MS_S32 size;
816     };
817 
818     struct memdq *dq = (struct memdq *) ((MS_U32 )pOrgAddress  - sizeof(struct memdq));
819     u32OrgSize = dq->size - sizeof(struct memdq);   //dq->size was rounded up to 16B-aligned when malloc, so u32OrgSize may be larger than requested
820 
821     //No resize function is implemented, so malloc a new block directly
822     pNewAddress = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32NewSize);
823 
824     if ( pNewAddress != NULL) //move to a new block
825     {
826         if ( u32NewSize < u32OrgSize)
827         {
828             memcpy( pNewAddress, pOrgAddress, u32NewSize );
829         }
830         else
831         {
832             memcpy( pNewAddress, pOrgAddress, u32OrgSize );
833         }
834         cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pOrgAddress);
835 
836     }
837     else //not enough available memory to expand the block to the given size
838     {
839         //the original block is unchanged
840     }
841 
842     return pNewAddress;
843 }
844 #endif
845 #endif
846 
847 //
848 // Task
849 //
850 //-------------------------------------------------------------------------------------------------
851 /// Create a task
852 /// @param  pTaskEntry       \b IN: task entry point
853 /// @param  u32TaskEntryData \b IN: task entry data: a pointer to some static data, or a
854 ///          small integer, or NULL if the task does not require any additional data.
855 /// @param  eTaskPriority    \b IN: task priority
856 /// @param  bAutoStart       \b IN: start immediately or later
857 /// @param  pStackBase       \b IN: task stack
858 /// @param  u32StackSize     \b IN: stack size
859 /// @param  pTaskName        \b IN: task name
860 /// @return >=0 : assigned Task ID
861 /// @return < 0 : fail
862 //-------------------------------------------------------------------------------------------------
MsOS_CreateTask(TaskEntry pTaskEntry,MS_VIRT u32TaskEntryData,TaskPriority eTaskPriority,MS_BOOL bAutoStart,void * pStackEntry,MS_U32 u32StackSize,char * pTaskName)863 MS_S32 MsOS_CreateTask (TaskEntry pTaskEntry,
864                         MS_VIRT u32TaskEntryData,
865                         TaskPriority eTaskPriority,
866                         MS_BOOL bAutoStart,
867                         void * pStackEntry,
868                         MS_U32 u32StackSize,
869                         char *pTaskName)
870 {
871     // @FIXME:
872     //     (1) eTaskPriority: Task priority is ignored here
873     //     (2) pTaskName: is ignored here
874     //     (3) Need mutex to protect critical section
875 
876     MS_S32 s32Id;
877 
878     TASK_MUTEX_LOCK();
879 
880     for( s32Id=0; s32Id<MSOS_TASK_MAX; s32Id++)
881     {
882         if(_MsOS_Task_Info[s32Id].bUsed == FALSE)
883         {
884             break;
885         }
886     }
887     if( s32Id >= MSOS_TASK_MAX)
888     {
889         TASK_MUTEX_UNLOCK();
890         return -1;
891     }
892     _MsOS_Task_Info[s32Id].bUsed = TRUE;
893     _MsOS_Task_Info[s32Id].bTerminal = FALSE;
894     _MsOS_Task_Info[s32Id].pTaskEntry = pTaskEntry;
895     _MsOS_Task_Info[s32Id].u32TaskEntryData = u32TaskEntryData;
896     _MsOS_Task_Info[s32Id].pstThreadInfo = kthread_create(  _MsOS_LinuxKernelTaskWrapper,
897                                                             (void *)&_MsOS_Task_Info[s32Id],
898                                                             pTaskName);
899     if (IS_ERR(_MsOS_Task_Info[s32Id].pstThreadInfo))
900     {
901         _MsOS_Task_Info[s32Id].bUsed = FALSE;
902         _MsOS_Task_Info[s32Id].bTerminal = FALSE;
903         _MsOS_Task_Info[s32Id].pTaskEntry = NULL;
904         _MsOS_Task_Info[s32Id].u32TaskEntryData = 0;
905         _MsOS_Task_Info[s32Id].pstThreadInfo = NULL;
906         TASK_MUTEX_UNLOCK();
907         printk("Utopia2K Task %s Create Fail\n", pTaskName);
908         return -1;
909     }
910     TASK_MUTEX_UNLOCK();
911 
912     if (bAutoStart)
913     {
914         wake_up_process(_MsOS_Task_Info[s32Id].pstThreadInfo);
915     }
916 
917     s32Id |= MSOS_ID_PREFIX;
918 
919     return s32Id;
920 }
921 
_MsOS_LinuxKernelTaskWrapper(void * data)922 static int _MsOS_LinuxKernelTaskWrapper(void *data)
923 {
924     MsOS_Task_Info  *pMsOS_Task_Info = (MsOS_Task_Info *)data;
925     TaskEntry       pTaskEntry = pMsOS_Task_Info->pTaskEntry;
926     MS_U32          TaskEntryData = pMsOS_Task_Info->u32TaskEntryData;
927 
928     pTaskEntry(TaskEntryData, (void *)pMsOS_Task_Info);
929 
930     TASK_MUTEX_LOCK();
931     pMsOS_Task_Info->bTerminal = TRUE;
932     pMsOS_Task_Info->bUsed = FALSE;
933     pMsOS_Task_Info->pTaskEntry = NULL;
934     pMsOS_Task_Info->u32TaskEntryData = 0;
935     TASK_MUTEX_UNLOCK();
936 
937     return 0;
938 }
939 
940 //-------------------------------------------------------------------------------------------------
941 /// Delete a previously created task
942 /// @param  s32TaskId   \b IN: task ID
943 /// @return TRUE : succeed
944 /// @return FALSE : fail
945 //-------------------------------------------------------------------------------------------------
MsOS_DeleteTask(MS_S32 s32TaskId)946 MS_BOOL MsOS_DeleteTask (MS_S32 s32TaskId)
947 {
948     if ( (s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
949     {
950         return FALSE;
951     }
952     else
953     {
954         s32TaskId &= MSOS_ID_MASK;
955     }
956 
957     TASK_MUTEX_LOCK();
958     if (!_MsOS_Task_Info[s32TaskId].bTerminal)
959     {
960         if (_MsOS_Task_Info[s32TaskId].bUsed)
961             printk("%s : Utopia2K does not support to force destroy Task!\n", __func__);
962         TASK_MUTEX_UNLOCK();
963         return FALSE;
964     }
965     //It dose not support force destroy thread function, because it need used kthread_should_stop() in thread loop.
966     //kthread_stop(_MsOS_Task_Info[s32TaskId].pstThreadInfo);
967     TASK_MUTEX_UNLOCK();
968 
969     return TRUE;
970 }
971 
972 //-------------------------------------------------------------------------------------------------
973 /// Yield the execution right to ready tasks with "the same" priority
974 /// @return None
975 //-------------------------------------------------------------------------------------------------
MsOS_YieldTask(void)976 void MsOS_YieldTask (void)
977 {
978     yield();
979 }
980 
981 //-------------------------------------------------------------------------------------------------
982 /// Suspend the calling task for u32Ms milliseconds
983 /// @param  u32Ms  \b IN: delay 1 ~ MSOS_WAIT_FOREVER ms
984 /// @return None
985 /// @note   Not allowed in interrupt context; otherwise, exception will occur.
986 //-------------------------------------------------------------------------------------------------
MsOS_DelayTask(MS_U32 u32Ms)987 void MsOS_DelayTask (MS_U32 u32Ms)
988 {
989     // Refer to Documentation/timers/timers-howto.txt
990     //
991     // SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms):
992     //        * Use usleep_range
993     // SLEEPING FOR LARGER MSECS ( 10ms+ )
994     //        * Use msleep or possibly msleep_interruptible
995     if(u32Ms <= 20)
996     {
997         usleep_range(u32Ms * 1000, u32Ms * 1000);
998     }
999     else
1000     {
1001         msleep_interruptible((unsigned int)u32Ms);
1002     }
1003 }
1004 
1005 //-------------------------------------------------------------------------------------------------
1006 /// Delay for u32Us microseconds
1007 /// @param  u32Us  \b IN: delay 0 ~ 999 us
1008 /// @return None
1009 /// @note   implemented by "busy waiting". Plz call MsOS_DelayTask directly for ms-order delay
1010 //-------------------------------------------------------------------------------------------------
MsOS_DelayTaskUs(MS_U32 u32Us)1011 void MsOS_DelayTaskUs (MS_U32 u32Us)
1012 {
1013     struct timespec TS1, TS2;
1014     getnstimeofday(&TS1);
1015     getnstimeofday(&TS2);
1016 
1017     while((TS2.tv_nsec - TS1.tv_nsec)< (u32Us * 1000UL))
1018     {
1019         getnstimeofday(&TS2);
1020     }
1021 }
1022 
1023 //-------------------------------------------------------------------------------------------------
1024 /// Delay Poll for u32Us microseconds
1025 /// @param  u32Us  \b IN: delay 0 ~ 999 us
1026 /// @return None
1027 /// @note   implemented by "busy waiting". Plz call MsOS_DelayTask directly for ms-order delay
1028 //-------------------------------------------------------------------------------------------------
MsOS_DelayTaskUs_Poll(MS_U32 u32Us)1029 void MsOS_DelayTaskUs_Poll(MS_U32 u32Us)
1030 {
1031     MsOS_DelayTaskUs(u32Us);
1032 }
1033 
1034 //-------------------------------------------------------------------------------------------------
1035 /// Get task status
1036 /// @param  pTaskInfo       \b IN: task information structure pointer
1037 /// @param  peTaskState      \b OUT: ptr to task istate
1038 /// @return TRUE : succeed
1039 /// @return FALSE : invalid process result
1040 /// @note not support
1041 //-------------------------------------------------------------------------------------------------
MsOS_GetTaskStatus(Task_Info * pTaskInfo,TaskStatus * peTaskState)1042 MS_BOOL MsOS_GetTaskStatus (Task_Info* pTaskInfo, TaskStatus *peTaskState)
1043 {
1044 
1045     if ( (pTaskInfo == NULL) || (peTaskState == NULL))
1046     {
1047         return FALSE;
1048     }
1049 
1050     *peTaskState = E_TASK_INVALID_STATE;
1051     /* not support */
1052     return TRUE;
1053 }
1054 
1055 //-------------------------------------------------------------------------------------------------
1056 /// Resume the specified suspended task
1057 /// @param  s32TaskId   \b IN: Task ID
1058 /// @return TRUE : succeed
1059 /// @return FALSE : fail
1060 /// @note   This API is not supported in Linux
1061 //-------------------------------------------------------------------------------------------------
MsOS_ResumeTask(MS_S32 s32TaskId)1062 MS_BOOL MsOS_ResumeTask (MS_S32 s32TaskId)
1063 {
1064     if ( (s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1065     {
1066         return FALSE;
1067     }
1068     else
1069     {
1070         s32TaskId &= MSOS_ID_MASK;
1071     }
1072 
1073     TASK_MUTEX_LOCK();
1074     if (!_MsOS_Task_Info[s32TaskId].bUsed || _MsOS_Task_Info[s32TaskId].bTerminal)
1075     {
1076         TASK_MUTEX_UNLOCK();
1077         return FALSE;
1078     }
1079     TASK_MUTEX_UNLOCK();
1080     wake_up_process(_MsOS_Task_Info[s32TaskId].pstThreadInfo);
1081 
1082     return TRUE;
1083 }
1084 
1085 //-------------------------------------------------------------------------------------------------
1086 /// Suspend the specified task
1087 /// @param  s32TaskId   \b IN: Task ID
1088 /// @return TRUE : succeed
1089 /// @return FALSE : fail
1090 /// @note   This API is not supported in Linux
1091 //-------------------------------------------------------------------------------------------------
MsOS_SuspendTask(MS_S32 s32TaskId)1092 MS_BOOL MsOS_SuspendTask (MS_S32 s32TaskId)
1093 {
1094     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
1095     return FALSE;
1096 }
1097 
1098 //-------------------------------------------------------------------------------------------------
1099 // Get a task information
1100 // @param  s32TaskId       \b IN: task ID
1101 // @param  peTaskPriority  \b OUT: ptr to task priority
1102 // @param  pu32StackSize   \b OUT: ptr to stack size
1103 // @param  pTaskName       \b OUT: ptr to task name
1104 // @return TRUE : succeed
1105 // @return FALSE : the task has not been created
1106 //-------------------------------------------------------------------------------------------------
MsOS_InfoTask(MS_S32 s32TaskId,TaskPriority * peTaskPriority,MS_U32 * pu32StackSize,char * pTaskName)1107 MS_BOOL MsOS_InfoTask (MS_S32 s32TaskId, TaskPriority *peTaskPriority, MS_U32 *pu32StackSize, char *pTaskName)
1108 {
1109     if ( (s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1110     {
1111         return FALSE;
1112     }
1113     else
1114     {
1115         s32TaskId &= MSOS_ID_MASK;
1116     }
1117 
1118     //ToDO
1119     return TRUE;
1120 }
1121 
1122 //-------------------------------------------------------------------------------------------------
1123 /// Get current task ID
1124 /// @return >=0 : current task ID
1125 /// @return <0 : fail
1126 //-------------------------------------------------------------------------------------------------
MsOS_InfoTaskID(void)1127 MS_S32 MsOS_InfoTaskID (void)
1128 {
1129     MS_S32 s32Id;
1130     struct task_struct *self = current;
1131 
1132     TASK_MUTEX_LOCK();
1133     for (s32Id=0; s32Id < MSOS_TASK_MAX; s32Id++)
1134     {
1135         if (self == _MsOS_Task_Info[s32Id].pstThreadInfo)
1136         {
1137             break;
1138         }
1139     }
1140     TASK_MUTEX_UNLOCK();
1141 
1142     if (s32Id < MSOS_TASK_MAX)
1143     {
1144         s32Id |= MSOS_ID_PREFIX;
1145         return s32Id;
1146     }
1147     else
1148     {
1149         return -1;
1150     }
1151 }
1152 
1153 //-------------------------------------------------------------------------------------------------
1154 /// Get thread ID of current thread/process in Linux(Kernel)
1155 /// @return : current thread ID
1156 //-------------------------------------------------------------------------------------------------
MsOS_GetOSThreadID(void)1157 MS_S32 MsOS_GetOSThreadID (void)
1158 {
1159     return MsOS_InfoTaskID();
1160 }
1161 
1162 //
1163 // Mutex
1164 //
1165 //-------------------------------------------------------------------------------------------------
1166 /// Create a mutex in the unlocked state
1167 /// @param  eAttribute  \b IN: E_MSOS_FIFO: suspended in FIFO order
1168 /// @param  pMutexName  \b IN: mutex name
1169 /// @param  u32Flag  \b IN: process data shared flag
1170 /// @return >=0 : assigned mutex Id
1171 /// @return <0 : fail
1172 /// @note   A mutex has the concept of an owner, whereas a semaphore does not.
1173 ///         A mutex provides priority inheritance protocol against proiorty inversion, whereas a binary semaphore does not.
1174 //-------------------------------------------------------------------------------------------------
MsOS_CreateMutex(MsOSAttribute eAttribute,char * pMutexName1,MS_U32 u32Flag)1175 MS_S32 MsOS_CreateMutex ( MsOSAttribute eAttribute, char *pMutexName1, MS_U32 u32Flag)
1176 {
1177     MS_S32 s32Id, s32LstUnused = MSOS_MUTEX_MAX;
1178     MS_U8 pMutexName[MAX_MUTEX_NAME_LENGTH];
1179     MS_U32 u32MaxLen;
1180 
1181     if (NULL == pMutexName1)
1182     {
1183         return -1;
1184     }
1185     if (strlen(pMutexName1) >= (MAX_MUTEX_NAME_LENGTH-1))
1186     {
1187         printk("%s: Warning strlen(%s) is longer than MAX_MUTEX_NAME_LENGTH(%d). Oversize char will be discard.\n",
1188         __FUNCTION__,pMutexName1,MAX_MUTEX_NAME_LENGTH);
1189     }
1190     if (0 == (u32MaxLen = MIN(strlen(pMutexName1), (MAX_MUTEX_NAME_LENGTH-1))))
1191     {
1192         return -1;
1193     }
1194     strncpy((char*)pMutexName, (const char*)pMutexName1, u32MaxLen);
1195     pMutexName[u32MaxLen] = '\0';
1196 
1197     MUTEX_MUTEX_LOCK();
1198     for(s32Id=0;s32Id<MSOS_MUTEX_MAX;s32Id++)
1199     {
1200         // if (PTHREAD_PROCESS_SHARED == s32Prop) // @FIXME: Richard: is the mutex name always used as an id, regardless of process shared/private property?
1201         {
1202             if(TRUE == _MsOS_Mutex_Info[s32Id].bUsed)
1203             {
1204                 if (0== strcmp((const char*)_MsOS_Mutex_Info[s32Id].u8Name, (const char*)pMutexName))
1205                 {
1206                     break;
1207                 }
1208             }
1209         }
1210         if (FALSE==_MsOS_Mutex_Info[s32Id].bUsed && MSOS_MUTEX_MAX==s32LstUnused)
1211         {
1212             s32LstUnused = s32Id;
1213         }
1214     }
1215     if ((MSOS_MUTEX_MAX==s32Id) && (MSOS_MUTEX_MAX>s32LstUnused))
1216     {
1217         _MsOS_Mutex_Info[s32LstUnused].bUsed = TRUE;
1218         strcpy((char*)_MsOS_Mutex_Info[s32LstUnused].u8Name, (const char*)pMutexName);
1219         mutex_init(&_MsOS_Mutex_Info[s32LstUnused].stMutex);
1220         s32Id = s32LstUnused;
1221     }
1222     MUTEX_MUTEX_UNLOCK();
1223 
1224     if(MSOS_MUTEX_MAX <= s32Id)
1225     {
1226         return -1;
1227     }
1228 
1229     s32Id |= MSOS_ID_PREFIX;
1230 
1231     return s32Id;
1232 }
1233 
1234 //-------------------------------------------------------------------------------------------------
1235 /// Delete the specified mutex
1236 /// @param  s32MutexId  \b IN: mutex ID
1237 /// @return TRUE : succeed
1238 /// @return FALSE : fail
1239 /// @note   It is important that the mutex be in the unlocked state when it is
1240 ///            destroyed, or else the behavior is undefined.
1241 //-------------------------------------------------------------------------------------------------
MsOS_DeleteMutex(MS_S32 s32MutexId)1242 MS_BOOL MsOS_DeleteMutex (MS_S32 s32MutexId)
1243 {
1244     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1245     {
1246         return FALSE;
1247     }
1248     else
1249     {
1250         s32MutexId &= MSOS_ID_MASK;
1251     }
1252 
1253     MUTEX_MUTEX_LOCK();
1254 
1255     //MS_ASSERT(_MsOS_Mutex_Info[s32MutexId].bUsed);
1256     if (!_MsOS_Mutex_Info[s32MutexId].bUsed)
1257     {
1258         MUTEX_MUTEX_UNLOCK();
1259         return FALSE;
1260     }
1261 
1262     /**
1263      * mutex_is_locked - is the mutex locked
1264      * @lock: the mutex to be queried
1265      *
1266      * Returns 1 if the mutex is locked, 0 if unlocked.
1267      */
1268     if (TRUE == mutex_is_locked(&_MsOS_Mutex_Info[s32MutexId].stMutex))
1269     {
1270         MUTEX_MUTEX_UNLOCK();
1271         printk("[Utopia2K] %s : Still locked mutex can not be deleted.\n", __func__);
1272         return FALSE;
1273     }
1274 
1275     _MsOS_Mutex_Info[s32MutexId].bUsed = FALSE;
1276     _MsOS_Mutex_Info[s32MutexId].u8Name[0] = '\0';
1277 
1278     MUTEX_MUTEX_UNLOCK();
1279     return TRUE;
1280 }
1281 
1282 //-------------------------------------------------------------------------------------------------
1283 /// Attempt to lock a mutex
1284 /// @param  s32MutexId  \b IN: mutex ID
1285 /// @param  u32WaitMs   \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the mutex is locked
1286 /// @return TRUE : succeed
1287 /// @return FALSE : fail
1288 //-------------------------------------------------------------------------------------------------
1289 // @FIXME: don't support time-out at this stage
MsOS_ObtainMutex(MS_S32 s32MutexId,MS_U32 u32WaitMs)1290 MS_BOOL MsOS_ObtainMutex (MS_S32 s32MutexId, MS_U32 u32WaitMs)
1291 {
1292     MS_BOOL bRet = FALSE;
1293 
1294     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1295     {
1296         return FALSE;
1297     }
1298     else
1299     {
1300         s32MutexId &= MSOS_ID_MASK;
1301     }
1302 
1303     MUTEX_MUTEX_LOCK();
1304     if (!_MsOS_Mutex_Info[s32MutexId].bUsed)
1305     {
1306         MUTEX_MUTEX_UNLOCK();
1307         return FALSE;
1308     }
1309     MUTEX_MUTEX_UNLOCK();
1310 
1311     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
1312     {
1313         mutex_lock(&_MsOS_Mutex_Info[s32MutexId].stMutex);
1314         bRet = TRUE;
1315     }
1316     else if (u32WaitMs==0) //non-blocking
1317     {
1318         if (!mutex_trylock(&_MsOS_Mutex_Info[s32MutexId].stMutex))
1319         {
1320             bRet = TRUE;
1321         }
1322     }
1323     else //blocking wait with timeout
1324     {
1325         //printk("[%s][%d] %s doesn't support mutex timeout at this stage\n", __FUNCTION__, __LINE__, __FUNCTION__);
1326         mutex_lock(&_MsOS_Mutex_Info[s32MutexId].stMutex);
1327         bRet = TRUE;
1328     }
1329     return bRet;
1330 }
1331 
1332 //-------------------------------------------------------------------------------------------------
1333 /// Attempt to unlock a mutex
1334 /// @param  s32MutexId  \b IN: mutex ID
1335 /// @return TRUE : succeed
1336 /// @return FALSE : fail
1337 /// @note   Only the owner thread of the mutex can unlock it.
1338 //-------------------------------------------------------------------------------------------------
MsOS_ReleaseMutex(MS_S32 s32MutexId)1339 MS_BOOL MsOS_ReleaseMutex (MS_S32 s32MutexId)
1340 {
1341     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1342     {
1343         return FALSE;
1344     }
1345     else
1346     {
1347         s32MutexId &= MSOS_ID_MASK;
1348     }
1349 
1350     MUTEX_MUTEX_LOCK();
1351     if (!_MsOS_Mutex_Info[s32MutexId].bUsed)
1352     {
1353         MUTEX_MUTEX_UNLOCK();
1354         return FALSE;
1355     }
1356     MUTEX_MUTEX_UNLOCK();
1357 
1358     mutex_unlock(&_MsOS_Mutex_Info[s32MutexId].stMutex);
1359 
1360     return TRUE;
1361 }
1362 
1363 //-------------------------------------------------------------------------------------------------
1364 /// Attempt to unlock a mutex by another thread
1365 /// @param  s32MutexId  \b IN: mutex ID
1366 /// @param  bEnable     \b IN: True(Enable) or False(Disable)
1367 /// @return TRUE : succeed
1368 /// @return FALSE : fail
1369 /// @note   Let another thread can unlock it.
1370 //-------------------------------------------------------------------------------------------------
MsOS_EnableCrossThreadReleaseMutex(MS_S32 s32MutexId,MS_BOOL bEnable)1371 MS_BOOL MsOS_EnableCrossThreadReleaseMutex (MS_S32 s32MutexId, MS_BOOL bEnable)
1372 {
1373     // NOT SUPPORT IN UTPA KDRV
1374     return FALSE;
1375 }
1376 
1377 //-------------------------------------------------------------------------------------------------
1378 // Get a mutex informaton
1379 // @param  s32MutexId  \b IN: mutex ID
1380 // @param  peAttribute \b OUT: ptr to suspended mode: E_MSOS_FIFO / E_MSOS_PRIORITY
1381 // @param  pMutexName  \b OUT: ptr to mutex name
1382 // @return TRUE : succeed
1383 // @return FALSE : the mutex has not been created.
1384 //-------------------------------------------------------------------------------------------------
MsOS_InfoMutex(MS_S32 s32MutexId,MsOSAttribute * peAttribute,char * pMutexName)1385 MS_BOOL MsOS_InfoMutex (MS_S32 s32MutexId, MsOSAttribute *peAttribute, char *pMutexName)
1386 {
1387     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1388     {
1389         return FALSE;
1390     }
1391     else
1392     {
1393         s32MutexId &= MSOS_ID_MASK;
1394     }
1395 
1396     if(_MsOS_Mutex_Info[s32MutexId].bUsed == TRUE)
1397     {
1398         //ToDo: extend _MsOS_Mutex_Info structure ?
1399         *peAttribute = E_MSOS_FIFO; //only FIFO for eCos
1400         // @FIXME: linux porting
1401         // UTL_strcpy(pMutexName, "ABC");
1402         strcpy(pMutexName, (const char*)_MsOS_Mutex_Info[s32MutexId].u8Name);
1403         return TRUE;
1404     }
1405     else
1406     {
1407         return FALSE;
1408     }
1409 }
1410 
1411 //
1412 // Semaphore
1413 //
1414 //-------------------------------------------------------------------------------------------------
1415 /// Create a semaphore
1416 /// @param  u32InitCnt \b IN: initial semaphore value
1417 /// @param  eAttribute \b IN: E_MSOS_FIFO suspended in FIFO order
1418 /// @param  pSemaphoreName \b IN: semaphore name
1419 /// @return >=0 : assigned Semaphore Id
1420 /// @return <0 : fail
1421 /// @note   A semaphore does not have the concept of an owner; it is possible for one thread to lock a
1422 ///           binary semaphore and another thread to unlock it.
1423 //-------------------------------------------------------------------------------------------------
MsOS_CreateSemaphore(MS_U32 u32InitCnt,MsOSAttribute eAttribute,char * pSemaphoreName)1424 MS_S32 MsOS_CreateSemaphore (MS_U32 u32InitCnt,
1425                           MsOSAttribute eAttribute,
1426                           char *pSemaphoreName)
1427 {
1428     MS_S32 s32Id;
1429     unsigned long flags;
1430 
1431     //PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Semaphore_Mutex));
1432     SEMA_MUTEX_LOCK(flags);
1433     for(s32Id=0;s32Id<MSOS_SEMAPHORE_MAX;s32Id++)
1434     {
1435         if(_MsOS_Semaphore_Info[s32Id].bUsed == FALSE)
1436         {
1437             break;
1438         }
1439     }
1440 
1441     if(s32Id < MSOS_SEMAPHORE_MAX)
1442     {
1443         _MsOS_Semaphore_Info[s32Id].bUsed = TRUE;
1444     }
1445 
1446     if(s32Id >= MSOS_SEMAPHORE_MAX)
1447     {
1448         SEMA_MUTEX_UNLOCK(flags);
1449         return -1;
1450     }
1451 
1452     sema_init(&_MsOS_Semaphore_Info[s32Id].stSemaphore, u32InitCnt);
1453     _MsOS_Semaphore_Info[s32Id].u32SemaCount = u32InitCnt;
1454     s32Id |= MSOS_ID_PREFIX;
1455 
1456     SEMA_MUTEX_UNLOCK(flags);
1457 
1458     return s32Id;
1459 }
1460 
1461 //-------------------------------------------------------------------------------------------------
1462 /// Delete the specified semaphore
1463 /// @param  s32SemaphoreId  \b IN: semaphore ID
1464 /// @return TRUE : succeed
1465 /// @return FALSE : fail
1466 /// @note   It is important that there are not any threads waiting on the semaphore
1467 ///             when this function is called or the behavior is undefined.
1468 //-------------------------------------------------------------------------------------------------
MsOS_DeleteSemaphore(MS_S32 s32SemaphoreId)1469 MS_BOOL MsOS_DeleteSemaphore (MS_S32 s32SemaphoreId)
1470 {
1471     MS_S32  s32Count=0;
1472     MS_BOOL bResult, bLockAll=TRUE;
1473     unsigned long flags;
1474 
1475     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1476     {
1477         return FALSE;
1478     }
1479     else
1480     {
1481         s32SemaphoreId &= MSOS_ID_MASK;
1482     }
1483 
1484     SEMA_MUTEX_LOCK(flags);
1485 
1486     if (!_MsOS_Semaphore_Info[s32SemaphoreId].bUsed)
1487     {
1488         SEMA_MUTEX_UNLOCK(flags);
1489         return FALSE;
1490     }
1491 
1492     for(s32Count=0;s32Count<_MsOS_Semaphore_Info[s32SemaphoreId].u32SemaCount;s32Count++)
1493     {
1494         /**
1495          * down_trylock - try to acquire the semaphore, without waiting
1496          * @sem: the semaphore to be acquired
1497          *
1498          * Try to acquire the semaphore atomically.  Returns 0 if the mutex has
1499          * been acquired successfully or 1 if it it cannot be acquired.
1500          */
1501         bResult = down_trylock(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore);
1502         if (bResult!=0)
1503         {
1504             bLockAll = FALSE;
1505             break;
1506         }
1507     }
1508 
1509     for(;s32Count>0;s32Count--)
1510         up(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore);
1511 
1512     if (!bLockAll)
1513     {
1514         printk("[%s][%d] Semaphore Delete FAIL!\n", __FUNCTION__, __LINE__);
1515         SEMA_MUTEX_UNLOCK(flags);
1516         return FALSE;
1517     }
1518 
1519     _MsOS_Semaphore_Info[s32SemaphoreId].bUsed = FALSE;
1520     _MsOS_Semaphore_Info[s32SemaphoreId].u32SemaCount = 0;
1521 
1522     SEMA_MUTEX_UNLOCK(flags);
1523     return TRUE;
1524 }
1525 
1526 //-------------------------------------------------------------------------------------------------
1527 /// Attempt to decrement a semaphore count
1528 /// @param  s32SemaphoreId  \b IN: semaphore ID
1529 /// @param  u32WaitMs       \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the semaphore count = 0
1530 /// @return TRUE : succeed
1531 /// @return FALSE : fail
1532 //-------------------------------------------------------------------------------------------------
MsOS_ObtainSemaphore(MS_S32 s32SemaphoreId,MS_U32 u32WaitMs)1533 MS_BOOL MsOS_ObtainSemaphore (MS_S32 s32SemaphoreId, MS_U32 u32WaitMs)
1534 {
1535     MS_BOOL bRet = FALSE;
1536     unsigned long flags;
1537 
1538     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1539     {
1540         return FALSE;
1541     }
1542     else
1543     {
1544         s32SemaphoreId &= MSOS_ID_MASK;
1545     }
1546 
1547     SEMA_MUTEX_LOCK(flags);
1548     if (!_MsOS_Semaphore_Info[s32SemaphoreId].bUsed)
1549     {
1550         SEMA_MUTEX_UNLOCK(flags);
1551         return FALSE;
1552     }
1553     SEMA_MUTEX_UNLOCK(flags);
1554 
1555     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
1556     {
1557     #if 0
1558         /**
1559         * down_interruptible - acquire the semaphore unless interrupted
1560         * @sem: the semaphore to be acquired
1561         *
1562         * Attempts to acquire the semaphore.  If no more tasks are allowed to
1563         * acquire the semaphore, calling this function will put the task to sleep.
1564         * If the sleep is interrupted by a signal, this function will return -EINTR.
1565         * If the semaphore is successfully acquired, this function returns 0.
1566         */
1567         bRet = down_interruptible(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore)  >=0 ? TRUE : FALSE;
1568     #else
1569         /**
1570         * down - acquire the semaphore
1571         * @sem: the semaphore to be acquired
1572         *
1573         * Acquires the semaphore.  If no more tasks are allowed to acquire the
1574         * semaphore, calling this function will put the task to sleep until the
1575         * semaphore is released.
1576         *
1577         * Use of this function is deprecated, please use down_interruptible() or
1578         * down_killable() instead.
1579         */
1580         down(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore);
1581         bRet = TRUE;
1582     #endif
1583     }
1584     else //blocking wait with timeout
1585     {
1586         long    timeout;
1587 
1588         timeout = msecs_to_jiffies(u32WaitMs);
1589 
1590     #if 0
1591         /**
1592         * down_timeout_interruptible - acquire the semaphore within a specified time unless interrupted
1593         * @sem: the semaphore to be acquired
1594         * @jiffies: how long to wait before failing
1595         */
1596         bRet = (down_timeout_interruptible(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore, timeout) >=0 ? TRUE : FALSE);
1597     #else
1598         /**
1599         * down_timeout - acquire the semaphore within a specified time
1600         * @sem: the semaphore to be acquired
1601         * @jiffies: how long to wait before failing
1602         *
1603         * Attempts to acquire the semaphore.  If no more tasks are allowed to
1604         * acquire the semaphore, calling this function will put the task to sleep.
1605         * If the semaphore is not released within the specified number of jiffies,
1606         * this function returns -ETIME.  It returns 0 if the semaphore was acquired.
1607         */
1608         bRet = (down_timeout(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore, timeout) >=0 ? TRUE : FALSE);
1609     #endif
1610     }
1611 
1612     return bRet;
1613 }
1614 
1615 //-------------------------------------------------------------------------------------------------
1616 /// Increase a semaphore count
1617 /// @param  s32SemaphoreId  \b IN: semaphore ID
1618 /// @return TRUE : succeed
1619 /// @return FALSE : fail
1620 /// @note   It's possible for any thread to increase the semaphore count
1621 //-------------------------------------------------------------------------------------------------
MsOS_ReleaseSemaphore(MS_S32 s32SemaphoreId)1622 MS_BOOL MsOS_ReleaseSemaphore (MS_S32 s32SemaphoreId)
1623 {
1624     unsigned long flags;
1625     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1626     {
1627         return FALSE;
1628     }
1629     else
1630     {
1631         s32SemaphoreId &= MSOS_ID_MASK;
1632     }
1633 
1634     SEMA_MUTEX_LOCK(flags);
1635     if (!_MsOS_Semaphore_Info[s32SemaphoreId].bUsed)
1636     {
1637         SEMA_MUTEX_UNLOCK(flags);
1638         return FALSE;
1639     }
1640     SEMA_MUTEX_UNLOCK(flags);
1641 
1642     /**
1643     * up - release the semaphore
1644     * @sem: the semaphore to release
1645     *
1646     * Release the semaphore.  Unlike mutexes, up() may be called from any
1647     * context and even by tasks which have never called down().
1648     */
1649     up(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore);
1650     return TRUE;
1651 }
1652 
1653 #if 0
1654 //-------------------------------------------------------------------------------------------------
1655 // Get a semaphore informaton
1656 // @param  s32SemaphoreId  \b IN: semaphore ID
1657 // @param  pu32InitCnt     \b OUT: ptr to initial semaphore value
1658 // @param  peAttribute     \b OUT: ptr to suspended mode: E_MSOS_FIFO / E_MSOS_PRIORITY
1659 // @param  pSemaphoreName  \b OUT: ptr to semaphore name
1660 // @return TRUE : succeed
1661 // @return FALSE : the semaphore has not been created.
1662 //-------------------------------------------------------------------------------------------------
1663 MS_BOOL MsOS_InfoSemaphore (MS_S32 s32SemaphoreId, MS_U32 *pu32InitCnt, MsOSAttribute *peAttribute, char *pSemaphoreName)
1664 {
1665     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1666     {
1667         return FALSE;
1668     }
1669     else
1670     {
1671         s32SemaphoreId &= MSOS_ID_MASK;
1672     }
1673 
1674     return sem_getvalue(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore,
1675         (int *)pu32InitCnt) >= 0 ? TRUE : FALSE;
1676 }
1677 #endif
1678 
1679 //
1680 // Event management
1681 //
1682 //-------------------------------------------------------------------------------------------------
1683 /// Create an event group
1684 /// @param  pEventName  \b IN: event group name
1685 /// @return >=0 : assigned Event Id
1686 /// @return <0 : fail
1687 //-------------------------------------------------------------------------------------------------
MsOS_CreateEventGroup(char * pEventName)1688 MS_S32 MsOS_CreateEventGroup (char *pEventName)
1689 {
1690     MS_S32 s32Id;
1691     unsigned long flag;
1692 
1693     EVENT_MUTEX_LOCK(flag);
1694 
1695     for(s32Id=0; s32Id<MSOS_EVENTGROUP_MAX; s32Id++)
1696     {
1697         if(_MsOS_EventGroup_Info[s32Id].bUsed == FALSE)
1698         {
1699             break;
1700         }
1701     }
1702 
1703     if(s32Id >= MSOS_EVENTGROUP_MAX)
1704     {
1705         EVENT_MUTEX_UNLOCK(flag);
1706         return -1;
1707     }
1708 
1709     spin_lock_init(&_MsOS_EventGroup_Info[s32Id].stMutexEvent);
1710     _MsOS_EventGroup_Info[s32Id].bUsed = TRUE;
1711     _MsOS_EventGroup_Info[s32Id].u32Waiting = 0;
1712     spin_lock_irqsave(&_MsOS_EventGroup_Info[s32Id].stMutexEvent, flag);
1713     _MsOS_EventGroup_Info[s32Id].u32EventGroup= 0;
1714     spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32Id].stMutexEvent, flag);
1715 
1716     EVENT_MUTEX_UNLOCK(flag);
1717 
1718     init_waitqueue_head(&_MsOS_EventGroup_Info[s32Id].stEventWaitQueue);
1719     s32Id |= MSOS_ID_PREFIX;
1720     return s32Id;
1721 }
1722 
1723 //-------------------------------------------------------------------------------------------------
1724 /// Delete the event group
1725 /// @param  s32EventGroupId \b IN: event group ID
1726 /// @return TRUE : succeed
1727 /// @return FALSE : fail, sb is waiting for the event flag
1728 /// @note event group that are being waited on must not be deleted
1729 //-------------------------------------------------------------------------------------------------
MsOS_DeleteEventGroup(MS_S32 s32EventGroupId)1730 MS_BOOL MsOS_DeleteEventGroup (MS_S32 s32EventGroupId)
1731 {
1732     unsigned long flags;
1733     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1734     {
1735         return FALSE;
1736     }
1737     else
1738     {
1739         s32EventGroupId &= MSOS_ID_MASK;
1740     }
1741 
1742     EVENT_MUTEX_LOCK(flags);
1743     if (!_MsOS_EventGroup_Info[s32EventGroupId].bUsed)
1744     {
1745         EVENT_MUTEX_UNLOCK(flags);
1746         return FALSE;
1747     }
1748 
1749     if (0 < _MsOS_EventGroup_Info[s32EventGroupId].u32Waiting)
1750     {
1751         EVENT_MUTEX_UNLOCK(flags);
1752         printk("\033[35m[%s][%d] EventGroup Delete FAIL : Event was still waiting.\033[m\n", __func__, __LINE__);
1753         return FALSE;
1754     }
1755 
1756     spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flags);
1757     _MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup= 0;
1758     spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flags);
1759     _MsOS_EventGroup_Info[s32EventGroupId].bUsed = FALSE;
1760     _MsOS_EventGroup_Info[s32EventGroupId].u32Waiting = 0;
1761     EVENT_MUTEX_UNLOCK(flags);
1762 
1763     init_waitqueue_head(&_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue);
1764     return TRUE;
1765 }
1766 
1767 
1768 //-------------------------------------------------------------------------------------------------
1769 /// Set the event flag (bitwise OR w/ current value) in the specified event group
1770 /// @param  s32EventGroupId \b IN: event group ID
1771 /// @param  u32EventFlag    \b IN: event flag value
1772 /// @return TRUE : succeed
1773 /// @return FALSE : fail
1774 //-------------------------------------------------------------------------------------------------
MsOS_SetEvent(MS_S32 s32EventGroupId,MS_U32 u32EventFlag)1775 MS_BOOL MsOS_SetEvent (MS_S32 s32EventGroupId, MS_U32 u32EventFlag)
1776 {
1777     unsigned long flag;
1778     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1779     {
1780         return FALSE;
1781     }
1782     else
1783     {
1784         s32EventGroupId &= MSOS_ID_MASK;
1785     }
1786 
1787     EVENT_MUTEX_LOCK(flag);
1788     if (!_MsOS_EventGroup_Info[s32EventGroupId].bUsed)
1789     {
1790         EVENT_MUTEX_UNLOCK(flag);
1791         return FALSE;
1792     }
1793     EVENT_MUTEX_UNLOCK(flag);
1794 
1795     spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1796     SET_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, u32EventFlag);
1797     wake_up_all(&_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue);
1798     spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1799 
1800     return TRUE;
1801 }
1802 
1803 //-------------------------------------------------------------------------------------------------
1804 /// Clear the specified event flag (bitwise XOR operation) in the specified event group
1805 /// @param  s32EventGroupId \b IN: event group ID
1806 /// @param  u32EventFlag    \b IN: event flag value
1807 /// @return TRUE : succeed
1808 /// @return FALSE : fail
1809 //-------------------------------------------------------------------------------------------------
MsOS_ClearEvent(MS_S32 s32EventGroupId,MS_U32 u32EventFlag)1810 MS_BOOL MsOS_ClearEvent (MS_S32 s32EventGroupId, MS_U32 u32EventFlag)
1811 {
1812     unsigned long flag;
1813     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1814     {
1815         return FALSE;
1816     }
1817     else
1818     {
1819         s32EventGroupId &= MSOS_ID_MASK;
1820     }
1821 
1822     EVENT_MUTEX_LOCK(flag);
1823     if (!_MsOS_EventGroup_Info[s32EventGroupId].bUsed)
1824     {
1825         EVENT_MUTEX_UNLOCK(flag);
1826         return FALSE;
1827     }
1828     EVENT_MUTEX_UNLOCK(flag);
1829 
1830     spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
1831     RESET_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, u32EventFlag);
1832     spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1833 
1834     return TRUE;
1835 }
1836 
1837 //-------------------------------------------------------------------------------------------------
1838 /// Wait for the specified event flag combination from the event group
1839 /// @param  s32EventGroupId     \b IN: event group ID
1840 /// @param  u32WaitEventFlag    \b IN: wait event flag value
1841 /// @param  pu32RetrievedEventFlag \b OUT: retrieved event flag value
1842 /// @param  eWaitMode           \b IN: E_AND/E_OR/E_AND_CLEAR/E_OR_CLEAR
1843 /// @param  u32WaitMs           \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the event is not ready
1844 /// @return TRUE : succeed
1845 /// @return FALSE : fail
1846 //-------------------------------------------------------------------------------------------------
MsOS_WaitEvent(MS_S32 s32EventGroupId,MS_U32 u32WaitEventFlag,MS_U32 * pu32RetrievedEventFlag,EventWaitMode eWaitMode,MS_U32 u32WaitMs)1847 MS_BOOL MsOS_WaitEvent (MS_S32 s32EventGroupId,
1848                      MS_U32 u32WaitEventFlag,
1849                      MS_U32 *pu32RetrievedEventFlag,
1850                      EventWaitMode eWaitMode,
1851                      MS_U32 u32WaitMs)
1852 {
1853     MS_BOOL bRet= FALSE;
1854     MS_BOOL bAnd;
1855     MS_BOOL bClear;
1856     unsigned long flag;
1857 
1858     *pu32RetrievedEventFlag = 0;
1859 
1860     if (!u32WaitEventFlag)
1861     {
1862         return FALSE;
1863     }
1864 
1865     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1866     {
1867         return FALSE;
1868     }
1869     else
1870     {
1871         s32EventGroupId &= MSOS_ID_MASK;
1872     }
1873 
1874     EVENT_MUTEX_LOCK(flag);
1875     if (!_MsOS_EventGroup_Info[s32EventGroupId].bUsed)
1876     {
1877         EVENT_MUTEX_UNLOCK(flag);
1878         return FALSE;
1879     }
1880     _MsOS_EventGroup_Info[s32EventGroupId].u32Waiting++;
1881     EVENT_MUTEX_UNLOCK(flag);
1882 
1883     bClear= ((E_AND_CLEAR== eWaitMode) || (E_OR_CLEAR== eWaitMode))? TRUE: FALSE;
1884     bAnd= ((E_AND== eWaitMode)|| (E_AND_CLEAR== eWaitMode))? TRUE: FALSE;
1885 
1886     spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
1887 
1888     do{
1889         if (u32WaitMs== MSOS_WAIT_FOREVER) //blocking wait
1890         {
1891             if (bAnd)
1892             {
1893                 spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1894                 wait_event(_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue,
1895                             ((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag) == u32WaitEventFlag));
1896                 spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1897             }
1898             else
1899             {
1900                 spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1901                 wait_event(_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue,
1902                             ((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag) != 0));
1903                 spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1904             }
1905         }
1906         else if (u32WaitMs == 0)
1907         {
1908             *pu32RetrievedEventFlag= HAS_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, u32WaitEventFlag);
1909             break;
1910         }
1911         else
1912         {
1913             u32WaitMs = msecs_to_jiffies(u32WaitMs);
1914 
1915             if (bAnd)
1916             {
1917                 spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1918                 wait_event_timeout(_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue,
1919                                     ((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag) == u32WaitEventFlag),
1920                                     u32WaitMs);
1921                 spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1922             }
1923             else
1924             {
1925                 spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1926                 wait_event_timeout(_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue,
1927                                     ((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag) != 0),
1928                                     u32WaitMs);
1929                 spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1930             }
1931         }
1932         *pu32RetrievedEventFlag= HAS_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, u32WaitEventFlag);
1933     } while (0);
1934 
1935     //spin_lock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent);
1936     bRet= (bAnd)? (*pu32RetrievedEventFlag== u32WaitEventFlag): (0!= *pu32RetrievedEventFlag);
1937     if (bRet && bClear)
1938     {
1939         RESET_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, *pu32RetrievedEventFlag);
1940     }
1941     spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
1942 
1943     EVENT_MUTEX_LOCK(flag);
1944     _MsOS_EventGroup_Info[s32EventGroupId].u32Waiting--;
1945     EVENT_MUTEX_UNLOCK(flag);
1946 
1947     return bRet;
1948 }
1949 
1950 
1951 //-------------------------------------------------------------------------------------------------
1952 /// Wait for the specified event flag combination from the event group
1953 /// @param  s32EventGroupId     \b IN: event group ID
1954 /// @param  u32WaitEventFlag    \b IN: wait event flag value
1955 /// @param  pu32RetrievedEventFlag \b OUT: retrieved event flag value
1956 /// @param  eWaitMode           \b IN: E_AND/E_OR/E_AND_CLEAR/E_OR_CLEAR
1957 /// @param  u32WaitMs           \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the event is not ready
1958 /// @return TRUE : succeed
1959 /// @return FALSE : fail
1960 /// @return -ERESTARTSYS : interrupt by  ERESTARTSYS
1961 //-------------------------------------------------------------------------------------------------
MsOS_WaitEvent_Interrupt(MS_S32 s32EventGroupId,MS_U32 u32WaitEventFlag,MS_U32 * pu32RetrievedEventFlag,EventWaitMode eWaitMode,MS_U32 u32WaitMs)1962 MS_S32 MsOS_WaitEvent_Interrupt(MS_S32 s32EventGroupId,
1963                      MS_U32 u32WaitEventFlag,
1964                      MS_U32 *pu32RetrievedEventFlag,
1965                      EventWaitMode eWaitMode,
1966                      MS_U32 u32WaitMs)
1967 {
1968     MS_S32 s32Ret= FALSE;
1969     MS_BOOL bAnd;
1970     MS_BOOL bClear;
1971     unsigned long flag;
1972 
1973     *pu32RetrievedEventFlag = 0;
1974 
1975     if (!u32WaitEventFlag)
1976     {
1977         return s32Ret;
1978     }
1979 
1980     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1981     {
1982         return s32Ret;
1983     }
1984     else
1985     {
1986         s32EventGroupId &= MSOS_ID_MASK;
1987     }
1988 
1989     EVENT_MUTEX_LOCK(flag);
1990     if (!_MsOS_EventGroup_Info[s32EventGroupId].bUsed)
1991     {
1992         EVENT_MUTEX_UNLOCK(flag);
1993         return (MS_S32)FALSE;
1994     }
1995     _MsOS_EventGroup_Info[s32EventGroupId].u32Waiting++;
1996     EVENT_MUTEX_UNLOCK(flag);
1997 
1998     bClear= ((E_AND_CLEAR== eWaitMode) || (E_OR_CLEAR== eWaitMode))? TRUE: FALSE;
1999     bAnd= ((E_AND== eWaitMode)|| (E_AND_CLEAR== eWaitMode))? TRUE: FALSE;
2000 
2001     spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
2002 
2003     do{
2004         if (u32WaitMs== MSOS_WAIT_FOREVER) //blocking wait
2005         {
2006             if (bAnd)
2007             {
2008                 spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
2009                 do
2010                 {
2011                     s32Ret = wait_event_interruptible(_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue,
2012                             ((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag) == u32WaitEventFlag));
2013                     if(s32Ret == -ERESTARTSYS)
2014                     {
2015 					_MsOS_EventGroup_Info[s32EventGroupId].u32Waiting--;
2016                     return -ERESTARTSYS;
2017                     }
2018 
2019                 }while(!((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag)== u32WaitEventFlag));
2020                 spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
2021             }
2022             else
2023             {
2024                 do
2025                 {
2026                 spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
2027                 s32Ret = wait_event_interruptible(_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue,
2028                             ((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag) != 0));
2029                     if(s32Ret == -ERESTARTSYS)
2030                     {
2031 					_MsOS_EventGroup_Info[s32EventGroupId].u32Waiting--;
2032                     return -ERESTARTSYS;
2033                     }
2034                 }while(!((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag)!= 0));
2035                 spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
2036             }
2037         }
2038         else
2039         {
2040             if(u32WaitMs != 0)
2041             {
2042             u32WaitMs = msecs_to_jiffies(u32WaitMs);
2043             if (bAnd)
2044             {
2045                 spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
2046                 wait_event_timeout(_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue,
2047                                     ((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag) == u32WaitEventFlag),
2048                                     u32WaitMs);
2049                 spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
2050             }
2051             else
2052             {
2053                 spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
2054                 wait_event_timeout(_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue,
2055                                     ((_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup & u32WaitEventFlag) != 0),
2056                                     u32WaitMs);
2057                 spin_lock_irqsave(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent, flag);
2058             }
2059             }
2060         }
2061         *pu32RetrievedEventFlag= HAS_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, u32WaitEventFlag);
2062     } while (0);
2063 
2064     //spin_lock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent);
2065     s32Ret= (bAnd)? (*pu32RetrievedEventFlag== u32WaitEventFlag): (0!= *pu32RetrievedEventFlag);
2066     if (s32Ret && (MS_S32)bClear)
2067     {
2068         RESET_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, *pu32RetrievedEventFlag);
2069     }
2070     spin_unlock_irqrestore(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,flag);
2071 
2072     EVENT_MUTEX_LOCK(flag);
2073     _MsOS_EventGroup_Info[s32EventGroupId].u32Waiting--;
2074     EVENT_MUTEX_UNLOCK(flag);
2075 
2076     return s32Ret;
2077 }
2078 
MsOS_GetEventQueue(MS_S32 s32EventGroupId)2079 wait_queue_head_t* MsOS_GetEventQueue (MS_S32 s32EventGroupId)
2080 {
2081     unsigned long flag;
2082     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2083     {
2084         return NULL;
2085     }
2086     else
2087     {
2088         s32EventGroupId &= MSOS_ID_MASK;
2089     }
2090 
2091     EVENT_MUTEX_LOCK(flag);
2092     if (!_MsOS_EventGroup_Info[s32EventGroupId].bUsed)
2093     {
2094         EVENT_MUTEX_UNLOCK(flag);
2095         return NULL;
2096     }
2097     EVENT_MUTEX_UNLOCK(flag);
2098 
2099     return (&_MsOS_EventGroup_Info[s32EventGroupId].stEventWaitQueue);
2100 }
2101 
2102 /// @FIXME: Timer API are empty
2103 //
2104 // Timer management
2105 //
_MsOS_TimerNotify(unsigned long data)2106 static void _MsOS_TimerNotify(unsigned long data)
2107 {
2108     MS_S32 s32Id = (MS_S32) data;
2109     TimerCb pfnTimerCb;
2110     unsigned long flags;
2111 
2112     TIMER_MUTEX_LOCK(flags);
2113 
2114     if( !_MsOS_Timer_Info[s32Id].bUsed )
2115     {
2116         TIMER_MUTEX_UNLOCK(flags);
2117         return;
2118     }
2119 
2120     pfnTimerCb = _MsOS_Timer_Info[s32Id].pTimerCb;
2121     _MsOS_Timer_Info[s32Id].timer.expires = jiffies + HZ*_MsOS_Timer_Info[s32Id].period/1000;
2122 
2123     if ( _MsOS_Timer_Info[s32Id].bCircle )
2124         add_timer(&(_MsOS_Timer_Info[s32Id].timer));
2125 
2126     TIMER_MUTEX_UNLOCK(flags);
2127 
2128     if (pfnTimerCb)
2129     {
2130         pfnTimerCb(0, s32Id | MSOS_ID_PREFIX);
2131     }
2132 }
2133 
2134 
2135 //-------------------------------------------------------------------------------------------------
2136 /// Create a Timer
2137 /// @param  pTimerCb        \b IN: timer callback function
2138 /// @param  u32FirstTimeMs  \b IN: first ms for timer expiration
2139 /// @param  u32PeriodTimeMs \b IN: periodic ms for timer expiration after first expiration
2140 ///                                0: one shot timer
2141 /// @param  bStartTimer     \b IN: TRUE: activates the timer after it is created
2142 ///                                FALSE: leaves the timer disabled after it is created
2143 /// @param  pTimerName      \b IN: Timer name (not used by eCos)
2144 /// @return >=0 : assigned Timer ID
2145 ///         <0 : fail
2146 //-------------------------------------------------------------------------------------------------
MsOS_CreateTimer(TimerCb pTimerCb,MS_U32 u32FirstTimeMs,MS_U32 u32PeriodTimeMs,MS_BOOL bStartTimer,char * pTimerName)2147 MS_S32 MsOS_CreateTimer (TimerCb pTimerCb,
2148                       MS_U32 u32FirstTimeMs,
2149                       MS_U32 u32PeriodTimeMs,
2150                       MS_BOOL bStartTimer,
2151                       char *pTimerName)
2152 {
2153     MS_S32 s32Id;
2154     unsigned long flags;
2155 
2156     TIMER_MUTEX_LOCK(flags);
2157     for(s32Id=0;s32Id<MSOS_TIMER_MAX;s32Id++)
2158     {
2159         if(_MsOS_Timer_Info[s32Id].bUsed == FALSE)
2160         {
2161             break;
2162         }
2163     }
2164 
2165     if(s32Id >= MSOS_TIMER_MAX)
2166     {
2167         TIMER_MUTEX_UNLOCK(flags);
2168         return -1;
2169     }
2170 
2171     init_timer(&(_MsOS_Timer_Info[s32Id].timer));
2172     _MsOS_Timer_Info[s32Id].bUsed = TRUE;
2173     _MsOS_Timer_Info[s32Id].bCircle = TRUE;
2174     _MsOS_Timer_Info[s32Id].pTimerCb = pTimerCb;
2175     _MsOS_Timer_Info[s32Id].first = u32FirstTimeMs;
2176     _MsOS_Timer_Info[s32Id].period = u32PeriodTimeMs;
2177     _MsOS_Timer_Info[s32Id].timer.data = (unsigned long)s32Id;
2178     _MsOS_Timer_Info[s32Id].timer.expires = jiffies + HZ*u32FirstTimeMs/1000;
2179     _MsOS_Timer_Info[s32Id].timer.function = _MsOS_TimerNotify;
2180 
2181     if (bStartTimer)
2182     {
2183         add_timer(&(_MsOS_Timer_Info[s32Id].timer));
2184     }
2185     TIMER_MUTEX_UNLOCK(flags);
2186     s32Id |= MSOS_ID_PREFIX;
2187     return s32Id;
2188 }
2189 
2190 //-------------------------------------------------------------------------------------------------
2191 /// Delete the Timer
2192 /// @param  s32TimerId  \b IN: Timer ID
2193 /// @return TRUE : succeed
2194 /// @return FALSE : fail
2195 //-------------------------------------------------------------------------------------------------
MsOS_DeleteTimer(MS_S32 s32TimerId)2196 MS_BOOL MsOS_DeleteTimer (MS_S32 s32TimerId)
2197 {
2198     unsigned long flags;
2199     //return FALSE;
2200 
2201     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2202     {
2203         return FALSE;
2204     }
2205     else
2206     {
2207         s32TimerId &= MSOS_ID_MASK;
2208     }
2209 
2210     TIMER_MUTEX_LOCK(flags);
2211     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2212     {
2213         del_timer(&(_MsOS_Timer_Info[s32TimerId].timer));
2214         _MsOS_Timer_Info[s32TimerId].bUsed = FALSE;
2215         _MsOS_Timer_Info[s32TimerId].bCircle = FALSE;
2216         _MsOS_Timer_Info[s32TimerId].pTimerCb = NULL;
2217         _MsOS_Timer_Info[s32TimerId].period = 0;
2218         _MsOS_Timer_Info[s32TimerId].first = 0;
2219         memset(&_MsOS_Timer_Info[s32TimerId].timer, 0, sizeof(struct timer_list));
2220         TIMER_MUTEX_UNLOCK(flags);
2221         return TRUE;
2222     }
2223     else
2224     {
2225         TIMER_MUTEX_UNLOCK(flags);
2226         return FALSE;
2227     }
2228 }
2229 
2230 //-------------------------------------------------------------------------------------------------
2231 /// Start the Timer
2232 /// @param  s32TimerId  \b IN: Timer ID
2233 /// @return TRUE : succeed
2234 /// @return FALSE : fail
2235 //-------------------------------------------------------------------------------------------------
MsOS_StartTimer(MS_S32 s32TimerId)2236 MS_BOOL MsOS_StartTimer (MS_S32 s32TimerId)
2237 {
2238     unsigned long flags;
2239     //return FALSE;
2240 
2241     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2242     {
2243         return FALSE;
2244     }
2245     else
2246     {
2247         s32TimerId &= MSOS_ID_MASK;
2248     }
2249 
2250     TIMER_MUTEX_LOCK(flags);
2251     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2252     {
2253         _MsOS_Timer_Info[s32TimerId].bCircle = TRUE;
2254         _MsOS_Timer_Info[s32TimerId].timer.expires = jiffies + _MsOS_Timer_Info[s32TimerId].period/1000;
2255         add_timer(&(_MsOS_Timer_Info[s32TimerId].timer));
2256         TIMER_MUTEX_UNLOCK(flags);
2257         return TRUE;
2258     }
2259     else
2260     {
2261         TIMER_MUTEX_UNLOCK(flags);
2262         return FALSE;
2263     }
2264 }
2265 
2266 //-------------------------------------------------------------------------------------------------
2267 /// Stop the Timer
2268 /// @param  s32TimerId  \b IN: Timer ID
2269 /// @return TRUE : succeed
2270 /// @return FALSE : fail
2271 /// @note   MsOS_StopTimer then MsOS_StartTimer => The timer will trigger at the same relative
2272 ///             intervals that it would have if it had not been disabled.
2273 //-------------------------------------------------------------------------------------------------
MsOS_StopTimer(MS_S32 s32TimerId)2274 MS_BOOL MsOS_StopTimer (MS_S32 s32TimerId)
2275 {
2276     unsigned long flags;
2277     //return FALSE;
2278 
2279     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2280     {
2281         return FALSE;
2282     }
2283     else
2284     {
2285         s32TimerId &= MSOS_ID_MASK;
2286     }
2287 
2288     TIMER_MUTEX_LOCK(flags);
2289     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2290     {
2291         _MsOS_Timer_Info[s32TimerId].bCircle = FALSE;
2292         del_timer(&(_MsOS_Timer_Info[s32TimerId].timer));
2293         TIMER_MUTEX_UNLOCK(flags);
2294         return TRUE;
2295     }
2296     else
2297     {
2298         TIMER_MUTEX_UNLOCK(flags);
2299         return FALSE;
2300     }
2301 }
2302 
2303 //-------------------------------------------------------------------------------------------------
2304 /// Reset a Timer & reset the expiration periods
2305 /// @param  s32TimerId      \b IN: Timer ID
2306 /// @param  u32FirstTimeMs  \b IN: first ms for timer expiration
2307 /// @param  u32PeriodTimeMs \b IN: periodic ms for timer expiration after first expiration
2308 ///                                0: one shot timer
2309 /// @param  bStartTimer     \b IN: TRUE: activates the timer after it is created
2310 ///                                FALSE: leaves the timer disabled after it is created
2311 /// @return TRUE : succeed
2312 /// @return FALSE : fail
2313 //-------------------------------------------------------------------------------------------------
MsOS_ResetTimer(MS_S32 s32TimerId,MS_U32 u32FirstTimeMs,MS_U32 u32PeriodTimeMs,MS_BOOL bStartTimer)2314 MS_BOOL MsOS_ResetTimer (MS_S32 s32TimerId,
2315                       MS_U32 u32FirstTimeMs,
2316                       MS_U32 u32PeriodTimeMs,
2317                       MS_BOOL bStartTimer)
2318 {
2319 #if 0
2320     struct itimerspec StopTimer;
2321     struct itimerspec dummy;
2322 
2323     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2324     {
2325         return FALSE;
2326     }
2327     else
2328     {
2329         s32TimerId &= MSOS_ID_MASK;
2330     }
2331 
2332     _MsOS_Timer_Info[s32TimerId].TimeInfo.it_value.tv_sec=           u32FirstTimeMs/1000;
2333     _MsOS_Timer_Info[s32TimerId].TimeInfo.it_value.tv_nsec=          (u32FirstTimeMs- (_MsOS_Timer_Info[s32TimerId].TimeInfo.it_value.tv_sec)*1000)* 1000000;
2334     _MsOS_Timer_Info[s32TimerId].TimeInfo.it_interval.tv_sec=        u32PeriodTimeMs/1000;
2335     _MsOS_Timer_Info[s32TimerId].TimeInfo.it_interval.tv_sec=        (u32PeriodTimeMs- (_MsOS_Timer_Info[s32TimerId].TimeInfo.it_interval.tv_sec)*1000)* 1000000;
2336 
2337 
2338     if(bStartTimer)
2339     {
2340         if (0> timer_settime(_MsOS_Timer_Info[s32TimerId].TimerId, 0, &_MsOS_Timer_Info[s32TimerId].TimeInfo, &dummy))
2341         {
2342             // @FIXME: should not fail here. Do error handling later
2343             MS_ASSERT(0);
2344         }
2345     }
2346     else
2347     {
2348         memset(&StopTimer, 0, sizeof(StopTimer));
2349         if (0> timer_settime(_MsOS_Timer_Info[s32TimerId].TimerId, 0, &StopTimer, &dummy))
2350         {
2351             // @FIXME: should not fail here. Do error handling later
2352             MS_ASSERT(0);
2353         }
2354     }
2355 
2356     return TRUE;
2357 #else
2358     return FALSE;
2359 #endif
2360 }
2361 
2362 //
2363 // System time
2364 //
2365 //-------------------------------------------------------------------------------------------------
2366 /// Get current system time in ms
2367 /// @return system time in ms
2368 //-------------------------------------------------------------------------------------------------
MsOS_GetSystemTime(void)2369 MS_U32 MsOS_GetSystemTime (void)
2370 {
2371     struct timespec         ts;
2372 
2373     getrawmonotonic(&ts);
2374     return ts.tv_sec* 1000+ ts.tv_nsec/1000000;
2375 }
2376 
2377 //-------------------------------------------------------------------------------------------------
2378 ///[OBSOLETE]
2379 /// Time difference between current time and task time
2380 /// @return system time diff in ms
2381 //-------------------------------------------------------------------------------------------------
MsOS_Timer_DiffTimeFromNow(MS_U32 u32TaskTimer)2382 MS_U32 MsOS_Timer_DiffTimeFromNow(MS_U32 u32TaskTimer) //unit = ms
2383 {
2384     return (MsOS_GetSystemTime() - u32TaskTimer);
2385 }
2386 
2387 //-------------------------------------------------------------------------------------------------
2388 ///[OBSOLETE]
2389 /// Time difference between setting time and task time
2390 /// @return system time diff in ms
2391 //-------------------------------------------------------------------------------------------------
MsOS_Timer_DiffTime(MS_U32 u32Timer,MS_U32 u32TaskTimer)2392 MS_U32 MsOS_Timer_DiffTime(MS_U32 u32Timer, MS_U32 u32TaskTimer) //unit = ms
2393 {
2394     // simple minus is enough, because max(timer_counter) == max(u32)
2395     return (u32Timer - u32TaskTimer);
2396 }
2397 
2398 /*
2399 //COUNT was reset at system initialization
2400 //-------------------------------------------------------------------------------------------------
2401 /// Set current system time
2402 /// @param  u32SystemTime  \b IN: system time in ms
2403 /// @return TRUE - succeed
2404 //-------------------------------------------------------------------------------------------------
2405 MS_BOOL MsOS_SetSystemTime (MS_U32 u32SystemTime)
2406 {
2407     MS_U32 u32COUNT = u32SystemTime*TICK_PER_ONE_MS*CYGNUM_HAL_RTC_PERIOD;
2408 
2409     asm volatile (
2410         "move $8,%0;"
2411         "mtc0 $8,$9;"
2412         "nop; nop; nop;"
2413         :
2414         : "r"(u32COUNT)
2415         : "$8"
2416         );
2417 
2418     return TRUE;
2419 }
2420 */
2421 
2422 #if 0
2423 //
2424 // Queue
2425 //
2426 static inline MS_U32 _MsOS_QueueUsedSize(MsOS_Queue_Info* pQueueInfo)
2427 {
2428     return (pQueueInfo->pu8Write>= pQueueInfo->pu8Read)?
2429                (pQueueInfo->pu8Write- pQueueInfo->pu8Read):
2430                (pQueueInfo->pu8Tail- pQueueInfo->pu8Head+ pQueueInfo->pu8Write- pQueueInfo->pu8Read);
2431 }
2432 
2433 static inline MS_U32 _MsOS_QueueFreeSize(MsOS_Queue_Info* pQueueInfo)
2434 {
2435     return pQueueInfo->pu8Tail- pQueueInfo->pu8Head- _MsOS_QueueUsedSize(pQueueInfo);
2436 }
2437 
2438 //-------------------------------------------------------------------------------------------------
2439 /// Create a Queue
2440 /// @param  pStartAddr      \b IN: It is useless now, can pass NULL.
2441 /// @param  u32QueueSize    \b IN: queue size (byte unit) : now fixed as
2442 ///                                CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE * u32MessageSize
2443 /// @param  eMessageType    \b IN: E_MSG_FIXED_SIZE / E_MSG_VAR_SIZE
2444 /// @param  u32MessageSize  \b IN: message size (byte unit) for E_MSG_FIXED_SIZE
2445 ///                                max message size (byte unit) for E_MSG_VAR_SIZE
2446 /// @param  eAttribute      \b IN: E_MSOS_FIFO suspended in FIFO order
2447 /// @param  pQueueName      \b IN: queue name
2448 /// @return assigned message queue ID
2449 /// @return < 0 - fail
2450 //-------------------------------------------------------------------------------------------------
2451 MS_S32 MsOS_CreateQueue (void         *pStartAddr,
2452                       MS_U32           u32QueueSize,
2453                       MessageType   eMessageType,
2454                       MS_U32           u32MessageSize,
2455                       MsOSAttribute eAttribute,
2456                       char         *pQueueName)
2457 {
2458     MS_S32 s32Id;
2459     MS_U32 u32AlignSize;
2460     pthread_mutexattr_t _MsOS_Mutex_Attr;
2461 
2462     PTH_RET_CHK(pthread_mutexattr_init(&_MsOS_Mutex_Attr));
2463     //PTH_RET_CHK(pthread_mutexattr_setprotocol(&_MsOS_Mutex_Attr, PTHREAD_PRIO_INHERIT));
2464 #ifdef MS_DEBUG
2465     PTH_RET_CHK(pthread_mutexattr_settype(&_MsOS_Mutex_Attr, PTHREAD_MUTEX_ERRORCHECK));
2466 #endif
2467 
2468     if (E_MSG_VAR_SIZE== eMessageType)
2469     {
2470         printk("E_MSG_VAR_SIZE has not been supported yet\n");
2471         return -1;
2472     }
2473 
2474     PTH_RET_CHK(pthread_mutex_lock( &_MsOS_Queue_Mutex));
2475     for( s32Id=0; s32Id<MSOS_QUEUE_MAX; s32Id++)
2476     {
2477         if(_MsOS_Queue_Info[s32Id].bUsed == FALSE)
2478         {
2479             break;
2480         }
2481     }
2482     if(s32Id < MSOS_QUEUE_MAX)
2483     {
2484         _MsOS_Queue_Info[s32Id].u32AlignedMsgSize = u32AlignSize= ALIGN_4(u32MessageSize);
2485         u32QueueSize= u32AlignSize* (CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE+1);
2486         _MsOS_Queue_Info[s32Id].pu8Head= (MS_U8*)malloc(u32AlignSize* (CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE+1));
2487         if(!_MsOS_Queue_Info[s32Id].pu8Head)
2488         {
2489             s32Id = MSOS_QUEUE_MAX; // Invalid queue index
2490         }
2491         else
2492         {
2493             _MsOS_Queue_Info[s32Id].pu8Read= _MsOS_Queue_Info[s32Id].pu8Write= _MsOS_Queue_Info[s32Id].pu8Head;
2494             _MsOS_Queue_Info[s32Id].pu8Tail= _MsOS_Queue_Info[s32Id].pu8Head+ u32QueueSize;
2495             _MsOS_Queue_Info[s32Id].bUsed = TRUE;
2496             _MsOS_Queue_Info[s32Id].eMsgType = eMessageType;
2497         }
2498     }
2499     PTH_RET_CHK(pthread_mutex_unlock( &_MsOS_Queue_Mutex));
2500 
2501     if(s32Id >= MSOS_QUEUE_MAX)
2502     {
2503         return -1;
2504     }
2505     PTH_RET_CHK(pthread_cond_init(&_MsOS_Queue_Info[s32Id].SendSem, NULL));
2506     PTH_RET_CHK(pthread_cond_init(&_MsOS_Queue_Info[s32Id].RecvSem, NULL));
2507     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Queue_Info[s32Id].SendMutex, &_MsOS_Mutex_Attr));
2508     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Queue_Info[s32Id].RecvMutex, &_MsOS_Mutex_Attr));
2509 
2510     s32Id |= MSOS_ID_PREFIX;
2511     return s32Id;
2512 }
2513 
2514 //-------------------------------------------------------------------------------------------------
2515 /// Delete the Queue
2516 /// @param  s32QueueId  \b IN: Queue ID
2517 /// @return TRUE : succeed
2518 /// @return FALSE :  fail
2519 /// @note   It is important that there are not any threads blocked on the queue
2520 ///             when this function is called or the behavior is undefined.
2521 //-------------------------------------------------------------------------------------------------
2522 MS_BOOL MsOS_DeleteQueue (MS_S32 s32QueueId)
2523 {
2524     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2525     {
2526         return FALSE;
2527     }
2528     else
2529     {
2530         s32QueueId &= MSOS_ID_MASK;
2531     }
2532 
2533     PTH_RET_CHK(pthread_mutex_lock( &_MsOS_Queue_Mutex));
2534     if(_MsOS_Queue_Info[s32QueueId].pu8Head)
2535     {
2536         free(_MsOS_Queue_Info[s32QueueId].pu8Head);
2537     }
2538     _MsOS_Queue_Info[s32QueueId].pu8Head= NULL;
2539     _MsOS_Queue_Info[s32QueueId].bUsed = FALSE;
2540     PTH_RET_CHK(pthread_mutex_unlock( &_MsOS_Queue_Mutex));
2541 
2542     PTH_RET_CHK(pthread_cond_destroy(&_MsOS_Queue_Info[s32QueueId].SendSem));
2543     PTH_RET_CHK(pthread_cond_destroy(&_MsOS_Queue_Info[s32QueueId].RecvSem));
2544     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_Queue_Info[s32QueueId].SendMutex));
2545     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_Queue_Info[s32QueueId].RecvMutex));
2546     return TRUE;
2547 }
2548 
2549 //-------------------------------------------------------------------------------------------------
2550 /// Send a message to the end of the specified queue
2551 /// @param  s32QueueId  \b IN: Queue ID
2552 /// @param  pu8Message  \b IN: ptr to msg to send. NULL ptr is not allowed
2553 /// @param  u32Size     \b IN: msg size (byte)
2554 /// @param  u32WaitMs   \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the queue is full
2555 /// @return TRUE : succeed
2556 /// @return FALSE :  fail
2557 //-------------------------------------------------------------------------------------------------
2558 MS_BOOL MsOS_SendToQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32Size, MS_U32 u32WaitMs)
2559 {
2560     MsOS_Queue_Info* pQueueInfo= NULL;
2561 
2562     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2563     {
2564         return FALSE;
2565     }
2566     else
2567     {
2568         s32QueueId &= MSOS_ID_MASK;
2569     }
2570 
2571     //coz cyg_mbox_get will return NULL for error
2572     if ( pu8Message==NULL)
2573     {
2574         return FALSE;
2575     }
2576 
2577     pQueueInfo= &_MsOS_Queue_Info[s32QueueId];
2578     if(u32Size > pQueueInfo->u32AlignedMsgSize)
2579     {
2580         return FALSE;
2581     }
2582 
2583     if (u32Size>= _MsOS_QueueFreeSize(pQueueInfo))
2584     {
2585         if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
2586         {
2587             PTH_RET_CHK(pthread_cond_wait(&pQueueInfo->RecvSem, &pQueueInfo->RecvMutex));
2588         }
2589         else
2590         {
2591             struct timespec     StopTime;
2592 //            if (0== u32WaitMs)
2593 //            {
2594 //                u32WaitMs=          MSOS_TIME_MIN_WAIT_TV;
2595 //            }
2596             _TimeAbs(StopTime, u32WaitMs);
2597             if (PTH_RET_CHK(pthread_cond_timedwait(&pQueueInfo->RecvSem, &pQueueInfo->RecvMutex, &StopTime)))
2598             {
2599                 return FALSE;
2600             }
2601         }
2602     }
2603 
2604     memcpy(pQueueInfo->pu8Write, pu8Message, u32Size);
2605     pQueueInfo->pu8Write+= pQueueInfo->u32AlignedMsgSize;
2606     if (pQueueInfo->pu8Write>= pQueueInfo->pu8Tail)
2607     {
2608         pQueueInfo->pu8Write= pQueueInfo->pu8Head;
2609     }
2610     PTH_RET_CHK(pthread_cond_signal(&pQueueInfo->SendSem));
2611     return TRUE;
2612 }
2613 
2614 //-------------------------------------------------------------------------------------------------
2615 /// Receive a message from the specified queue
2616 /// @param  s32QueueId      \b IN: Queue ID
2617 /// @param  pu8Message      \b OUT: msg destination
2618 /// @param  u32IntendedSize \b IN: intended msg size (byte unit) to receive:
2619 /// @param  pu32ActualSize  \b OUT: actual msg size (byte unit) received
2620 /// @param  u32WaitMs       \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the queue is empty
2621 /// @return TRUE : succeed
2622 /// @return FALSE :  fail
2623 //-------------------------------------------------------------------------------------------------
2624 MS_BOOL MsOS_RecvFromQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32IntendedSize, MS_U32 *pu32ActualSize, MS_U32 u32WaitMs)
2625 {
2626     MsOS_Queue_Info* pQueueInfo= NULL;
2627 
2628     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2629     {
2630         return FALSE;
2631     }
2632     else
2633     {
2634         s32QueueId &= MSOS_ID_MASK;
2635     }
2636 
2637     pQueueInfo= &_MsOS_Queue_Info[s32QueueId];
2638 
2639     MS_ASSERT(ALIGN_4(u32IntendedSize)== pQueueInfo->u32AlignedMsgSize);
2640 
2641     if (0== _MsOS_QueueUsedSize(pQueueInfo))
2642     {
2643         if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
2644         {
2645             PTH_RET_CHK(pthread_cond_wait(&pQueueInfo->SendSem, &pQueueInfo->SendMutex));
2646         }
2647         else
2648         {
2649             struct timespec     StopTime;
2650 //            if (0== u32WaitMs)
2651 //            {
2652 //                u32WaitMs=          MSOS_TIME_MIN_WAIT_TV;
2653 //            }
2654             _TimeAbs(StopTime, u32WaitMs);
2655             if (PTH_RET_CHK(pthread_cond_timedwait(&pQueueInfo->SendSem, &pQueueInfo->SendMutex, &StopTime)))
2656             {
2657                 return FALSE;
2658             }
2659         }
2660     }
2661 
2662     memcpy(pu8Message, pQueueInfo->pu8Read, u32IntendedSize);
2663     pQueueInfo->pu8Read+= pQueueInfo->u32AlignedMsgSize;
2664     if (pQueueInfo->pu8Read>= pQueueInfo->pu8Tail)
2665     {
2666         pQueueInfo->pu8Read= pQueueInfo->pu8Head;
2667     }
2668     PTH_RET_CHK(pthread_cond_signal(&pQueueInfo->RecvSem));
2669     *pu32ActualSize = u32IntendedSize;
2670 
2671     return TRUE;
2672 }
2673 
2674 //-------------------------------------------------------------------------------------------------
2675 /// Receive a message from the specified queue
2676 /// @param  s32QueueId      \b IN: Queue ID
2677 /// @param  pu8Message      \b OUT: msg destination
2678 /// @param  u32IntendedSize \b IN: intended msg size (byte unit) to receive:
2679 /// @param  pu32ActualSize  \b OUT: actual msg size (byte unit) received
2680 /// @return TRUE : succeed
2681 /// @return FALSE :  fail
2682 //-------------------------------------------------------------------------------------------------
2683 MS_BOOL MsOS_PeekFromQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32IntendedSize, MS_U32 *pu32ActualSize)
2684 {
2685     MsOS_Queue_Info* pQueueInfo= NULL;
2686 
2687     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2688     {
2689         return FALSE;
2690     }
2691     else
2692     {
2693         s32QueueId &= MSOS_ID_MASK;
2694     }
2695 
2696     pQueueInfo= &_MsOS_Queue_Info[s32QueueId];
2697 
2698     MS_ASSERT(ALIGN_4(u32IntendedSize)== pQueueInfo->u32AlignedMsgSize);
2699 
2700     if (0== _MsOS_QueueUsedSize(pQueueInfo))
2701     {
2702         return FALSE;
2703     }
2704     memcpy(pu8Message, pQueueInfo->pu8Read, u32IntendedSize);
2705     *pu32ActualSize = u32IntendedSize;
2706     return TRUE;
2707 }
2708 #endif
2709 
2710 
2711 //
2712 // Interrupt management
2713 //
2714 //-------------------------------------------------------------------------------------------------
2715 /// Attach the interrupt callback function to interrupt #
2716 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
2717 /// @param  pIntCb  \b IN: Interrupt callback function
2718 /// @return TRUE : succeed
2719 /// @return FALSE :  fail
2720 //-------------------------------------------------------------------------------------------------
MsOS_AttachInterrupt(InterruptNum eIntNum,InterruptCb pIntCb)2721 MS_BOOL MsOS_AttachInterrupt (InterruptNum eIntNum, InterruptCb pIntCb)
2722 {
2723     HAL_IRQ_Attach(eIntNum, pIntCb,IRQF_ONESHOT);
2724     return TRUE;
2725 }
2726 
2727 
MsOS_AttachInterrupt_Shared(InterruptNum eIntNum,InterruptCb pIntCb)2728 MS_BOOL MsOS_AttachInterrupt_Shared (InterruptNum eIntNum, InterruptCb pIntCb)
2729 {
2730     HAL_IRQ_Attach(eIntNum, pIntCb,IRQF_SHARED);
2731     return TRUE;
2732 }
2733 
2734 
2735 //-------------------------------------------------------------------------------------------------
2736 /// Detach the interrupt callback function from interrupt #
2737 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
2738 /// @return TRUE : succeed
2739 /// @return FALSE :  fail
2740 //-------------------------------------------------------------------------------------------------
MsOS_DetachInterrupt(InterruptNum eIntNum)2741 MS_BOOL MsOS_DetachInterrupt (InterruptNum eIntNum)
2742 {
2743     HAL_IRQ_Detech((int)eIntNum);
2744     return TRUE;
2745 }
2746 
2747 //-------------------------------------------------------------------------------------------------
2748 /// Enable (unmask) the interrupt #
2749 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
2750 /// @return TRUE : succeed
2751 /// @return FALSE :  fail
2752 //-------------------------------------------------------------------------------------------------
MsOS_EnableInterrupt(InterruptNum eIntNum)2753 MS_BOOL MsOS_EnableInterrupt (InterruptNum eIntNum)
2754 {
2755     return CHIP_EnableIRQ((int)eIntNum);
2756 }
2757 
2758 //-------------------------------------------------------------------------------------------------
2759 /// Disable (mask) the interrupt #
2760 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
2761 /// @return TRUE : succeed
2762 //-------------------------------------------------------------------------------------------------
MsOS_DisableInterrupt(InterruptNum eIntNum)2763 MS_BOOL MsOS_DisableInterrupt (InterruptNum eIntNum)
2764 {
2765     return CHIP_DisableIRQ(eIntNum);
2766 }
2767 
2768 //-------------------------------------------------------------------------------------------------
2769 /// Disable all interrupts (including timer interrupt), the scheduler is disabled.
2770 /// @return Interrupt register value before all interrupts disable
2771 //-------------------------------------------------------------------------------------------------
MsOS_DisableAllInterrupts(void)2772 MS_U32 MsOS_DisableAllInterrupts(void)
2773 {
2774 #if 0
2775     return CHIP_DisableAllInterrupt() ;
2776 #else
2777     return 0;
2778 #endif
2779 }
2780 
2781 //-------------------------------------------------------------------------------------------------
2782 /// Restore the interrupts from last MsOS_DisableAllInterrupts.
2783 /// @param  u32OldInterrupts \b IN: Interrupt register value from @ref MsOS_DisableAllInterrupts
2784 /// @return TRUE : succeed
2785 //-------------------------------------------------------------------------------------------------
MsOS_RestoreAllInterrupts(MS_U32 u32OldInterrupts)2786 MS_BOOL MsOS_RestoreAllInterrupts(MS_U32 u32OldInterrupts)
2787 {
2788     return TRUE;
2789 }
2790 //-------------------------------------------------------------------------------------------------
2791 /// Enable all CPU interrupts.
2792 /// @return TRUE : succeed
2793 //-------------------------------------------------------------------------------------------------
MsOS_EnableAllInterrupts(void)2794 MS_BOOL MsOS_EnableAllInterrupts(void)
2795 {
2796 #if 0
2797     return CHIP_EnableAllInterrupt() ;
2798 #else
2799     return TRUE;
2800 #endif
2801 }
2802 
2803 //-------------------------------------------------------------------------------------------------
2804 /// In Interuupt Context or not
2805 /// @return TRUE : Yes
2806 /// @return FALSE : No
2807 //-------------------------------------------------------------------------------------------------
MsOS_In_Interrupt(void)2808 MS_BOOL MsOS_In_Interrupt (void)
2809 {
2810 #if 0
2811     return CHIP_InISRContext();
2812 #else
2813     return FALSE;
2814 #endif
2815 }
2816 
2817 //-------------------------------------------------------------------------------------------------
2818 /// Write back if dirty & Invalidate the cache lines in the given range
2819 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
2820 /// @param  u32Size  \b IN: size (must be 16-B aligned)
2821 /// @return TRUE : succeed
2822 /// @return FALSE : fail due to invalide parameter
2823 //-------------------------------------------------------------------------------------------------
MsOS_Dcache_Flush(MS_VIRT ptrStart,MS_SIZE tSize)2824 MS_BOOL MsOS_Dcache_Flush( MS_VIRT ptrStart, MS_SIZE tSize )
2825 {
2826     return MsOS_MPool_Dcache_Flush(ptrStart, tSize);
2827 }
2828 
2829 //-------------------------------------------------------------------------------------------------
2830 /// Write back if dirty & Invalidate the cache lines for all.
2831 /// @return TRUE : succeed
2832 /// @return FALSE : fail due to invalide parameter
2833 //-------------------------------------------------------------------------------------------------
MsOS_Dcache_Flush_All(void)2834 MS_BOOL MsOS_Dcache_Flush_All(void)
2835 {
2836     return MsOS_MPool_Dcache_Flush_All();
2837 }
2838 
2839 //-------------------------------------------------------------------------------------------------
2840 /// Invalidate the cache lines in the given range
2841 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
2842 /// @param  u32Size  \b IN: size (must be 16-B aligned)
2843 /// @return TRUE : succeed
2844 /// @return FALSE : fail due to invalide parameter
2845 //-------------------------------------------------------------------------------------------------
MsOS_Dcache_Invalidate(MS_VIRT ptrStart,MS_SIZE tSize)2846 MS_BOOL MsOS_Dcache_Invalidate( MS_VIRT ptrStart , MS_SIZE tSize )
2847 {
2848 #if 0
2849     Chip_Inv_Cache_Range(ptrStart, tSize);
2850     return TRUE;
2851 #else
2852     return FALSE;
2853 #endif
2854 }
2855 
2856 //-------------------------------------------------------------------------------------------------
2857 /// Write back if dirty the cache lines in the given range
2858 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
2859 /// @param  u32Size  \b IN: size (must be 16-B aligned)
2860 /// @return TRUE : succeed
2861 /// @return FALSE : fail due to invalide parameter
2862 //-------------------------------------------------------------------------------------------------
MsOS_Dcache_Writeback(MS_VIRT ptrStart,MS_SIZE tSize)2863 MS_BOOL MsOS_Dcache_Writeback( MS_VIRT ptrStart , MS_SIZE tSize )
2864 {
2865 #if 0
2866     Chip_Clean_Cache_Range(u32Start, u32Size);
2867     return TRUE;
2868 #else
2869     return FALSE;
2870 #endif
2871 }
2872 
MsOS_VA2PA(MS_VIRT addr)2873 MS_PHY MsOS_VA2PA(MS_VIRT addr)
2874 {
2875     return MsOS_MPool_VA2PA(addr);
2876 }
2877 
MsOS_PA2KSEG0(MS_PHY addr)2878 MS_VIRT MsOS_PA2KSEG0(MS_PHY addr)
2879 {
2880     return MsOS_MPool_PA2KSEG0(addr);
2881 }
2882 
MsOS_PA2KSEG1(MS_PHY addr)2883 MS_VIRT MsOS_PA2KSEG1(MS_PHY addr)
2884 {
2885     return MsOS_MPool_PA2KSEG1(addr);
2886 }
2887 
2888 // Share memory operation
2889 static int _shm_init = -1;
2890 
MsOS_SHM_Init(void)2891 MS_BOOL MsOS_SHM_Init(void)
2892 {
2893     SHM_MUTEX_LOCK();
2894 
2895     if (-1 != _shm_init)
2896     {
2897         return TRUE;
2898     }
2899 
2900 	memset(&g_shm_array, 0, sizeof(g_shm_array));
2901     //Init First data as default.
2902     strcpy(g_shm_array.shm_entry[0].name, "DEFAULT_NULL");
2903     g_shm_array.shm_entry[0].addr = NULL;
2904     g_shm_array.shm_entry[0].size = 0;
2905     g_shm_array.count = 1;
2906 
2907     _shm_init = 1;
2908 
2909     SHM_MUTEX_UNLOCK();
2910 
2911     return TRUE;
2912 }
2913 
2914 char tmp[2][850*1024];
2915 int tmp_cnt=0;
2916 // Share memory operation
MsOS_SHM_GetId(MS_U8 * pu8ClientName,MS_U32 u32BufSize,MS_U32 * pu32ShmId,MS_VIRT * pu32Addr,MS_U32 * pu32BufSize,MS_U32 u32Flag)2917 MS_BOOL MsOS_SHM_GetId(MS_U8* pu8ClientName, MS_U32 u32BufSize, MS_U32* pu32ShmId, MS_VIRT* pu32Addr, MS_U32* pu32BufSize, MS_U32 u32Flag)
2918 {
2919 	int i, match = FALSE, result = FALSE;
2920 
2921     SHM_MUTEX_LOCK();
2922 
2923     if (-1 == _shm_init)
2924     {
2925         printk("[%s][%d] SHM Array was not initial!\n", __FUNCTION__, __LINE__);
2926         SHM_MUTEX_UNLOCK();
2927         return result;
2928     }
2929 
2930 	// search matching entry
2931 	for (i = 0; i < g_shm_array.count; i++)
2932 	{
2933 		if (0 == strcmp(g_shm_array.shm_entry[i].name, (char*)pu8ClientName))
2934 		{
2935 			match = TRUE;
2936 			break;
2937 		}
2938 	}
2939 
2940 	if (match) {
2941 		// if match, fill info
2942 		*pu32ShmId = i;
2943 		*pu32Addr = (MS_VIRT)(g_shm_array.shm_entry[i].addr);
2944 		*pu32BufSize = g_shm_array.shm_entry[i].size;
2945 		result = TRUE;
2946 	} else if (u32Flag == MSOS_SHM_CREATE) {
2947 		// if not match & specify to create one, register to g_shm_array
2948 		*pu32ShmId = g_shm_array.count;
2949         if(u32BufSize > 700*1024)
2950         {
2951             *pu32Addr = tmp[tmp_cnt];
2952             tmp_cnt++;
2953             if(tmp_cnt>=3)printk("ERROR: patch size not enough, please find me %s %d\n",__FUNCTION__,__LINE__);
2954             else printk("Please ask jway to fix me\n");
2955             memset((void*)*pu32Addr, 0,850*1024);
2956         }else
2957         {
2958             *pu32Addr = (MS_VIRT)kmalloc(u32BufSize, GFP_ATOMIC);
2959             if(NULL == *pu32Addr)
2960             {
2961                 SHM_MUTEX_UNLOCK();
2962                 return result;
2963             }
2964             memset((void*)*pu32Addr, 0, u32BufSize);
2965         }
2966 
2967 		*pu32BufSize = u32BufSize;
2968 		// this would cause bug, because string source may be "stack variable"
2969 		//g_shm_array.shm_entry[g_shm_array.count].name = (char*)pu8ClientName;
2970 		strcpy(g_shm_array.shm_entry[g_shm_array.count].name, (char*)pu8ClientName);
2971 		g_shm_array.shm_entry[g_shm_array.count].addr = (void*)*pu32Addr;
2972 		g_shm_array.shm_entry[g_shm_array.count].size = *pu32BufSize;
2973 		g_shm_array.count++;
2974 		result = TRUE;
2975 	}
2976     SHM_MUTEX_UNLOCK();
2977 
2978 	return result;
2979 }
2980 
MsOS_SHM_FreeId(MS_U8 * pu8ClientName,MS_U32 u32ShmId)2981 MS_BOOL MsOS_SHM_FreeId(MS_U8* pu8ClientName, MS_U32 u32ShmId)
2982 {
2983     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
2984     return FALSE;
2985 }
2986 
2987 //-------------------------------------------------------------------------------------------------
2988 /// Disable the CPU interrupt
2989 /// @return Interrupt register value before all interrupts disable
2990 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DisableInterrupt(void)2991 MS_U32 MsOS_CPU_DisableInterrupt (void)
2992 {
2993     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
2994     return FALSE;
2995 }
2996 
2997 //-------------------------------------------------------------------------------------------------
2998 /// Enable the CPU interrupt
2999 /// @return TRUE : succeed
3000 //-------------------------------------------------------------------------------------------------
MsOS_CPU_EnableInterrupt(void)3001 MS_BOOL MsOS_CPU_EnableInterrupt (void)
3002 {
3003     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3004     return FALSE;
3005 }
3006 
3007 //-------------------------------------------------------------------------------------------------
3008 /// Restore the CPU interrupt from last MsOS_CPU_DisableInterrupts.
3009 /// @param  u32OldInterrupts \b IN: Interrupt register value from @ref MsOS_CPU_DisableInterrupts
3010 /// @return TRUE : succeed
3011 //-------------------------------------------------------------------------------------------------
MsOS_CPU_RestoreInterrupt(MS_U32 u32OldInterrupts)3012 MS_BOOL MsOS_CPU_RestoreInterrupt (MS_U32 u32OldInterrupts)
3013 {
3014     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3015     return FALSE;
3016 }
3017 
3018 //-------------------------------------------------------------------------------------------------
3019 /// Mask all the CPU interrupt
3020 /// @return TRUE : succeed
3021 //-------------------------------------------------------------------------------------------------
MsOS_CPU_MaskAllInterrupt(void)3022 MS_BOOL MsOS_CPU_MaskAllInterrupt (void)
3023 {
3024     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3025     return FALSE;
3026 }
3027 
3028 //-------------------------------------------------------------------------------------------------
3029 /// Mask the CPU interrupt
3030 /// @param  intr_num \b IN: Interrupt number in enumerator MHAL_INTERRUPT_TYPE
3031 /// @return TRUE : succeed
3032 //-------------------------------------------------------------------------------------------------
MsOS_CPU_MaskInterrupt(MHAL_INTERRUPT_TYPE intr_num)3033 MS_BOOL MsOS_CPU_MaskInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3034 {
3035     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3036     return FALSE;
3037 }
3038 
3039 //-------------------------------------------------------------------------------------------------
3040 /// UnMask the CPU interrupt
3041 /// @param  intr_num \b IN: Interrupt number in enumerator MHAL_INTERRUPT_TYPE
3042 /// @return TRUE : succeed
3043 //-------------------------------------------------------------------------------------------------
MsOS_CPU_UnMaskInterrupt(MHAL_INTERRUPT_TYPE intr_num)3044 MS_BOOL MsOS_CPU_UnMaskInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3045 {
3046     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3047     return FALSE;
3048 }
3049 
3050 //-------------------------------------------------------------------------------------------------
3051 /// Lock the CPU interrupt
3052 /// @return TRUE : succeed
3053 //-------------------------------------------------------------------------------------------------
MsOS_CPU_LockInterrupt(void)3054 MS_BOOL MsOS_CPU_LockInterrupt (void)
3055 {
3056     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3057     return FALSE;
3058 }
3059 
3060 //-------------------------------------------------------------------------------------------------
3061 /// UnLock the CPU interrupt
3062 /// @return TRUE : succeed
3063 //-------------------------------------------------------------------------------------------------
MsOS_CPU_UnLockInterrupt(void)3064 MS_BOOL MsOS_CPU_UnLockInterrupt (void)
3065 {
3066     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3067     return FALSE;
3068 }
3069 
3070 //-------------------------------------------------------------------------------------------------
3071 /// Attach the CPU interrupt callback function to interrupt #
3072 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3073 /// @param  pIntCb  \b IN: Interrupt callback function
3074 /// @param  dat  \b IN: Data
3075 /// @return TRUE : succeed
3076 //-------------------------------------------------------------------------------------------------
MsOS_CPU_AttachInterrupt(MHAL_INTERRUPT_TYPE intr_num,mhal_isr_t isr,MS_U32 dat)3077 MS_BOOL MsOS_CPU_AttachInterrupt (MHAL_INTERRUPT_TYPE intr_num, mhal_isr_t isr, MS_U32 dat)
3078 {
3079     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3080     return FALSE;
3081 }
3082 
3083 //-------------------------------------------------------------------------------------------------
3084 /// Detach the CPU interrupt callback function to interrupt #
3085 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3086 /// @param  pIntCb  \b IN: Interrupt callback function
3087 /// @param  dat  \b IN: Data
3088 /// @return TRUE : succeed
3089 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DetachInterrupt(MHAL_INTERRUPT_TYPE intr_num)3090 MS_BOOL MsOS_CPU_DetachInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3091 {
3092     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3093     return FALSE;
3094 }
3095 
3096 //-------------------------------------------------------------------------------------------------
3097 /// Attach the CPU exception callback function to interrupt #
3098 /// @param  eIntNum \b IN: Exception number in enumerator InterruptNum
3099 /// @param  pIntCb  \b IN: Exception callback function
3100 /// @param  dat  \b IN: Data
3101 /// @return TRUE : succeed
3102 //-------------------------------------------------------------------------------------------------
MsOS_CPU_AttachException(MHAL_EXCEPTION_TYPE expt_num,mhal_isr_t isr,MS_U32 dat)3103 MS_BOOL MsOS_CPU_AttachException (MHAL_EXCEPTION_TYPE expt_num, mhal_isr_t isr, MS_U32 dat)
3104 {
3105     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3106     return FALSE;
3107 }
3108 
3109 //-------------------------------------------------------------------------------------------------
3110 /// Detach the CPU exception callback function to interrupt #
3111 /// @param  eIntNum \b IN: Exception number in enumerator InterruptNum
3112 /// @param  pIntCb  \b IN: Exception callback function
3113 /// @param  dat  \b IN: Data
3114 /// @return TRUE : succeed
3115 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DetachExceptiont(MHAL_EXCEPTION_TYPE expt_num)3116 MS_BOOL MsOS_CPU_DetachExceptiont (MHAL_EXCEPTION_TYPE expt_num)
3117 {
3118     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3119     return FALSE;
3120 }
3121 //-------------------------------------------------------------------------------------------------
3122 /// Set EBASE
3123 /// @param  u32Addr \b IN: MIPS Code Start Address
3124 /// @return TRUE : succeed
3125 //-------------------------------------------------------------------------------------------------
MsOS_CPU_SetEBASE(MS_U32 u32Addr)3126 MS_BOOL MsOS_CPU_SetEBASE (MS_U32 u32Addr)
3127 {
3128     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3129     return FALSE;
3130 }
3131 
3132 //-------------------------------------------------------------------------------------------------
3133 /// Sync data in EC-Brigde
3134 /// @return TRUE : succeed
3135 /// @return FALSE : fail
3136 //-------------------------------------------------------------------------------------------------
3137 
MsOS_Sync(void)3138 void MsOS_Sync(void)
3139 {//not support in current stage.
3140     printk("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3141 }
3142 
MsOS_FlushMemory(void)3143 void MsOS_FlushMemory(void)
3144 {
3145     Chip_Flush_Memory(); // Refine for CDI Report issues
3146 }
3147 
MsOS_ReadMemory(void)3148 void MsOS_ReadMemory(void)
3149 {
3150     Chip_Read_Memory();  // Refine for CDI Report issues
3151 }
3152 
3153 #endif
3154