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