xref: /utopia/UTPA2-700.0.x/modules/msos/msos/ecos/MsOS_ecos.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file    MsOS.c
98 /// @brief  MStar OS Wrapper
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101 
102 #if defined (MSOS_TYPE_ECOS)
103 
104 #include "cyg/kernel/kapi.h"
105 #include "cyg/hal/hal_arch.h"
106 #include "cyg/hal/hal_diag.h"
107 //POSIX API
108 //#include <fcntl.h>
109 //#include <mqueue.h>
110 
111 //-------------------------------------------------------------------------------------------------
112 // Include Files
113 //-------------------------------------------------------------------------------------------------
114 
115 #include "MsCommon.h"
116 #include "MsOS.h"
117 #include "asmCPU.h"
118 #include "regCHIP.h"
119 #include "halCHIP.h"
120 #include "halMMIO.h"
121 #include "MsVersion.h"
122 #include "utopia.h"
123 
124 //-------------------------------------------------------------------------------------------------
125 // Local Defines
126 //------------------------------------------------------------------------------------------------
127 // Switch tasks every 1 ms.
128 #define TASK_TIME_SLICE             (TICK_PER_ONE_MS)
129 #define DCACHE_LINE_SIZE 16
130 
131 // Combine 3-B prefix with s32ID = MSOS_ID_PREFIX | s32Id
132 //  to avoid the kernel object being used before initialzed.
133 #define MSOS_ID_PREFIX              0x76540000
134 #define MSOS_ID_PREFIX_MASK         0xFFFF0000
135 #define MSOS_ID_MASK                0x0000FFFF //~MSOS_ID_PREFIX_MASK
136 
137 #if (defined(CHIP_T3) || defined(CHIP_T4) || defined(CHIP_T7) || defined(CHIP_T9) || defined(CHIP_U4) || defined(CHIP_T13) || defined(CHIP_A1) || defined(CHIP_A6) || defined(CHIP_A7) || defined(CHIP_AMETHYST) || defined(CHIP_EMERALD) || defined(CHIP_NUGGET) || defined(CHIP_NIKON))
138 #define MIU1_CACHEABLE_START        0xC0000000
139 #define MIU1_CACHEABLE_END          0xD0000000
140 #define MIU1_UNCACHEABLE_START      0xD0000000
141 #define MIU1_UNCACHEABLE_END        0xE0000000
142 #elif defined(CHIP_K2)
143 #define MIU1_CACHEABLE_START        0x00000000
144 #define MIU1_CACHEABLE_END          0x10000000
145 #define MIU1_UNCACHEABLE_START      0x10000000
146 #define MIU1_UNCACHEABLE_END        0x20000000
147 #elif defined(CHIP_KAISER)
148 #define MIU1_CACHEABLE_START        0x60000000
149 #define MIU1_CACHEABLE_END          0x50000000
150 #define MIU1_UNCACHEABLE_START      0x60000000
151 #define MIU1_UNCACHEABLE_END        0x80000000
152 #endif
153 
154 #if (defined(CHIP_K6)||defined(CHIP_K6LITE)||defined(CHIP_K7U)||defined(CHIP_KANO))
155 //cached/unchched segment
156 #define KSEG0_BASE              ((void *)0x00000000)
157 #define KSEG1_BASE              ((void *)0x20000000)
158 #define KSEG0_SIZE              0x20000000
159 #define KSEG1_SIZE              0x20000000
160 
161 //cached addr <-> unchched addr
162 #define KSEG02KSEG1(addr)       ((void *)((MS_U32)(addr)|0x20000000))  //cached -> unchched
163 #define KSEG12KSEG0(addr)       ((void *)((MS_U32)(addr)&~0x20000000)) //unchched -> cached
164 
165 //virtual addr <-> physical addr
166 #define VA2PA(addr)             ((void *)(((MS_U32)addr) & 0x1fffffff)) //virtual -> physical
167 #define PA2KSEG0(addr)          ((void *)(((MS_U32)addr) | 0x00000000)) //physical -> cached
168 #define PA2KSEG1(addr)          ((void *)(((MS_U32)addr) | 0x20000000)) //physical -> unchched
169 #else
170 //cached/unchched segment
171 #define KSEG0_BASE              ((void *)0x80000000)
172 #define KSEG1_BASE              ((void *)0xa0000000)
173 #define KSEG0_SIZE              0x20000000
174 #define KSEG1_SIZE              0x20000000
175 
176 //cached addr <-> unchched addr
177 #define KSEG02KSEG1(addr)       ((void *)((MS_U32)(addr)|0x20000000))  //cached -> unchched
178 #define KSEG12KSEG0(addr)       ((void *)((MS_U32)(addr)&~0x20000000)) //unchched -> cached
179 
180 //virtual addr <-> physical addr
181 #define VA2PA(addr)             ((void *)(((MS_U32)addr) & 0x1fffffff)) //virtual -> physical
182 #define PA2KSEG0(addr)          ((void *)(((MS_U32)addr) | 0x80000000)) //physical -> cached
183 #define PA2KSEG1(addr)          ((void *)(((MS_U32)addr) | 0xa0000000)) //physical -> unchched
184 
185 #endif
186 //MS_U32<->MS_U16
187 #define LOU16(u32Val)           ( (MS_U16)(u32Val) )
188 #define HIU16(u32Val)           ( (MS_U16)((u32Val) >> 16) )
189 #define CATU32(u16HiVal, u16LoVal)  ( (MS_U32)(u16HiVal)<<16 | (MS_U32)(u16LoVal) )
190 
191 //MS_U16<->MS_U8
192 #define LOU8(u16Val)            ( (MS_U8)(u16Val) )
193 #define HIU8(u16Val)            ( (MS_U8)((u16Val) >> 8) )
194 
195 //-------------------------------------------------------------------------------------------------
196 // Macros
197 //-------------------------------------------------------------------------------------------------
198 #define PRINT_DEBUG_INFO    0
199 #if PRINT_DEBUG_INFO
200 #define PRINT_INFO(fmt, args...)  printf("[Utopia Info]" fmt, ## args)
201 #else
202 #define PRINT_INFO(fmt, args...)
203 #endif
204 
205 
206 //-------------------------------------------------------------------------------------------------
207 // Global Variables
208 //-------------------------------------------------------------------------------------------------
209 
210 
211 //-------------------------------------------------------------------------------------------------
212 // Local Variables
213 //-------------------------------------------------------------------------------------------------
214 //
215 // Variable-size Memory pool
216 //
217 typedef struct
218 {
219     MS_BOOL                         bUsed;
220     cyg_handle_t                    stMemoryPool;
221     cyg_mempool_var                 stMemoryPoolInfo;
222 } MsOS_MemoryPool_Info;
223 
224 static MsOS_MemoryPool_Info         _MsOS_MemoryPool_Info[MSOS_MEMPOOL_MAX];
225 static cyg_mutex_t                  _MsOS_MemoryPool_Mutex;
226 
227 //
228 // Fixed-size Memory pool
229 //
230 typedef struct
231 {
232     MS_BOOL                         bUsed;
233     cyg_handle_t                    stMemoryPool;
234     cyg_mempool_fix                 stMemoryPoolInfo;
235 } MsOS_FixSizeMemoryPool_Info;
236 
237 static MsOS_FixSizeMemoryPool_Info  _MsOS_FixSizeMemoryPool_Info[MSOS_FIXSIZE_MEMPOOL_MAX];
238 static cyg_mutex_t                  _MsOS_FixSizeMemoryPool_Mutex;
239 
240 //
241 // Task Management
242 //
243 typedef struct
244 {
245     MS_BOOL                         bUsed;
246     cyg_handle_t                    stTask;
247     cyg_thread                      stThreadInfo;
248     void *                          pStackBase;
249     cyg_addrword_t                  entry_data;
250     TaskEntry                       pTaskEntry;
251 } MsOS_Task_Info;
252 
253 static MsOS_Task_Info               _MsOS_Task_Info[MSOS_TASK_MAX];
254 static cyg_mutex_t                  _MsOS_Task_Mutex;
255 
256 //
257 // Mutex
258 //
259 typedef struct
260 {
261     MS_BOOL                         bUsed;
262     cyg_mutex_t                     stMutex;
263 } MsOS_Mutex_Info;
264 
265 static MsOS_Mutex_Info  _MsOS_Mutex_Info[MSOS_MUTEX_MAX];
266 static cyg_mutex_t  _MsOS_Mutex_Mutex;
267 
268 //
269 // Semaphore
270 //
271 typedef struct
272 {
273     MS_BOOL                         bUsed;
274     cyg_sem_t                       stSemaphore;
275 } MsOS_Semaphore_Info;
276 
277 static MsOS_Semaphore_Info          _MsOS_Semaphore_Info[MSOS_SEMAPHORE_MAX];
278 static cyg_mutex_t                  _MsOS_Semaphore_Mutex;
279 
280 //
281 // Event Group
282 //
283 typedef struct
284 {
285     MS_BOOL                         bUsed;
286     cyg_flag_t                      stEventGroup;
287 } MsOS_EventGroup_Info;
288 
289 static MsOS_EventGroup_Info         _MsOS_EventGroup_Info[MSOS_EVENTGROUP_MAX];
290 static cyg_mutex_t                  _MsOS_EventGroup_Mutex;
291 
292 //
293 // Queue
294 //
295 typedef struct
296 {
297     MS_BOOL                         bUsed;
298     cyg_handle_t                    stQueue;
299     cyg_mbox                        stQueueInfo;
300     cyg_mutex_t                     stMutex;
301     MS_U8                           *pu8MsgQueue;
302     MS_U32                          u32AlignedMsgSize;
303     MS_U32                          u32MsgWriteIdx;
304     MessageType                     eMsgType;
305 } MsOS_Queue_Info;
306 
307 static MsOS_Queue_Info              _MsOS_Queue_Info[MSOS_QUEUE_MAX];
308 static cyg_mutex_t                  _MsOS_Queue_Mutex;
309 
310 //
311 // Timer
312 //
313 typedef struct
314 {
315     MS_BOOL                         bUsed;
316     cyg_handle_t                    stTimer; //alarm handler
317     cyg_alarm                       stAlarm; //alarm object
318 } MsOS_Timer_Info;
319 static MsOS_Timer_Info              _MsOS_Timer_Info[MSOS_TIMER_MAX];
320 static cyg_mutex_t                  _MsOS_Timer_Mutex;
321 static cyg_handle_t                 _stCounter; //counter handle
322 static cyg_handle_t                 _stSysClk;  //clock handle
323 
324 //
325 // Condition Variables
326 //
327 typedef struct
328 {
329     MS_BOOL                         bUsed;
330     cyg_cond_t                      stCond;
331 } MsOS_Condition_Info;
332 static MsOS_Condition_Info         _MsOS_Condition_Info[MSOS_CONDITION_MAX];
333 static cyg_mutex_t                  _MsOS_Condition_Mutex;
334 
335 //
336 // Interrupt
337 //
338 static cyg_mutex_t                  _MsOS_HISR_Mutex;
339 
340 //FIXME: It's better to be internal or have internal system pool for usage.
341 extern MS_S32 gs32SystemPoolID;
342 //extern MS_S32 gs32CachedPoolID;
343 //extern MS_S32 gs32NonCachedPoolID;
344 //extern MS_S32 gs32DisplayPoolID;
345 //extern MS_S32 gs32UserPoolID;                                              //[OPTIONAL]
346 //extern MS_S32 gs32RAMFSPoolID;                                             //[OPTIONAL]
347 
UTL_strcpy(char * strDst,const char * strSrc)348 char *UTL_strcpy(char *strDst, const char *strSrc)
349 {
350     int i;
351 
352     for(i=0;strSrc[i];i++)
353     {
354         strDst[i] = strSrc[i];
355     }
356     strDst[i] = '\0';
357     return strDst;
358 }
359 
_MsOS_eCosTaskWrapper(cyg_addrword_t data)360 void* _MsOS_eCosTaskWrapper (cyg_addrword_t data)
361 {
362     MsOS_Task_Info *taskinfo = NULL;
363     taskinfo = (MsOS_Task_Info *)data;
364     taskinfo->pTaskEntry((MS_U32)taskinfo->entry_data,(void *)NULL);
365     cyg_mutex_lock(&_MsOS_Task_Mutex);
366     taskinfo->bUsed = FALSE;
367     cyg_mutex_unlock(&_MsOS_Task_Mutex);
368     cyg_thread_exit();
369     return NULL;
370 }
371 
372 //-------------------------------------------------------------------------------------------------
373 // Local Function Prototypes
374 //-------------------------------------------------------------------------------------------------
375 
376 extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, unsigned long entryhi, unsigned long pagemask);
377 
378 static MSIF_Version _drv_msos_version = {
379     .DDI = { MSOS_DRV_VERSION },
380 };
381 ////////////////////////////////////////////////////////////////////////////////
382 /// @brief \b Function  \b Name: MDrv_MSOS_GetLibVer
383 /// @brief \b Function  \b Description: Show the MSOS driver version
384 /// @param ppVersion    \b Out: Library version string
385 /// @return             \b Result
386 ////////////////////////////////////////////////////////////////////////////////
MDrv_MSOS_GetLibVer(const MSIF_Version ** ppVersion)387 MS_BOOL MDrv_MSOS_GetLibVer(const MSIF_Version **ppVersion)
388 {
389     if (!ppVersion)
390         return FALSE;
391 
392     *ppVersion = &_drv_msos_version;
393     return TRUE;
394 }
395 
396 //-------------------------------------------------------------------------------------------------
397 /// Initialize MsOS
398 /// @return TRUE : succeed
399 /// @return FALSE : fail
400 //-------------------------------------------------------------------------------------------------
MsOS_Init(void)401 MS_BOOL MsOS_Init (void)
402 {
403     MS_U32 u32I;
404     static int bInit = 0;
405 
406     if (bInit == 0)
407 	    bInit = 1;
408     else
409         return TRUE;
410 
411     if (FALSE == MsOS_SHM_Init())
412     {
413         return FALSE;
414     }
415 
416     // Empty all the MsOS structures
417     for( u32I=0; u32I<MSOS_MEMPOOL_MAX; u32I++)
418     {
419         _MsOS_MemoryPool_Info[u32I].bUsed = FALSE;
420     }
421     for( u32I=0; u32I<MSOS_FIXSIZE_MEMPOOL_MAX; u32I++)
422     {
423         _MsOS_FixSizeMemoryPool_Info[u32I].bUsed = FALSE;
424     }
425     for( u32I=0; u32I<MSOS_TASK_MAX; u32I++)
426     {
427         _MsOS_Task_Info[u32I].bUsed = FALSE;
428     }
429     for( u32I=0; u32I<MSOS_MUTEX_MAX; u32I++)
430     {
431         _MsOS_Mutex_Info[u32I].bUsed = FALSE;
432     }
433     for( u32I=0; u32I<MSOS_SEMAPHORE_MAX; u32I++)
434     {
435         _MsOS_Semaphore_Info[u32I].bUsed = FALSE;
436     }
437     for( u32I=0; u32I<MSOS_EVENTGROUP_MAX; u32I++)
438     {
439         _MsOS_EventGroup_Info[u32I].bUsed = FALSE;
440     }
441     for( u32I=0; u32I<MSOS_TIMER_MAX; u32I++)
442     {
443         _MsOS_Timer_Info[u32I].bUsed = FALSE;
444     }
445     for( u32I=0; u32I<MSOS_CONDITION_MAX; u32I++)
446     {
447         _MsOS_Condition_Info[u32I].bUsed = FALSE;
448     }
449 
450     // Please update the HISR priority here if it is necessary.
451 
452     //For MsOS_CreateTimer
453     _stSysClk = cyg_real_time_clock();
454     cyg_clock_to_counter( _stSysClk, &_stCounter);
455 
456     // Create Semaphore for all resources.
457     cyg_mutex_init(&_MsOS_MemoryPool_Mutex);
458     cyg_mutex_init(&_MsOS_FixSizeMemoryPool_Mutex);
459     cyg_mutex_init(&_MsOS_Task_Mutex);
460     cyg_mutex_init(&_MsOS_Mutex_Mutex);
461     cyg_mutex_init(&_MsOS_Semaphore_Mutex);
462     cyg_mutex_init(&_MsOS_EventGroup_Mutex);
463     cyg_mutex_init(&_MsOS_Queue_Mutex);
464     cyg_mutex_init(&_MsOS_Timer_Mutex);
465     cyg_mutex_init(&_MsOS_Condition_Mutex);
466     cyg_mutex_init(&_MsOS_HISR_Mutex);
467 
468 #if(defined(MCU_MIPS_34K) || defined(MCU_MIPS_74K) || defined(MCU_MIPS_1004K))
469     #if (defined(CHIP_T12) || defined(CHIP_A2) || defined(CHIP_T8) || defined(CHIP_J2) || defined(CHIP_A5) || defined(CHIP_A5P) || defined(CHIP_A3) || defined(CHIP_EDISON) || defined(CHIP_EIFFEL) || defined(CHIP_NIKE) || defined(CHIP_MADISON) || defined(CHIP_NADAL) || defined(CHIP_MIAMI) || defined(CHIP_MUNICH))
470         // MIU0
471         unsigned long entrylo0 = ((0x10000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
472         unsigned long entrylo1 = ((0x10000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
473         // MIU1
474         unsigned long entrylo0_miu1_lo256mb = ((0x20000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
475         unsigned long entrylo1_miu1_lo256mb = ((0x20000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
476         unsigned long entrylo0_miu1_hi256mb = ((0x30000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
477         unsigned long entrylo1_miu1_hi256mb = ((0x30000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
478         // MIU0
479         add_wired_entry(entrylo0, entrylo1, 0xC0000000 , 0x1fffe000);  //  PageMask[28:13]=0x1fffe000(256MB max size)
480         // MIU1
481         add_wired_entry(entrylo0_miu1_lo256mb, entrylo1_miu1_lo256mb, 0x00000000 , 0x1fffe000);
482         add_wired_entry(entrylo0_miu1_hi256mb, entrylo1_miu1_hi256mb, 0x20000000 , 0x1fffe000);
483     #elif (defined(CHIP_KENYA))
484            MS_U32 entry = 0;
485            extern int read_tlb_entry_number(void);
486            // MIU0
487            unsigned long entrylo0 = ((0x50000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
488            unsigned long entrylo1 = ((0x50000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
489            // MIU1
490 //           unsigned long entrylo0_miu1_lo256mb = ((0x60000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
491 //           unsigned long entrylo1_miu1_lo256mb = ((0x60000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
492 //           unsigned long entrylo0_miu1_hi256mb = ((0x70000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
493 //           unsigned long entrylo1_miu1_hi256mb = ((0x70000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
494 
495            entry = read_tlb_entry_number();
496 
497            if(entry == 0)
498            {
499                // MIU0
500                add_wired_entry(entrylo0, entrylo1, 0xC0000000 , 0x1fffe000);  //  PageMask[28:13]=0x1fffe000(256MB max size)
501            }
502            else
503            {
504                printf("TLB had ready mapped. Not mapping again !!\n");
505            }
506      #elif (defined(CHIP_K2))
507         MS_U32 entry = 0;
508         extern int read_tlb_entry_number(void);
509         // MIU0
510         unsigned long entrylo0 = ((0x50000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
511         unsigned long entrylo1 = ((0x50000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
512         // MIU1
513         unsigned long entrylo0_miu1_lo256mb = ((0x60000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
514         unsigned long entrylo1_miu1_lo256mb = ((0x60000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
515         unsigned long entrylo0_miu1_hi256mb = ((0x70000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
516         unsigned long entrylo1_miu1_hi256mb = ((0x70000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
517 
518         entry = read_tlb_entry_number();
519 
520         if(entry == 0)
521         {
522             // MIU0
523             add_wired_entry(entrylo0, entrylo1, 0xC0000000 , 0x1fffe000);  //  PageMask[28:13]=0x1fffe000(256MB max size)
524             // MIU1
525             add_wired_entry(entrylo0_miu1_lo256mb, entrylo1_miu1_lo256mb, 0x00000000 , 0x1fffe000);
526             add_wired_entry(entrylo0_miu1_hi256mb, entrylo1_miu1_hi256mb, 0x20000000 , 0x1fffe000);
527         }
528         else
529         {
530             printf("TLB had ready mapped. Not mapping again !!\n");
531         }
532      #elif (defined(CHIP_U4))
533         unsigned long entrylo0 = ((0x40000000>> 12) << 6) | (0<<3) | (1<< 2) | (1<< 1) | (1<< 0); // cacheable
534         unsigned long entrylo1 = ((0x40000000>> 12) << 6) | (2<<3) | (1<< 2) | (1<< 1) | (1<< 0); // un-cacheable or 0x7
535         add_wired_entry(entrylo0, entrylo1, MIU1_CACHEABLE_START , 0x1fffe000);
536     #endif
537 #endif
538 
539     CHIP_InitISR();
540 
541     //can't enable INT till LISR/HISR has been registered/attached
542     MsOS_DisableInterrupt(E_INT_IRQ_FIQ_ALL);
543 
544 	UtopiaInit();
545 
546     return TRUE;
547 }
548 
549 
550 //
551 // Memory management
552 //
553 //-------------------------------------------------------------------------------------------------
554 /// Create a variable-size memory pool dynamically
555 /// @param  u32PoolSize         \b IN: pool size in bytes
556 /// @param  u32MinAllocation    \b IN: not used
557 /// @param  pPoolAddr           \b IN: starting address for the memory pool
558 /// @param  eAttribute          \b IN: only E_MSOS_FIFO - suspended in FIFO order
559 /// @param  pPoolName           \b IN: not used
560 /// @return >=0 : assigned memory pool ID
561 /// @return < 0 : fail
562 //-------------------------------------------------------------------------------------------------
MsOS_CreateMemoryPool(MS_U32 u32PoolSize,MS_U32 u32MinAllocation,void * pPoolAddr,MsOSAttribute eAttribute,char * pPoolName)563 MS_S32 MsOS_CreateMemoryPool (MS_U32        u32PoolSize,
564                               MS_U32        u32MinAllocation,
565                               void          *pPoolAddr,
566                               MsOSAttribute eAttribute,
567                               char          *pPoolName)
568 {
569     MS_S32 s32Id;
570 
571     cyg_mutex_lock(&_MsOS_MemoryPool_Mutex);
572 
573     for(s32Id=0;s32Id<MSOS_MEMPOOL_MAX;s32Id++)
574     {
575         if(_MsOS_MemoryPool_Info[s32Id].bUsed == FALSE)
576         {
577             break;
578         }
579     }
580     if(s32Id < MSOS_MEMPOOL_MAX)
581     {
582         _MsOS_MemoryPool_Info[s32Id].bUsed = TRUE;
583     }
584     cyg_mutex_unlock(&_MsOS_MemoryPool_Mutex);
585 
586     if(s32Id >= MSOS_MEMPOOL_MAX)
587     {
588         return -1;
589     }
590 
591     //no Priority order for eCos
592     //pPoolName is not used for eCos
593 
594     // Call OS kernel to create a memory pool.
595     cyg_mempool_var_create( pPoolAddr,
596                             u32PoolSize,
597                             &_MsOS_MemoryPool_Info[s32Id].stMemoryPool,
598                             &_MsOS_MemoryPool_Info[s32Id].stMemoryPoolInfo );
599 
600     s32Id |= MSOS_ID_PREFIX;
601     return s32Id;
602 }
603 
604 //-------------------------------------------------------------------------------------------------
605 /// Delete a variable-size memory pool
606 /// @param  s32PoolId   \b IN: pool ID
607 /// @return TRUE : succeed
608 /// @return FALSE : fail
609 //-------------------------------------------------------------------------------------------------
MsOS_DeleteMemoryPool(MS_S32 s32PoolId)610 MS_BOOL MsOS_DeleteMemoryPool (MS_S32 s32PoolId)
611 {
612     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
613     {
614         return FALSE;
615     }
616     else
617     {
618         s32PoolId &= MSOS_ID_MASK;
619     }
620 
621     cyg_mempool_var_delete(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool);
622     cyg_mutex_lock(&_MsOS_MemoryPool_Mutex);
623     _MsOS_MemoryPool_Info[s32PoolId].bUsed = FALSE;
624     cyg_mutex_unlock(&_MsOS_MemoryPool_Mutex);
625     return TRUE;
626 }
627 
628 //-------------------------------------------------------------------------------------------------
629 /// Get the information of a variable-size memory pool
630 /// @param  s32PoolId   \b IN: memory pool ID
631 /// @param  pPoolAddr   \b OUT: holding the starting address for the memory pool
632 /// @param  pu32PoolSize \b OUT: holding the total size of the memory pool
633 /// @param  pu32FreeSize \b OUT: holding the available free size of the memory pool
634 /// @param  pu32LargestFreeBlockSize  \b OUT: holding the size of the largest free block
635 /// @return TRUE : succeed
636 /// @return FALSE : the pool has not been created
637 //-------------------------------------------------------------------------------------------------
MsOS_InfoMemoryPool(MS_S32 s32PoolId,void ** pPoolAddr,MS_U32 * pu32PoolSize,MS_U32 * pu32FreeSize,MS_U32 * pu32LargestFreeBlockSize)638 MS_BOOL MsOS_InfoMemoryPool (MS_S32    s32PoolId,
639                           void      **pPoolAddr,
640                           MS_U32    *pu32PoolSize,
641                           MS_U32    *pu32FreeSize,
642                           MS_U32    *pu32LargestFreeBlockSize)
643 {
644     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
645     {
646         return FALSE;
647     }
648     else
649     {
650         s32PoolId &= MSOS_ID_MASK;
651     }
652 
653     cyg_mempool_info mempool_info;
654     cyg_mempool_var_get_info(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, &mempool_info);
655 
656     *pPoolAddr = mempool_info.base;
657     *pu32PoolSize = mempool_info.size;
658     *pu32FreeSize = mempool_info.freemem;
659     *pu32LargestFreeBlockSize = mempool_info.maxfree;
660 
661     return TRUE;
662 }
663 
664 //-------------------------------------------------------------------------------------------------
665 /// Allocate a memory block with 16-Byte aligned starting address from the variable-size memory pool
666 /// @param  u32Size     \b IN: request size
667 /// @param  s32PoolId   \b IN: memory pool ID
668 /// @return NULL : not enough available memory
669 /// @return Otherwise : pointer to the allocated memory block
670 //-------------------------------------------------------------------------------------------------
MsOS_AllocateMemory(MS_U32 u32Size,MS_S32 s32PoolId)671 void * MsOS_AllocateMemory (MS_U32 u32Size, MS_S32 s32PoolId)
672 {
673     void  *pAddr;
674 
675     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
676     {
677         return NULL;
678     }
679     else
680     {
681         s32PoolId &= MSOS_ID_MASK;
682     }
683 
684     // Jerry.Tsao: cyg_mempool_var_try_alloc allocates the maximum pool it has when size is zero.
685     if (u32Size == 0)
686     {
687         return NULL;
688     }
689 
690     pAddr = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32Size);
691 
692     //Current eCosPro kernel always allocates 16-B aligned block
693     if ( (MS_U32)pAddr % 16 )
694     {
695         return NULL;
696     }
697 
698     return ( pAddr );
699 }
700 
701 /*
702 //-------------------------------------------------------------------------------------------------
703 // Allocate a block of memory with aligned starting address from the variable-size memory pool
704 // @param  u32Size         \b IN: requested size
705 // @param  s32PoolId       \b IN: memory pool ID
706 // @param  u32AlignedByte  \b IN: #-byte aligned start address (must be a multiple of 4)
707 // @return NULL : fail
708 // @return Otherwise : pointer to the allocated memory block
709 //-------------------------------------------------------------------------------------------------
710 void * MsOS_AllocateAlignedMemory (MS_U32 u32Size, MS_U32 u32AlignedByte, MS_S32 s32PoolId)
711 {
712 #if 0
713     void *pAddr;
714 
715     if ( (u32AlignedByte % 4) != 0)
716     {
717         return NULL;
718     }
719     if( NU_Allocate_Aligned_Memory( &_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool,
720                                     &pAddr,
721                                     u32Size,
722                                     u32AlignedByte,
723                                     0) != NU_SUCCESS)
724     {
725         return NULL;
726     }
727     else
728     {
729         return pAddr;
730     }
731 #endif
732 
733     //eCos does not support aligned allocate
734     return NULL;
735 }
736 */
737 
738 //-------------------------------------------------------------------------------------------------
739 /// Free a memory block from the variable-size memory pool
740 /// @param  pAddress    \b IN: pointer to previously allocated memory block
741 /// @param  s32PoolId   \b IN: memory pool ID
742 /// @return TRUE : succeed
743 /// @return FALSE : fail
744 //-------------------------------------------------------------------------------------------------
MsOS_FreeMemory(void * pAddress,MS_S32 s32PoolId)745 MS_BOOL MsOS_FreeMemory (void *pAddress, MS_S32 s32PoolId)
746 {
747     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
748     {
749         return FALSE;
750     }
751     else
752     {
753         s32PoolId &= MSOS_ID_MASK;
754     }
755 
756     if (pAddress == NULL)
757     {
758         return FALSE;
759     }
760 
761     cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pAddress);
762 
763     return TRUE;
764 }
765 
766 //-------------------------------------------------------------------------------------------------
767 /// Reallocate a block of memory with 4-byte aligned start address from the variable-size memory pool
768 /// @param  pOrgAddress \b IN: points to the beginning of the original memory block
769 /// @param  u32NewSize  \b IN: size of new memory block
770 /// @param  s32PoolId   \b IN: memory pool ID
771 /// @return NULL : not enough available memory to expand the block or u32NewSize == 0 && pOrgAddress != NULL
772 /// @return Otherwise : pointer to the reallocated (and possibly moved) memory block
773 //  @note   reference realloc in malloc.cxx
774 //-------------------------------------------------------------------------------------------------
MsOS_ReallocateMemory(void * pOrgAddress,MS_U32 u32NewSize,MS_S32 s32PoolId)775 void * MsOS_ReallocateMemory (void *pOrgAddress, MS_U32 u32NewSize, MS_S32 s32PoolId)
776 {
777     void *pNewAddress = NULL;
778     MS_U32 u32OrgSize;
779 
780     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
781     {
782         return NULL;
783     }
784     else
785     {
786         s32PoolId &= MSOS_ID_MASK;
787     }
788 
789     if ( pOrgAddress == NULL)
790     {
791         //malloc
792         pNewAddress = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32NewSize);
793         return pNewAddress;
794     }
795 
796     if ( u32NewSize == 0)
797     {
798         //free
799         cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pOrgAddress);
800         return NULL;
801     }
802 
803     //mvarimpl.inl
804     struct memdq {
805         struct memdq *prev, *next;
806         cyg_int32 size;
807     };
808 
809     struct memdq *dq = (struct memdq *) ((MS_U32 )pOrgAddress  - sizeof(struct memdq));
810     u32OrgSize = dq->size - sizeof(struct memdq);   //dq->size was rounded up to 16B-aligned when malloc, so u32OrgSize may be larger than requested
811 
812     //No resize function is implemented, so malloc a new block directly
813     pNewAddress = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32NewSize);
814 
815     if ( pNewAddress != NULL) //move to a new block
816     {
817         if ( u32NewSize < u32OrgSize)
818         {
819             memcpy( pNewAddress, pOrgAddress, u32NewSize );
820         }
821         else
822         {
823             memcpy( pNewAddress, pOrgAddress, u32OrgSize );
824         }
825         cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pOrgAddress);
826 
827     }
828     else //not enough available memory to expand the block to the given size
829     {
830         //the original block is unchanged
831     }
832 
833     return pNewAddress;
834 
835 }
836 
837 //-------------------------------------------------------------------------------------------------
838 /// Create a fixed-size memory pool dynamically
839 /// @param  u32PoolSize         \b IN: pool size in bytes
840 /// @param  u32BlockSize        \b IN: fixed block size for each allocated block in the pool
841 /// @param  pPoolAddr           \b IN: starting address for the memory pool
842 /// @param  eAttribute          \b IN: only E_MSOS_FIFO - suspended in FIFO order
843 /// @param  pPoolName           \b IN: not used
844 /// @return >=0 : assigned memory pool ID
845 /// @return < 0 : fail
846 //-------------------------------------------------------------------------------------------------
MsOS_CreateFixSizeMemoryPool(MS_U32 u32PoolSize,MS_U32 u32BlockSize,void * pPoolAddr,MsOSAttribute eAttribute,char * pPoolName)847 MS_S32 MsOS_CreateFixSizeMemoryPool (MS_U32    u32PoolSize,
848                                   MS_U32    u32BlockSize,
849                                   void      *pPoolAddr,
850                                   MsOSAttribute eAttribute,
851                                   char      *pPoolName)
852 {
853     MS_S32 s32Id;
854 
855     cyg_mutex_lock(&_MsOS_FixSizeMemoryPool_Mutex);
856 
857     for( s32Id=0; s32Id<MSOS_FIXSIZE_MEMPOOL_MAX; s32Id++)
858     {
859         if(_MsOS_FixSizeMemoryPool_Info[s32Id].bUsed == FALSE)
860         {
861             break;
862         }
863     }
864     if(s32Id < MSOS_FIXSIZE_MEMPOOL_MAX)
865     {
866         _MsOS_FixSizeMemoryPool_Info[s32Id].bUsed = TRUE;
867     }
868     cyg_mutex_unlock(&_MsOS_FixSizeMemoryPool_Mutex);
869 
870     if(s32Id >= MSOS_FIXSIZE_MEMPOOL_MAX)
871     {
872         return -1;
873     }
874 
875     //no Priority order for eCos
876     //pPoolName is not used for eCos
877 
878     // Call OS kernel to create a memory pool.
879     cyg_mempool_fix_create( pPoolAddr,
880                             u32PoolSize,
881                             u32BlockSize,
882                             &_MsOS_FixSizeMemoryPool_Info[s32Id].stMemoryPool,
883                             &_MsOS_FixSizeMemoryPool_Info[s32Id].stMemoryPoolInfo );
884 
885     s32Id |= MSOS_ID_PREFIX;
886     return s32Id;
887 }
888 
889 //-------------------------------------------------------------------------------------------------
890 /// Delete a fixed-size memory pool
891 /// @param  s32PoolId   \b IN: pool ID
892 /// @return TRUE : succeed
893 /// @return FALSE : fail
894 //-------------------------------------------------------------------------------------------------
MsOS_DeleteFixSizeMemoryPool(MS_S32 s32PoolId)895 MS_BOOL MsOS_DeleteFixSizeMemoryPool (MS_S32 s32PoolId)
896 {
897     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
898     {
899         return FALSE;
900     }
901     else
902     {
903         s32PoolId &= MSOS_ID_MASK;
904     }
905 
906     cyg_mempool_fix_delete(_MsOS_FixSizeMemoryPool_Info[s32PoolId].stMemoryPool);
907     cyg_mutex_lock(&_MsOS_FixSizeMemoryPool_Mutex);
908     _MsOS_FixSizeMemoryPool_Info[s32PoolId].bUsed = FALSE;
909     cyg_mutex_unlock(&_MsOS_FixSizeMemoryPool_Mutex);
910 
911     return TRUE;
912 }
913 
914 //-------------------------------------------------------------------------------------------------
915 /// Get the information of a fixed-size memory pool
916 /// @param  s32PoolId   \b IN: memory pool ID
917 /// @param  pPoolAddr   \b OUT: holding the starting address for the memory pool
918 /// @param  pu32PoolSize \b OUT: holding the total size of the memory pool
919 /// @param  pu32FreeSize \b OUT: holding the available free size of the memory pool
920 /// @param  pu32LargestFreeBlockSize  \b OUT: holding the size of the largest free block
921 /// @return TRUE : succeed
922 /// @return FALSE : the pool has not been created
923 //-------------------------------------------------------------------------------------------------
MsOS_InfoFixSizeMemoryPool(MS_S32 s32PoolId,void ** pPoolAddr,MS_U32 * pu32PoolSize,MS_U32 * pu32FreeSize,MS_U32 * pu32LargestFreeBlockSize)924 MS_BOOL MsOS_InfoFixSizeMemoryPool (MS_S32 s32PoolId,
925                                  void   **pPoolAddr,
926                                  MS_U32 *pu32PoolSize,
927                                  MS_U32 *pu32FreeSize,
928                                  MS_U32 *pu32LargestFreeBlockSize)
929 {
930     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
931     {
932         return FALSE;
933     }
934     else
935     {
936         s32PoolId &= MSOS_ID_MASK;
937     }
938 
939     cyg_mempool_info mempool_info;
940     cyg_mempool_fix_get_info(_MsOS_FixSizeMemoryPool_Info[s32PoolId].stMemoryPool, &mempool_info);
941 
942     *pPoolAddr = mempool_info.base;
943     *pu32PoolSize = mempool_info.size;
944     *pu32FreeSize = mempool_info.freemem;
945     *pu32LargestFreeBlockSize = mempool_info.maxfree;
946 
947     return TRUE;
948 }
949 
950 //-------------------------------------------------------------------------------------------------
951 /// Allocate a memory block from the fixed-size memory pool
952 /// @param  s32PoolId   \b IN: memory pool ID
953 /// @return NULL : not enough available memory
954 /// @return Otherwise : pointer to the allocated memory block
955 /// @note   watch out for alignment if u32BlockSize is not a multiple of 4
956 //-------------------------------------------------------------------------------------------------
MsOS_AllocateFixSizeMemory(MS_S32 s32PoolId)957 void * MsOS_AllocateFixSizeMemory (MS_S32 s32PoolId)
958 {
959     void  *pAddr;
960 
961     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
962     {
963         return NULL;
964     }
965     else
966     {
967         s32PoolId &= MSOS_ID_MASK;
968     }
969 
970     pAddr = cyg_mempool_fix_try_alloc( _MsOS_FixSizeMemoryPool_Info[s32PoolId].stMemoryPool);
971 
972     return ( pAddr );
973 }
974 
975 //-------------------------------------------------------------------------------------------------
976 /// Free a memory block from the fixed-size memory pool
977 /// @param  pAddress    \b IN: pointer to previously allocated memory block
978 /// @param  s32PoolId   \b IN: memory pool ID
979 /// @return TRUE : succeed
980 /// @return FALSE : fail
981 //-------------------------------------------------------------------------------------------------
MsOS_FreeFixSizeMemory(void * pAddress,MS_S32 s32PoolId)982 MS_BOOL MsOS_FreeFixSizeMemory (void *pAddress, MS_S32 s32PoolId)
983 {
984     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
985     {
986         return FALSE;
987     }
988     else
989     {
990         s32PoolId &= MSOS_ID_MASK;
991     }
992 
993     if (pAddress == NULL)
994     {
995         return FALSE;
996     }
997 
998     cyg_mempool_fix_free( _MsOS_FixSizeMemoryPool_Info[s32PoolId].stMemoryPool, pAddress);
999 
1000     return TRUE;
1001 }
1002 
1003 
1004 //
1005 // Task
1006 //
1007 //-------------------------------------------------------------------------------------------------
1008 /// Create a task
1009 /// @param  pTaskEntry       \b IN: task entry point
1010 /// @param  u32TaskEntryData \b IN: task entry data: a pointer to some static data, or a
1011 ///          small integer, or NULL if the task does not require any additional data.
1012 /// @param  eTaskPriority    \b IN: task priority
1013 /// @param  bAutoStart       \b IN: start immediately or later
1014 /// @param  pStackBase       \b IN: task stack
1015 /// @param  u32StackSize     \b IN: stack size
1016 /// @param  pTaskName        \b IN: task name
1017 /// @return >=0 : assigned Task ID
1018 /// @return < 0 : fail
1019 //-------------------------------------------------------------------------------------------------
MsOS_CreateTask(TaskEntry pTaskEntry,MS_U32 u32TaskEntryData,TaskPriority eTaskPriority,MS_BOOL bAutoStart,void * pStackBase,MS_U32 u32StackSize,char * pTaskName)1020 MS_S32 MsOS_CreateTask (TaskEntry  pTaskEntry,
1021                      MS_U32     u32TaskEntryData,
1022                      TaskPriority eTaskPriority,
1023                      MS_BOOL    bAutoStart,
1024                      void       *pStackBase,
1025                      MS_U32     u32StackSize,
1026                      char       *pTaskName)
1027 {
1028     MS_S32 s32Id;
1029 
1030     // Check parameters
1031     if ( ((MS_U32)pStackBase % 4) || (u32StackSize < CYGNUM_HAL_STACK_SIZE_MINIMUM) )
1032     {
1033         return -1;
1034     }
1035 
1036     cyg_mutex_lock(&_MsOS_Task_Mutex);
1037     for( s32Id=0; s32Id<MSOS_TASK_MAX; s32Id++)
1038     {
1039         if(_MsOS_Task_Info[s32Id].bUsed == FALSE)
1040         {
1041             if (_MsOS_Task_Info[s32Id].stTask != 0)
1042             {
1043                 if ( cyg_thread_delete(_MsOS_Task_Info[s32Id].stTask) == TRUE)
1044                 {
1045                     _MsOS_Task_Info[s32Id].stTask = 0;
1046                 }
1047                 else
1048                 {
1049                     cyg_mutex_unlock(&_MsOS_Task_Mutex);
1050                     return -1;
1051                 }
1052             }
1053             break;
1054         }
1055     }
1056     if( s32Id < MSOS_TASK_MAX)
1057     {
1058         _MsOS_Task_Info[s32Id].bUsed = TRUE;
1059     }
1060     cyg_mutex_unlock(&_MsOS_Task_Mutex);
1061 
1062     if( s32Id >= MSOS_TASK_MAX)
1063     {
1064         return -1;
1065     }
1066 
1067     if (pStackBase == NULL)
1068     {
1069     /*
1070         #if 1 // stack autogen
1071         // No stack base specified create default 4K stack
1072         _MsOS_Task_Info[s32Id].pStackBase = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[0].stMemoryPool, u32StackSize);
1073         if (_MsOS_Task_Info[s32Id].pStackBase == NULL)
1074         {
1075             return -1;
1076         }
1077         cyg_thread_create( eTaskPriority,
1078                            (cyg_thread_entry_t  *)pTaskEntry, //TaskEntry has two arguments
1079                            u32TaskEntryData,
1080                            pTaskName,
1081                            _MsOS_Task_Info[s32Id].pStackBase,
1082                            u32StackSize,
1083                            &_MsOS_Task_Info[s32Id].stTask,
1084                            &_MsOS_Task_Info[s32Id].stThreadInfo );
1085         #else
1086         return -1;
1087         #endif
1088         */
1089         MS_ASSERT(0);
1090     }
1091     else
1092     {
1093         _MsOS_Task_Info[s32Id].pStackBase = NULL;
1094         _MsOS_Task_Info[s32Id].pTaskEntry = pTaskEntry;
1095         _MsOS_Task_Info[s32Id].entry_data = u32TaskEntryData;
1096         cyg_thread_create( eTaskPriority,
1097                            //(cyg_thread_entry_t  *)pTaskEntry, //TaskEntry has two arguments
1098                            (cyg_thread_entry_t  *)_MsOS_eCosTaskWrapper,
1099                            (cyg_addrword_t )&_MsOS_Task_Info[s32Id],
1100                            pTaskName,
1101                            pStackBase,
1102                            u32StackSize,
1103                            &_MsOS_Task_Info[s32Id].stTask,
1104                            &_MsOS_Task_Info[s32Id].stThreadInfo );
1105 
1106     }
1107 
1108     if (bAutoStart == TRUE)
1109     {
1110         cyg_thread_resume(_MsOS_Task_Info[s32Id].stTask);
1111     }
1112 
1113     s32Id |= MSOS_ID_PREFIX;
1114     return s32Id;
1115 }
1116 
1117 //-------------------------------------------------------------------------------------------------
1118 /// Delete a previously created task
1119 /// @param  s32TaskId   \b IN: task ID
1120 /// @return TRUE : succeed
1121 /// @return FALSE : fail
1122 //-------------------------------------------------------------------------------------------------
MsOS_DeleteTask(MS_S32 s32TaskId)1123 MS_BOOL MsOS_DeleteTask (MS_S32 s32TaskId)
1124 {
1125     if ( (s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1126     {
1127         return FALSE;
1128     }
1129     else
1130     {
1131         s32TaskId &= MSOS_ID_MASK;
1132     }
1133 
1134     if (FALSE == _MsOS_Task_Info[s32TaskId].bUsed)
1135     {
1136         return TRUE;
1137     }
1138 
1139     /*20090609 - somethims the delete task fail*/
1140     cyg_thread_kill(_MsOS_Task_Info[s32TaskId].stTask);
1141     MsOS_DelayTask(50);
1142 
1143     if( cyg_thread_delete(_MsOS_Task_Info[s32TaskId].stTask) == TRUE)
1144     {
1145         cyg_mutex_lock(&_MsOS_Task_Mutex);
1146         _MsOS_Task_Info[s32TaskId].bUsed = FALSE;
1147         _MsOS_Task_Info[s32TaskId].stTask = 0;
1148         cyg_mutex_unlock(&_MsOS_Task_Mutex);
1149         #if 1 // stack autogen
1150         if (_MsOS_Task_Info[s32TaskId].pStackBase)
1151         {
1152             // No stack base specified create default 4K stack
1153             cyg_mempool_var_free( _MsOS_MemoryPool_Info[0].stMemoryPool, _MsOS_Task_Info[s32TaskId].pStackBase);
1154             _MsOS_Task_Info[s32TaskId].pStackBase = NULL;
1155         }
1156         #endif
1157         return TRUE;
1158     }
1159     else
1160     {
1161         return FALSE;
1162     }
1163 }
1164 
1165 //-------------------------------------------------------------------------------------------------
1166 /// Yield the execution right to ready tasks with "the same" priority
1167 /// @return None
1168 //-------------------------------------------------------------------------------------------------
MsOS_YieldTask(void)1169 void MsOS_YieldTask (void)
1170 {
1171     MS_ASSERT( MsOS_In_Interrupt() == FALSE );
1172 
1173     cyg_thread_yield();
1174 }
1175 
1176 //-------------------------------------------------------------------------------------------------
1177 /// Suspend the calling task for u32Ms milliseconds
1178 /// @param  u32Ms  \b IN: delay 1 ~ MSOS_WAIT_FOREVER ms
1179 /// @return None
1180 /// @note   Not allowed in interrupt context; otherwise, exception will occur.
1181 //-------------------------------------------------------------------------------------------------
MsOS_DelayTask(MS_U32 u32Ms)1182 void MsOS_DelayTask (MS_U32 u32Ms)
1183 {
1184     //u32Ms=0 => The task will enter sleep state and wake up immediately with relative trigger time = 0
1185     // => Other ready tasks with the same or lower priorities will have no chance to run
1186     MS_ASSERT( u32Ms != 0);
1187     MS_ASSERT( MsOS_In_Interrupt() == FALSE );
1188 
1189     cyg_thread_delay(u32Ms*TICK_PER_ONE_MS);
1190 }
1191 
1192 //-------------------------------------------------------------------------------------------------
1193 /// Delay for u32Us microseconds
1194 /// @param  u32Us  \b IN: delay 0 ~ 999 us
1195 /// @return None
1196 /// @note   implemented by "busy waiting". Plz call MsOS_DelayTask directly for ms-order delay
1197 //-------------------------------------------------------------------------------------------------
MsOS_DelayTaskUs(MS_U32 u32Us)1198 void MsOS_DelayTaskUs (MS_U32 u32Us)
1199 {
1200     MS_ASSERT( MsOS_In_Interrupt() == FALSE );
1201 
1202     hal_delay_us(u32Us);
1203 }
1204 
1205 //-------------------------------------------------------------------------------------------------
1206 /// Delay Poll for u32Us microseconds
1207 /// @param  u32Us  \b IN: delay 0 ~ 999 us
1208 /// @return None
1209 /// @note   implemented by "busy waiting". Plz call MsOS_DelayTask directly for ms-order delay
1210 //-------------------------------------------------------------------------------------------------
MsOS_DelayTaskUs_Poll(MS_U32 u32Us)1211 void MsOS_DelayTaskUs_Poll(MS_U32 u32Us)
1212 {
1213 	MsOS_DelayTaskUs(u32Us);
1214 }
1215 
1216 //-------------------------------------------------------------------------------------------------
1217 /// Get task status
1218 /// @param  pTaskInfo       \b IN: task information structure pointer
1219 /// @param  peTaskState      \b OUT: ptr to task istate
1220 /// @return TRUE : succeed
1221 /// @return FALSE : invalid process result
1222 /// @note not support
1223 //-------------------------------------------------------------------------------------------------
MsOS_GetTaskStatus(Task_Info * pTaskInfo,TaskStatus * peTaskState)1224 MS_BOOL MsOS_GetTaskStatus (Task_Info* pTaskInfo, TaskStatus *peTaskState)
1225 {
1226 
1227     if ( (pTaskInfo == NULL) || (peTaskState == NULL))
1228     {
1229         return FALSE;
1230     }
1231 
1232     *peTaskState = E_TASK_INVALID_STATE;
1233     /* not support */
1234     return TRUE;
1235 }
1236 
1237 //-------------------------------------------------------------------------------------------------
1238 /// Resume the specified suspended task
1239 /// @param  s32TaskId   \b IN: Task ID
1240 /// @return TRUE : succeed
1241 /// @return FALSE : fail
1242 /// @note   This API is not supported in Linux
1243 //-------------------------------------------------------------------------------------------------
MsOS_ResumeTask(MS_S32 s32TaskId)1244 MS_BOOL MsOS_ResumeTask (MS_S32 s32TaskId)
1245 {
1246     if ( (s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1247     {
1248         return FALSE;
1249     }
1250     else
1251     {
1252         s32TaskId &= MSOS_ID_MASK;
1253     }
1254 
1255     cyg_thread_resume(_MsOS_Task_Info[s32TaskId].stTask);
1256     return TRUE;
1257 }
1258 
1259 //-------------------------------------------------------------------------------------------------
1260 /// Suspend the specified task
1261 /// @param  s32TaskId   \b IN: Task ID
1262 /// @return TRUE : succeed
1263 /// @return FALSE : fail
1264 /// @note   This API is not supported in Linux
1265 //-------------------------------------------------------------------------------------------------
MsOS_SuspendTask(MS_S32 s32TaskId)1266 MS_BOOL MsOS_SuspendTask (MS_S32 s32TaskId)
1267 {
1268     if ( (s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1269     {
1270         return FALSE;
1271     }
1272     else
1273     {
1274         s32TaskId &= MSOS_ID_MASK;
1275     }
1276 
1277     cyg_thread_suspend(_MsOS_Task_Info[s32TaskId].stTask);
1278     return TRUE;
1279 }
1280 
1281 //-------------------------------------------------------------------------------------------------
1282 /// Get a task information
1283 /// @param  s32TaskId       \b IN: task ID
1284 /// @param  peTaskPriority  \b OUT: ptr to task priority
1285 /// @param  pStackBase      \b OUT: ptr to stack base
1286 /// @param  pu32StackSize   \b OUT: ptr to stack size
1287 /// @param  pTaskName       \b OUT: ptr to task name
1288 /// @return TRUE : succeed
1289 /// @return FALSE : the task has not been created
1290 //-------------------------------------------------------------------------------------------------
MsOS_InfoTask(MS_S32 s32TaskId,TaskPriority * peTaskPriority,void * pStackBase,MS_U32 * pu32StackSize,MS_U32 * pu32StackUsed,char * pTaskName)1291 MS_BOOL MsOS_InfoTask (MS_S32 s32TaskId,
1292                        TaskPriority *peTaskPriority,
1293                        void* pStackBase,
1294                        MS_U32* pu32StackSize,
1295                        MS_U32* pu32StackUsed,
1296                        char *pTaskName)
1297 {
1298     cyg_thread_info ThreadInfo;
1299 
1300     if ( (s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1301     {
1302         return FALSE;
1303     }
1304     else
1305     {
1306         s32TaskId &= MSOS_ID_MASK;
1307     }
1308 
1309     if (FALSE == _MsOS_Task_Info[s32TaskId].bUsed)
1310     {
1311         return FALSE;
1312     }
1313 
1314     if(!cyg_thread_get_info(_MsOS_Task_Info[s32TaskId].stTask,
1315                             cyg_thread_get_id(_MsOS_Task_Info[s32TaskId].stTask),
1316                             &ThreadInfo))
1317     {
1318         return FALSE;
1319     }
1320     *peTaskPriority =           (TaskPriority) ThreadInfo.cur_pri;
1321     *((MS_U32*)pStackBase) =    (MS_U32)ThreadInfo.stack_base;
1322     *((MS_U32*)pu32StackSize) = (MS_U32)ThreadInfo.stack_size;
1323     *((MS_U32*)pu32StackUsed) = (MS_U32)ThreadInfo.stack_used;
1324     strcpy(pTaskName, ThreadInfo.name);
1325     return TRUE;
1326 }
1327 
1328 //-------------------------------------------------------------------------------------------------
1329 /// Get all task ID
1330 /// @param  ps32TaskIdList   \b IN/OUT: the memory for the all task ID
1331 /// @return number of task created
1332 //-------------------------------------------------------------------------------------------------
MsOS_InfoTaskList(MS_S32 * ps32TaskIdList)1333 MS_U32 MsOS_InfoTaskList (MS_S32* ps32TaskIdList)
1334 {
1335     MS_S32 s32Id;
1336     MS_U32 u32TaskNum = 0;
1337 
1338     for( s32Id=0; s32Id<MSOS_TASK_MAX; s32Id++)
1339     {
1340         if(_MsOS_Task_Info[s32Id].bUsed == TRUE)
1341         {
1342             ps32TaskIdList[u32TaskNum] = (s32Id | MSOS_ID_PREFIX);
1343             u32TaskNum++;
1344         }
1345     }
1346     return u32TaskNum;
1347 }
1348 
1349 
1350 //-------------------------------------------------------------------------------------------------
1351 /// Get current task ID
1352 /// @return >=0 : current task ID
1353 /// @return <0 : fail
1354 //-------------------------------------------------------------------------------------------------
MsOS_InfoTaskID(void)1355 MS_S32 MsOS_InfoTaskID (void)
1356 {
1357     MS_S32 s32Id;
1358     cyg_handle_t stTask;
1359     stTask = cyg_thread_self();
1360 
1361     for( s32Id=0; s32Id<MSOS_TASK_MAX; s32Id++)
1362     {
1363         if( stTask == _MsOS_Task_Info[s32Id].stTask )
1364         {
1365             break;
1366         }
1367     }
1368     if( s32Id < MSOS_TASK_MAX)
1369     {
1370         s32Id |= MSOS_ID_PREFIX;
1371         return s32Id;
1372     }
1373     else
1374     {
1375         return -1;
1376     }
1377 }
1378 
1379 //-------------------------------------------------------------------------------------------------
1380 /// Get thread ID of current thread/process in ecos
1381 /// @return : current thread ID
1382 //-------------------------------------------------------------------------------------------------
MsOS_GetOSThreadID(void)1383 MS_S32 MsOS_GetOSThreadID (void)
1384 {
1385     return (MS_S32)cyg_thread_self();
1386 }
1387 
1388 //
1389 // Mutex
1390 //
1391 //-------------------------------------------------------------------------------------------------
1392 /// Create a mutex in the unlocked state
1393 /// @param  eAttribute  \b IN: E_MSOS_FIFO: suspended in FIFO order
1394 /// @param  pMutexName  \b IN: mutex name
1395 /// @return >=0 : assigned mutex Id
1396 /// @return <0 : fail
1397 /// @note   A mutex has the concept of an owner, whereas a semaphore does not.
1398 ///         A mutex provides priority inheritance protocol against proiorty inversion, whereas a binary semaphore does not.
1399 //-------------------------------------------------------------------------------------------------
MsOS_CreateMutex(MsOSAttribute eAttribute,char * pMutexName,MS_U32 u32Flag)1400 MS_S32 MsOS_CreateMutex ( MsOSAttribute eAttribute, char *pMutexName, MS_U32 u32Flag)
1401 {
1402     MS_S32 s32Id;
1403     //OPTION suspend_type;
1404 
1405     cyg_mutex_lock(&_MsOS_Mutex_Mutex);
1406     for(s32Id=0;s32Id<MSOS_MUTEX_MAX;s32Id++)
1407     {
1408         if(_MsOS_Mutex_Info[s32Id].bUsed == FALSE)
1409         {
1410             break;
1411         }
1412     }
1413     if(s32Id < MSOS_MUTEX_MAX)
1414     {
1415         _MsOS_Mutex_Info[s32Id].bUsed = TRUE;
1416     }
1417     cyg_mutex_unlock(&_MsOS_Mutex_Mutex);
1418 
1419     if(s32Id >= MSOS_MUTEX_MAX)
1420     {
1421         return -1L;
1422     }
1423 
1424     //no Priority order for eCos
1425     //pMutexName is not used for eCos
1426 
1427     // Call OS kernel to create a semaphore.
1428     cyg_mutex_init( &_MsOS_Mutex_Info[s32Id].stMutex);
1429 
1430     s32Id |= MSOS_ID_PREFIX;
1431 
1432     return s32Id;
1433 }
1434 
1435 //-------------------------------------------------------------------------------------------------
1436 /// Delete the specified mutex
1437 /// @param  s32MutexId  \b IN: mutex ID
1438 /// @return TRUE : succeed
1439 /// @return FALSE : fail
1440 /// @note   It is important that the mutex be in the unlocked state when it is
1441 ///            destroyed, or else the behavior is undefined.
1442 //-------------------------------------------------------------------------------------------------
MsOS_DeleteMutex(MS_S32 s32MutexId)1443 MS_BOOL MsOS_DeleteMutex (MS_S32 s32MutexId)
1444 {
1445     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1446     {
1447         return FALSE;
1448     }
1449     else
1450     {
1451         s32MutexId &= MSOS_ID_MASK;
1452     }
1453 
1454     cyg_mutex_destroy(&_MsOS_Mutex_Info[s32MutexId].stMutex);
1455 
1456     cyg_mutex_lock(&_MsOS_Mutex_Mutex);
1457     _MsOS_Mutex_Info[s32MutexId].bUsed = FALSE;
1458     cyg_mutex_unlock(&_MsOS_Mutex_Mutex);
1459 
1460     return TRUE;
1461 }
1462 
1463 //-------------------------------------------------------------------------------------------------
1464 /// Attempt to lock a mutex
1465 /// @param  s32MutexId  \b IN: mutex ID
1466 /// @param  u32WaitMs   \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the mutex is locked
1467 /// @return TRUE : succeed
1468 /// @return FALSE : fail
1469 //-------------------------------------------------------------------------------------------------
MsOS_ObtainMutex(MS_S32 s32MutexId,MS_U32 u32WaitMs)1470 MS_BOOL MsOS_ObtainMutex (MS_S32 s32MutexId, MS_U32 u32WaitMs)
1471 {
1472     MS_BOOL bRet = FALSE;
1473 
1474     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1475     {
1476         return FALSE;
1477     }
1478     else
1479     {
1480         s32MutexId &= MSOS_ID_MASK;
1481     }
1482 
1483     //@NOTE not call this assert because TSP driver must call obtain mutex in TSP ISR fun.
1484     //@TODO need to call system team for help this
1485     //MS_ASSERT( MsOS_In_Interrupt() == FALSE );
1486 
1487     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
1488     {
1489         cyg_mutex_lock(&_MsOS_Mutex_Info[s32MutexId].stMutex);
1490         bRet = TRUE;
1491     }
1492     else if (u32WaitMs==0) //non-blocking
1493     {
1494         if ( cyg_mutex_trylock(&_MsOS_Mutex_Info[s32MutexId].stMutex) )
1495         {
1496             bRet = TRUE;
1497         }
1498     }
1499     else //blocking wait with timeout
1500     {
1501         if ( cyg_mutex_timed_lock(&_MsOS_Mutex_Info[s32MutexId].stMutex,
1502                                     cyg_current_time()+u32WaitMs*TICK_PER_ONE_MS) )
1503         {
1504             bRet = TRUE;
1505         }
1506     }
1507 
1508     return bRet;
1509 }
1510 
1511 //-------------------------------------------------------------------------------------------------
1512 /// Attempt to unlock a mutex
1513 /// @param  s32MutexId  \b IN: mutex ID
1514 /// @return TRUE : succeed
1515 /// @return FALSE : fail
1516 /// @note   Only the owner thread of the mutex can unlock it.
1517 //-------------------------------------------------------------------------------------------------
MsOS_ReleaseMutex(MS_S32 s32MutexId)1518 MS_BOOL MsOS_ReleaseMutex (MS_S32 s32MutexId)
1519 {
1520     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1521     {
1522         return FALSE;
1523     }
1524     else
1525     {
1526         s32MutexId &= MSOS_ID_MASK;
1527     }
1528 
1529     cyg_mutex_unlock(&_MsOS_Mutex_Info[s32MutexId].stMutex);
1530 
1531     return TRUE;
1532 }
1533 
1534 //-------------------------------------------------------------------------------------------------
1535 // Get a mutex informaton
1536 // @param  s32MutexId  \b IN: mutex ID
1537 // @param  peAttribute \b OUT: ptr to suspended mode: E_MSOS_FIFO / E_MSOS_PRIORITY
1538 // @param  pMutexName  \b OUT: ptr to mutex name
1539 // @return TRUE : succeed
1540 // @return FALSE : the mutex has not been created.
1541 //-------------------------------------------------------------------------------------------------
MsOS_InfoMutex(MS_S32 s32MutexId,MsOSAttribute * peAttribute,char * pMutexName)1542 MS_BOOL MsOS_InfoMutex (MS_S32 s32MutexId, MsOSAttribute *peAttribute, char *pMutexName)
1543 {
1544     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1545     {
1546         return FALSE;
1547     }
1548     else
1549     {
1550         s32MutexId &= MSOS_ID_MASK;
1551     }
1552 
1553     if(_MsOS_Mutex_Info[s32MutexId].bUsed == TRUE)
1554     {
1555         //ToDo: extend _MsOS_Mutex_Info structure ?
1556         *peAttribute = E_MSOS_FIFO; //only FIFO for eCos
1557         UTL_strcpy(pMutexName, "ABC");
1558 
1559         return TRUE;
1560     }
1561     else
1562     {
1563         return FALSE;
1564     }
1565 }
1566 
1567 //
1568 // Semaphore
1569 //
1570 //-------------------------------------------------------------------------------------------------
1571 /// Create a semaphore
1572 /// @param  u32InitCnt \b IN: initial semaphore value
1573 /// @param  eAttribute \b IN: E_MSOS_FIFO suspended in FIFO order
1574 /// @param  pSemaphoreName \b IN: semaphore name
1575 /// @return >=0 : assigned Semaphore Id
1576 /// @return <0 : fail
1577 /// @note   A semaphore does not have the concept of an owner; it is possible for one thread to lock a
1578 ///           binary semaphore and another thread to unlock it.
1579 //-------------------------------------------------------------------------------------------------
MsOS_CreateSemaphore(MS_U32 u32InitCnt,MsOSAttribute eAttribute,char * pSemaphoreName)1580 MS_S32 MsOS_CreateSemaphore (MS_U32 u32InitCnt,
1581                           MsOSAttribute eAttribute,
1582                           char *pSemaphoreName)
1583 {
1584     MS_S32 s32Id;
1585 
1586     cyg_mutex_lock(&_MsOS_Semaphore_Mutex);
1587     for(s32Id=0;s32Id<MSOS_SEMAPHORE_MAX;s32Id++)
1588     {
1589         if(_MsOS_Semaphore_Info[s32Id].bUsed == FALSE)
1590         {
1591             break;
1592         }
1593     }
1594     if(s32Id < MSOS_SEMAPHORE_MAX)
1595     {
1596         _MsOS_Semaphore_Info[s32Id].bUsed = TRUE;
1597     }
1598     cyg_mutex_unlock(&_MsOS_Semaphore_Mutex);
1599 
1600     if(s32Id >= MSOS_SEMAPHORE_MAX)
1601     {
1602         return -1;
1603     }
1604 
1605     //no Priority order for eCos
1606     //pSemaphoreName is not used for eCos
1607 
1608     // Call OS kernel to create a semaphore.
1609     cyg_semaphore_init( &_MsOS_Semaphore_Info[s32Id].stSemaphore, u32InitCnt);
1610 
1611     s32Id |= MSOS_ID_PREFIX;
1612     return s32Id;
1613 }
1614 
1615 //-------------------------------------------------------------------------------------------------
1616 /// Delete the specified semaphore
1617 /// @param  s32SemaphoreId  \b IN: semaphore ID
1618 /// @return TRUE : succeed
1619 /// @return FALSE : fail
1620 /// @note   It is important that there are not any threads waiting on the semaphore
1621 ///             when this function is called or the behavior is undefined.
1622 //-------------------------------------------------------------------------------------------------
MsOS_DeleteSemaphore(MS_S32 s32SemaphoreId)1623 MS_BOOL MsOS_DeleteSemaphore (MS_S32 s32SemaphoreId)
1624 {
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     cyg_semaphore_destroy(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore);
1635 
1636     cyg_mutex_lock(&_MsOS_Semaphore_Mutex);
1637     _MsOS_Semaphore_Info[s32SemaphoreId].bUsed = FALSE;
1638     cyg_mutex_unlock(&_MsOS_Semaphore_Mutex);
1639     return TRUE;
1640 }
1641 
1642 //-------------------------------------------------------------------------------------------------
1643 /// Attempt to decrement a semaphore count
1644 /// @param  s32SemaphoreId  \b IN: semaphore ID
1645 /// @param  u32WaitMs       \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the semaphore count = 0
1646 /// @return TRUE : succeed
1647 /// @return FALSE : fail
1648 //-------------------------------------------------------------------------------------------------
MsOS_ObtainSemaphore(MS_S32 s32SemaphoreId,MS_U32 u32WaitMs)1649 MS_BOOL MsOS_ObtainSemaphore (MS_S32 s32SemaphoreId, MS_U32 u32WaitMs)
1650 {
1651     MS_BOOL bRet = FALSE;
1652 
1653     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1654     {
1655         return FALSE;
1656     }
1657     else
1658     {
1659         s32SemaphoreId &= MSOS_ID_MASK;
1660     }
1661 
1662     MS_ASSERT( MsOS_In_Interrupt() == FALSE );
1663 
1664     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
1665     {
1666         cyg_semaphore_wait(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore);
1667         bRet = TRUE;
1668     }
1669     else if (u32WaitMs==0) //non-blocking
1670     {
1671         if ( cyg_semaphore_trywait(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore) )
1672         {
1673             bRet = TRUE;
1674         }
1675     }
1676     else //blocking wait with timeout
1677     {
1678         if ( cyg_semaphore_timed_wait(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore,
1679                                         cyg_current_time()+u32WaitMs*TICK_PER_ONE_MS) )
1680         {
1681             bRet = TRUE;
1682         }
1683     }
1684 
1685     return bRet;
1686 }
1687 
1688 //-------------------------------------------------------------------------------------------------
1689 /// Increase a semaphore count
1690 /// @param  s32SemaphoreId  \b IN: semaphore ID
1691 /// @return TRUE : succeed
1692 /// @return FALSE : fail
1693 /// @note   It's possible for any thread to increase the semaphore count
1694 //-------------------------------------------------------------------------------------------------
MsOS_ReleaseSemaphore(MS_S32 s32SemaphoreId)1695 MS_BOOL MsOS_ReleaseSemaphore (MS_S32 s32SemaphoreId)
1696 {
1697     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1698     {
1699         return FALSE;
1700     }
1701     else
1702     {
1703         s32SemaphoreId &= MSOS_ID_MASK;
1704     }
1705 
1706     cyg_semaphore_post(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore);
1707 
1708     return TRUE;
1709 }
1710 
1711 //-------------------------------------------------------------------------------------------------
1712 // Get a semaphore informaton
1713 // @param  s32SemaphoreId  \b IN: semaphore ID
1714 // @param  pu32InitCnt     \b OUT: ptr to initial semaphore value
1715 // @param  peAttribute     \b OUT: ptr to suspended mode: E_MSOS_FIFO / E_MSOS_PRIORITY
1716 // @param  pSemaphoreName  \b OUT: ptr to semaphore name
1717 // @return TRUE : succeed
1718 // @return FALSE : the semaphore has not been created.
1719 //-------------------------------------------------------------------------------------------------
MsOS_InfoSemaphore(MS_S32 s32SemaphoreId,MS_U32 * pu32InitCnt,MsOSAttribute * peAttribute,char * pSemaphoreName)1720 MS_BOOL MsOS_InfoSemaphore (MS_S32 s32SemaphoreId, MS_U32 *pu32InitCnt, MsOSAttribute *peAttribute, char *pSemaphoreName)
1721 {
1722     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1723     {
1724         return FALSE;
1725     }
1726     else
1727     {
1728         s32SemaphoreId &= MSOS_ID_MASK;
1729     }
1730 
1731     if(_MsOS_Semaphore_Info[s32SemaphoreId].bUsed == TRUE)
1732     {
1733         //ToDo: extend _MsOS_Semaphore_Info structure ?
1734         *pu32InitCnt = _MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore.count;
1735         *peAttribute = E_MSOS_FIFO;
1736         UTL_strcpy(pSemaphoreName, "XXX");
1737 
1738         return TRUE;
1739     }
1740     else
1741     {
1742         return FALSE;
1743     }
1744 }
1745 
1746 
1747 //
1748 // Event management
1749 //
1750 //-------------------------------------------------------------------------------------------------
1751 /// Create an event group
1752 /// @param  pEventName  \b IN: event group name
1753 /// @return >=0 : assigned Event Id
1754 /// @return <0 : fail
1755 //-------------------------------------------------------------------------------------------------
MsOS_CreateEventGroup(char * pEventName)1756 MS_S32 MsOS_CreateEventGroup (char *pEventName)
1757 {
1758     MS_S32 s32Id;
1759     cyg_mutex_lock(&_MsOS_EventGroup_Mutex);
1760 
1761     for(s32Id=0; s32Id<MSOS_EVENTGROUP_MAX; s32Id++)
1762     {
1763         if(_MsOS_EventGroup_Info[s32Id].bUsed == FALSE)
1764         {
1765             break;
1766         }
1767     }
1768     if(s32Id < MSOS_EVENTGROUP_MAX)
1769     {
1770         _MsOS_EventGroup_Info[s32Id].bUsed = TRUE;
1771     }
1772     cyg_mutex_unlock(&_MsOS_EventGroup_Mutex);
1773 
1774     if(s32Id >= MSOS_EVENTGROUP_MAX)
1775     {
1776         return -1;
1777     }
1778 
1779     //pEventName is not used for eCos
1780 
1781     cyg_flag_init(&_MsOS_EventGroup_Info[s32Id].stEventGroup);
1782 
1783     s32Id |= MSOS_ID_PREFIX;
1784     return s32Id;
1785 }
1786 
1787 //-------------------------------------------------------------------------------------------------
1788 /// Delete the event group
1789 /// @param  s32EventGroupId \b IN: event group ID
1790 /// @return TRUE : succeed
1791 /// @return FALSE : fail, sb is waiting for the event flag
1792 /// @note event group that are being waited on must not be deleted
1793 //-------------------------------------------------------------------------------------------------
MsOS_DeleteEventGroup(MS_S32 s32EventGroupId)1794 MS_BOOL MsOS_DeleteEventGroup (MS_S32 s32EventGroupId)
1795 {
1796     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1797     {
1798         return FALSE;
1799     }
1800     else
1801     {
1802         s32EventGroupId &= MSOS_ID_MASK;
1803     }
1804 
1805     if ( cyg_flag_waiting(&_MsOS_EventGroup_Info[s32EventGroupId].stEventGroup) )
1806     {
1807         return FALSE;
1808     }
1809     else
1810     {
1811         cyg_flag_destroy(&_MsOS_EventGroup_Info[s32EventGroupId].stEventGroup);
1812         cyg_mutex_lock(&_MsOS_EventGroup_Mutex);
1813         _MsOS_EventGroup_Info[s32EventGroupId].bUsed = FALSE;
1814         cyg_mutex_unlock(&_MsOS_EventGroup_Mutex);
1815         return TRUE;
1816     }
1817 }
1818 
1819 //-------------------------------------------------------------------------------------------------
1820 /// Set the event flag (bitwise OR w/ current value) in the specified event group
1821 /// @param  s32EventGroupId \b IN: event group ID
1822 /// @param  u32EventFlag    \b IN: event flag value
1823 /// @return TRUE : succeed
1824 /// @return FALSE : fail
1825 //-------------------------------------------------------------------------------------------------
MsOS_SetEvent(MS_S32 s32EventGroupId,MS_U32 u32EventFlag)1826 MS_BOOL MsOS_SetEvent (MS_S32 s32EventGroupId, MS_U32 u32EventFlag)
1827 {
1828     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1829     {
1830         return FALSE;
1831     }
1832     else
1833     {
1834         s32EventGroupId &= MSOS_ID_MASK;
1835     }
1836 
1837     cyg_flag_setbits(&_MsOS_EventGroup_Info[s32EventGroupId].stEventGroup, u32EventFlag);
1838     return TRUE;
1839 }
1840 
1841 //-------------------------------------------------------------------------------------------------
1842 /// Clear the specified event flag (bitwise XOR operation) in the specified event group
1843 /// @param  s32EventGroupId \b IN: event group ID
1844 /// @param  u32EventFlag    \b IN: event flag value
1845 /// @return TRUE : succeed
1846 /// @return FALSE : fail
1847 //-------------------------------------------------------------------------------------------------
MsOS_ClearEvent(MS_S32 s32EventGroupId,MS_U32 u32EventFlag)1848 MS_BOOL MsOS_ClearEvent (MS_S32 s32EventGroupId, MS_U32 u32EventFlag)
1849 {
1850     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1851     {
1852         return FALSE;
1853     }
1854     else
1855     {
1856         s32EventGroupId &= MSOS_ID_MASK;
1857     }
1858 
1859     cyg_flag_maskbits(&_MsOS_EventGroup_Info[s32EventGroupId].stEventGroup, ~u32EventFlag);
1860     return TRUE;
1861 }
1862 
1863 //-------------------------------------------------------------------------------------------------
1864 /// Wait for the specified event flag combination from the event group
1865 /// @param  s32EventGroupId     \b IN: event group ID
1866 /// @param  u32WaitEventFlag    \b IN: wait event flag value
1867 /// @param  pu32RetrievedEventFlag \b OUT: retrieved event flag value
1868 /// @param  eWaitMode           \b IN: E_AND/E_OR/E_AND_CLEAR/E_OR_CLEAR
1869 /// @param  u32WaitMs           \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the event is not ready
1870 /// @return TRUE : succeed
1871 /// @return FALSE : fail
1872 //-------------------------------------------------------------------------------------------------
MsOS_WaitEvent(MS_S32 s32EventGroupId,MS_U32 u32WaitEventFlag,MS_U32 * pu32RetrievedEventFlag,EventWaitMode eWaitMode,MS_U32 u32WaitMs)1873 MS_BOOL MsOS_WaitEvent (MS_S32     s32EventGroupId,
1874                      MS_U32     u32WaitEventFlag,
1875                      MS_U32     *pu32RetrievedEventFlag,
1876                      EventWaitMode eWaitMode,
1877                      MS_U32     u32WaitMs)
1878 {
1879     cyg_flag_mode_t operation;
1880     MS_BOOL bClear;
1881 
1882     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1883     {
1884         return FALSE;
1885     }
1886     else
1887     {
1888         s32EventGroupId &= MSOS_ID_MASK;
1889     }
1890 
1891     MS_ASSERT( MsOS_In_Interrupt() == FALSE );
1892 
1893     bClear = FALSE;
1894     switch(eWaitMode)
1895     {
1896     case E_AND:
1897         operation = CYG_FLAG_WAITMODE_AND;
1898         break;
1899     case E_OR:
1900         operation = CYG_FLAG_WAITMODE_OR;
1901         break;
1902     case E_AND_CLEAR:
1903         operation = CYG_FLAG_WAITMODE_AND;
1904         bClear = TRUE;
1905         break;
1906     case E_OR_CLEAR:
1907         operation = CYG_FLAG_WAITMODE_OR;
1908         bClear = TRUE;
1909         break;
1910     default:
1911         return FALSE;
1912     }
1913 
1914 
1915     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
1916     {
1917         *pu32RetrievedEventFlag = cyg_flag_wait( &_MsOS_EventGroup_Info[s32EventGroupId].stEventGroup,
1918                                                  u32WaitEventFlag,
1919                                                  operation );
1920     }
1921     else if (u32WaitMs==0) //non-blocking
1922     {
1923         *pu32RetrievedEventFlag = cyg_flag_poll( &_MsOS_EventGroup_Info[s32EventGroupId].stEventGroup,
1924                                                  u32WaitEventFlag,
1925                                                  operation );
1926     }
1927     else //blocking wait with timeout
1928     {
1929         *pu32RetrievedEventFlag = cyg_flag_timed_wait( &_MsOS_EventGroup_Info[s32EventGroupId].stEventGroup,
1930                                                        u32WaitEventFlag,
1931                                                        operation,
1932                                                        cyg_current_time()+u32WaitMs*TICK_PER_ONE_MS );
1933     }
1934 
1935     if (bClear && *pu32RetrievedEventFlag)
1936     {
1937         cyg_flag_maskbits(&_MsOS_EventGroup_Info[s32EventGroupId].stEventGroup, ~((*pu32RetrievedEventFlag)&(u32WaitEventFlag)));
1938     }
1939 
1940     if( *pu32RetrievedEventFlag )
1941     {
1942         return TRUE;
1943     }
1944     else
1945     {
1946         return FALSE;
1947     }
1948 }
1949 
1950 //-------------------------------------------------------------------------------------------------
1951 /// Wait for the specified event flag combination from the event group
1952 /// @param  s32EventGroupId     \b IN: event group ID
1953 /// @param  u32WaitEventFlag    \b IN: wait event flag value
1954 /// @param  pu32RetrievedEventFlag \b OUT: retrieved event flag value
1955 /// @param  eWaitMode           \b IN: E_AND/E_OR/E_AND_CLEAR/E_OR_CLEAR
1956 /// @param  u32WaitMs           \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the event is not ready
1957 /// @return TRUE : succeed
1958 /// @return FALSE : fail
1959 //-------------------------------------------------------------------------------------------------
MsOS_WaitEvent_Interrupt(MS_S32 s32EventGroupId,MS_U32 u32WaitEventFlag,MS_U32 * pu32RetrievedEventFlag,EventWaitMode eWaitMode,MS_U32 u32WaitMs)1960 MS_S32 MsOS_WaitEvent_Interrupt(MS_S32 s32EventGroupId,
1961                      MS_U32 u32WaitEventFlag,
1962                      MS_U32 *pu32RetrievedEventFlag,
1963                      EventWaitMode eWaitMode,
1964                      MS_U32 u32WaitMs)
1965 {
1966     return  (MS_S32)MsOS_WaitEvent(s32EventGroupId,u32WaitEventFlag,pu32RetrievedEventFlag,eWaitMode,u32WaitMs);
1967 }
1968 
1969 
1970 /*
1971 //
1972 // Signal management
1973 //
1974 //-------------------------------------------------------------------------------------------------
1975 // Create a signal and attach the callback function
1976 // @param  pSignalCb   \b IN: signal callback function
1977 // @return TRUE : succeed
1978 // @return FALSE : fail
1979 //-------------------------------------------------------------------------------------------------
1980 MS_BOOL MsOS_CreateSignal (SignalCb pSignalCb)
1981 {
1982     //ToDo: POSIX signal or ...
1983     return FALSE;
1984 }
1985 
1986 //-------------------------------------------------------------------------------------------------
1987 // Enable / Disable the corresponding signal
1988 // @param  u32SignalMask   \b IN: bit pattern signal mask (Set a bit to enable; Clear a bit to disable)
1989 // @return TRUE : succeed
1990 // @return FALSE : fail
1991 //-------------------------------------------------------------------------------------------------
1992 MS_BOOL MsOS_ControlSignals (MS_U32 u32SignalMask)
1993 {
1994     //ToDo: POSIX signal or ...
1995     return FALSE;
1996 }
1997 
1998 //-------------------------------------------------------------------------------------------------
1999 // Send the signal to the specified task
2000 // @param  s32TaskId \b IN: Task ID
2001 // @param  u32Signal \b IN: signal bit pattern
2002 // @return TRUE : succeed
2003 // @return FALSE : fail
2004 //-------------------------------------------------------------------------------------------------
2005 MS_BOOL MsOS_SendSignals (MS_S32 s32TaskId, MS_U32 u32Signal)
2006 {
2007     //ToDo: POSIX signal or ...
2008     return FALSE;
2009 }
2010 
2011 //-------------------------------------------------------------------------------------------------
2012 // Return the current signal value associated with the calling task
2013 // @return current signal value
2014 // @note   All signals are automatically cleared as a result of this service call
2015 //-------------------------------------------------------------------------------------------------
2016 MS_U32 MsOS_ReceiveSignals (void)
2017 {
2018     //ToDo: POSIX signal or ...
2019     return FALSE;
2020 }
2021 */
2022 
2023 //
2024 // Timer management
2025 //
2026 //-------------------------------------------------------------------------------------------------
2027 /// Create a Timer
2028 /// @param  pTimerCb        \b IN: timer callback function
2029 /// @param  u32FirstTimeMs  \b IN: first ms for timer expiration
2030 /// @param  u32PeriodTimeMs \b IN: periodic ms for timer expiration after first expiration
2031 ///                                0: one shot timer
2032 /// @param  bStartTimer     \b IN: TRUE: activates the timer after it is created
2033 ///                                FALSE: leaves the timer disabled after it is created
2034 /// @param  pTimerName      \b IN: Timer name (not used by eCos)
2035 /// @return >=0 : assigned Timer ID
2036 ///         <0 : fail
2037 //-------------------------------------------------------------------------------------------------
MsOS_CreateTimer(TimerCb pTimerCb,MS_U32 u32FirstTimeMs,MS_U32 u32PeriodTimeMs,MS_BOOL bStartTimer,char * pTimerName)2038 MS_S32 MsOS_CreateTimer (TimerCb   pTimerCb,
2039                          MS_U32    u32FirstTimeMs,
2040                          MS_U32    u32PeriodTimeMs,
2041                          MS_BOOL   bStartTimer,
2042                          char      *pTimerName)
2043 {
2044     MS_S32 s32Id;
2045 
2046     cyg_mutex_lock( &_MsOS_Timer_Mutex);
2047     for(s32Id=0;s32Id<MSOS_TIMER_MAX;s32Id++)
2048     {
2049         if(_MsOS_Timer_Info[s32Id].bUsed == FALSE)
2050         {
2051             break;
2052         }
2053     }
2054     if(s32Id < MSOS_TIMER_MAX)
2055     {
2056         _MsOS_Timer_Info[s32Id].bUsed = TRUE;
2057     }
2058     cyg_mutex_unlock( &_MsOS_Timer_Mutex);
2059 
2060     if(s32Id >= MSOS_TIMER_MAX)
2061     {
2062         return -1;
2063     }
2064 
2065     // Call OS kernel to create a Timer
2066     cyg_alarm_create( _stCounter, //_MsOS_Timer_Info[s32Id].stCounter,
2067                       (cyg_alarm_t*)pTimerCb,
2068                       s32Id | MSOS_ID_PREFIX,
2069                       &_MsOS_Timer_Info[s32Id].stTimer,
2070                       &_MsOS_Timer_Info[s32Id].stAlarm );
2071 
2072     //pTimerName is not used for eCos
2073 
2074     cyg_alarm_initialize( _MsOS_Timer_Info[s32Id].stTimer, cyg_current_time() + u32FirstTimeMs*TICK_PER_ONE_MS,
2075                             u32PeriodTimeMs*TICK_PER_ONE_MS); //will enable timer
2076 
2077     if(!bStartTimer)
2078     {
2079         cyg_alarm_disable(_MsOS_Timer_Info[s32Id].stTimer);
2080     }
2081 
2082     s32Id |= MSOS_ID_PREFIX;
2083     return s32Id;
2084 }
2085 
2086 //-------------------------------------------------------------------------------------------------
2087 /// Delete the Timer
2088 /// @param  s32TimerId  \b IN: Timer ID
2089 /// @return TRUE : succeed
2090 /// @return FALSE : fail
2091 //-------------------------------------------------------------------------------------------------
MsOS_DeleteTimer(MS_S32 s32TimerId)2092 MS_BOOL MsOS_DeleteTimer (MS_S32 s32TimerId)
2093 {
2094     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2095     {
2096         return FALSE;
2097     }
2098     else
2099     {
2100         s32TimerId &= MSOS_ID_MASK;
2101     }
2102 
2103     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2104     {
2105         cyg_alarm_delete(_MsOS_Timer_Info[s32TimerId].stTimer);
2106         cyg_mutex_lock( &_MsOS_Timer_Mutex);
2107         _MsOS_Timer_Info[s32TimerId].bUsed = FALSE;
2108         cyg_mutex_unlock(&_MsOS_Timer_Mutex);
2109         return TRUE;
2110     }
2111     else
2112     {
2113         return FALSE;
2114     }
2115 }
2116 
2117 //-------------------------------------------------------------------------------------------------
2118 /// Start the Timer
2119 /// @param  s32TimerId  \b IN: Timer ID
2120 /// @return TRUE : succeed
2121 /// @return FALSE : fail
2122 //-------------------------------------------------------------------------------------------------
MsOS_StartTimer(MS_S32 s32TimerId)2123 MS_BOOL MsOS_StartTimer (MS_S32 s32TimerId)
2124 {
2125     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2126     {
2127         return FALSE;
2128     }
2129     else
2130     {
2131         s32TimerId &= MSOS_ID_MASK;
2132     }
2133 
2134     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2135     {
2136         cyg_alarm_enable(_MsOS_Timer_Info[s32TimerId].stTimer);
2137         return TRUE;
2138     }
2139     else
2140     {
2141         return FALSE;
2142     }
2143 }
2144 
2145 //-------------------------------------------------------------------------------------------------
2146 /// Stop the Timer
2147 /// @param  s32TimerId  \b IN: Timer ID
2148 /// @return TRUE : succeed
2149 /// @return FALSE : fail
2150 /// @note   MsOS_StopTimer then MsOS_StartTimer => The timer will trigger at the same relative
2151 ///             intervals that it would have if it had not been disabled.
2152 //-------------------------------------------------------------------------------------------------
MsOS_StopTimer(MS_S32 s32TimerId)2153 MS_BOOL MsOS_StopTimer (MS_S32 s32TimerId)
2154 {
2155     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2156     {
2157         return FALSE;
2158     }
2159     else
2160     {
2161         s32TimerId &= MSOS_ID_MASK;
2162     }
2163 
2164     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2165     {
2166         cyg_alarm_disable(_MsOS_Timer_Info[s32TimerId].stTimer);
2167         return TRUE;
2168     }
2169     else
2170     {
2171         return FALSE;
2172     }
2173 }
2174 
2175 //-------------------------------------------------------------------------------------------------
2176 /// Reset a Timer & reset the expiration periods
2177 /// @param  s32TimerId      \b IN: Timer ID
2178 /// @param  u32FirstTimeMs  \b IN: first ms for timer expiration
2179 /// @param  u32PeriodTimeMs \b IN: periodic ms for timer expiration after first expiration
2180 ///                                0: one shot timer
2181 /// @param  bStartTimer     \b IN: TRUE: activates the timer after it is created
2182 ///                                FALSE: leaves the timer disabled after it is created
2183 /// @return TRUE : succeed
2184 /// @return FALSE : fail
2185 //-------------------------------------------------------------------------------------------------
MsOS_ResetTimer(MS_S32 s32TimerId,MS_U32 u32FirstTimeMs,MS_U32 u32PeriodTimeMs,MS_BOOL bStartTimer)2186 MS_BOOL MsOS_ResetTimer (MS_S32     s32TimerId,
2187                          MS_U32     u32FirstTimeMs,
2188                          MS_U32     u32PeriodTimeMs,
2189                          MS_BOOL    bStartTimer)
2190 {
2191     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2192     {
2193         return FALSE;
2194     }
2195     else
2196     {
2197         s32TimerId &= MSOS_ID_MASK;
2198     }
2199 
2200     cyg_alarm_initialize( _MsOS_Timer_Info[s32TimerId].stTimer, cyg_current_time() + u32FirstTimeMs*TICK_PER_ONE_MS,
2201                             u32PeriodTimeMs*TICK_PER_ONE_MS); //will enable timer
2202 
2203     if(!bStartTimer)
2204     {
2205         cyg_alarm_disable(_MsOS_Timer_Info[s32TimerId].stTimer);
2206     }
2207 
2208     return TRUE;
2209 }
2210 
2211 
2212 //
2213 // System time
2214 //
2215 /*
2216 //use MsOS_GetSystemTime instead
2217 //-------------------------------------------------------------------------------------------------
2218 /// Get current system time in timer ticks
2219 /// @return system time in timer ticks
2220 //-------------------------------------------------------------------------------------------------
2221 MS_U32 MsOS_GetSystemTick (void)
2222 {
2223 #if 1
2224     //kernel counter value will not be updated if called by eCos DSR
2225     // timer interrupts -> Cyg_RealTimeClock::dsr()->Cyg_Counter::tick()->counter += increment;
2226     //  will not be called if another DSR is currently being serived
2227     return cyg_current_time();
2228 
2229     //This will overtime after COUNT register reaches max value.
2230     MS_U32 u32COUNT;
2231 #else
2232     //FixMe: this is a little different from cyg_current_time, coz now kerel ignores the period from
2233     //       timer interrupt trigger to COUNT/COMPARE update
2234     asm volatile (
2235         "mfc0 $8,$9;"
2236         "nop; nop; nop;"
2237         "move %0,$8;"
2238         : "=r"(u32COUNT)
2239         :
2240         : "$8"
2241         );
2242 
2243     return ( u32COUNT/CYGNUM_HAL_RTC_PERIOD );
2244 #endif
2245 }
2246 */
2247 
2248 //-------------------------------------------------------------------------------------------------
2249 /// Get current system time in ms
2250 /// @return system time in ms
2251 //-------------------------------------------------------------------------------------------------
MsOS_GetSystemTime(void)2252 MS_U32 MsOS_GetSystemTime (void)
2253 {
2254     return ( cyg_current_time()/TICK_PER_ONE_MS );
2255 }
2256 //-------------------------------------------------------------------------------------------------
2257 ///[OBSOLETE]
2258 /// Time difference between current time and task time
2259 /// @return system time diff in ms
2260 //-------------------------------------------------------------------------------------------------
MsOS_Timer_DiffTimeFromNow(MS_U32 u32TaskTimer)2261 MS_U32 MsOS_Timer_DiffTimeFromNow(MS_U32 u32TaskTimer) //unit = ms
2262 {
2263     return (MsOS_GetSystemTime() - u32TaskTimer);
2264 }
2265 //-------------------------------------------------------------------------------------------------
2266 ///[OBSOLETE]
2267 /// Time difference between setting time and task time
2268 /// @return system time diff in ms
2269 //-------------------------------------------------------------------------------------------------
MsOS_Timer_DiffTime(MS_U32 u32Timer,MS_U32 u32TaskTimer)2270 MS_U32 MsOS_Timer_DiffTime(MS_U32 u32Timer, MS_U32 u32TaskTimer) //unit = ms
2271 {
2272     // simple minus is enough, because max(timer_counter) == max(u32)
2273     return (u32Timer - u32TaskTimer);
2274 }
2275 /*
2276 //COUNT was reset at system initialization
2277 //-------------------------------------------------------------------------------------------------
2278 /// Set current system time
2279 /// @param  u32SystemTime  \b IN: system time in ms
2280 /// @return TRUE - succeed
2281 //-------------------------------------------------------------------------------------------------
2282 MS_BOOL MsOS_SetSystemTime (MS_U32 u32SystemTime)
2283 {
2284     MS_U32 u32COUNT = u32SystemTime*TICK_PER_ONE_MS*CYGNUM_HAL_RTC_PERIOD;
2285 
2286     asm volatile (
2287         "move $8,%0;"
2288         "mtc0 $8,$9;"
2289         "nop; nop; nop;"
2290         :
2291         : "r"(u32COUNT)
2292         : "$8"
2293         );
2294 
2295     return TRUE;
2296 }
2297 */
2298 
2299 //
2300 // Queue
2301 //
2302 //-------------------------------------------------------------------------------------------------
2303 /// Create a Queue
2304 /// @param  pStartAddr      \b IN: It is useless now, can pass NULL.
2305 /// @param  u32QueueSize    \b IN: queue size (byte unit) : now fixed as
2306 ///                                CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE * u32MessageSize
2307 /// @param  eMessageType    \b IN: E_MSG_FIXED_SIZE / E_MSG_VAR_SIZE
2308 /// @param  u32MessageSize  \b IN: message size (byte unit) for E_MSG_FIXED_SIZE
2309 ///                                max message size (byte unit) for E_MSG_VAR_SIZE
2310 /// @param  eAttribute      \b IN: E_MSOS_FIFO suspended in FIFO order
2311 /// @param  pQueueName      \b IN: queue name
2312 /// @return assigned message queue ID
2313 /// @return < 0 - fail
2314 //-------------------------------------------------------------------------------------------------
MsOS_CreateQueue(void * pStartAddr,MS_U32 u32QueueSize,MessageType eMessageType,MS_U32 u32MessageSize,MsOSAttribute eAttribute,char * pQueueName)2315 MS_S32 MsOS_CreateQueue (void         *pStartAddr,
2316                          MS_U32           u32QueueSize,
2317                       MessageType   eMessageType,
2318                          MS_U32           u32MessageSize,
2319                       MsOSAttribute eAttribute,
2320                       char         *pQueueName)
2321 {
2322     // Note: eCos Kernel does not provide message queue API; use POSIX API instead ?
2323 
2324     MS_S32 s32Id;
2325 
2326     cyg_mutex_lock( &_MsOS_Queue_Mutex);
2327     for( s32Id=0; s32Id<MSOS_QUEUE_MAX; s32Id++)
2328     {
2329         if(_MsOS_Queue_Info[s32Id].bUsed == FALSE)
2330         {
2331             break;
2332         }
2333     }
2334     if(s32Id < MSOS_QUEUE_MAX)
2335     {
2336         _MsOS_Queue_Info[s32Id].bUsed = TRUE;
2337         _MsOS_Queue_Info[s32Id].u32AlignedMsgSize = ALIGN_4(u32MessageSize);
2338 
2339         // Allocate memory for queue.
2340         _MsOS_Queue_Info[s32Id].pu8MsgQueue =
2341             MsOS_AllocateMemory((ALIGN_4(u32MessageSize)+sizeof(MS_U32))*
2342                                 (CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE+1),
2343                                 gs32SystemPoolID);
2344         if(!_MsOS_Queue_Info[s32Id].pu8MsgQueue)
2345         {
2346             _MsOS_Queue_Info[s32Id].bUsed = FALSE;
2347             return -1;
2348         }
2349         _MsOS_Queue_Info[s32Id].u32MsgWriteIdx = 0;
2350         _MsOS_Queue_Info[s32Id].eMsgType = eMessageType;
2351     }
2352     cyg_mutex_unlock( &_MsOS_Queue_Mutex);
2353 
2354     if(s32Id >= MSOS_QUEUE_MAX)
2355     {
2356         return -1;
2357     }
2358     cyg_mutex_init(&_MsOS_Queue_Info[s32Id].stMutex);
2359 
2360     /* no E_MSG_VAR_SIZE for POSIX message queue
2361     switch(u32MessageType)
2362     {
2363     case E_MSG_FIXED_SIZE:
2364         msg_type = NU_FIXED_SIZE;
2365         break;
2366     case E_MSG_VAR_SIZE:
2367         msg_type = NU_VARIABLE_SIZE;
2368         break;
2369     default:
2370         return -1;
2371         break;
2372     }
2373     */
2374     /* ONLY Priority order for POSIX message queue
2375     switch(eAttribute)
2376     {
2377     case E_MSOS_PRIORITY:
2378         suspend_type = NU_PRIORITY;
2379         break;
2380     case E_MSOS_FIFO:
2381         suspend_type = NU_FIFO;
2382         break;
2383     default:
2384         return -1;
2385         break;
2386     }
2387     */
2388 
2389     //no Priority order for eCos
2390     //pQueueName is not used for eCos
2391 
2392     // u32QueueSize: fixed as CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE
2393     cyg_mbox_create( &_MsOS_Queue_Info[s32Id].stQueue, &_MsOS_Queue_Info[s32Id].stQueueInfo);
2394     /*
2395     if ( _MsOS_Queue_Info[s32Id].stQueue < 0 )
2396     {
2397         cyg_mutex_lock( &_MsOS_Queue_Mutex);
2398         _MsOS_Queue_Info[s32Id].bUsed = FALSE;
2399         cyg_mutex_unlock( &_MsOS_Queue_Mutex);
2400         s32Id = -1;
2401     }
2402     */
2403 
2404     s32Id |= MSOS_ID_PREFIX;
2405     return s32Id;
2406 
2407 }
2408 
2409 //-------------------------------------------------------------------------------------------------
2410 /// Delete the Queue
2411 /// @param  s32QueueId  \b IN: Queue ID
2412 /// @return TRUE : succeed
2413 /// @return FALSE :  fail
2414 /// @note   It is important that there are not any threads blocked on the queue
2415 ///             when this function is called or the behavior is undefined.
2416 //-------------------------------------------------------------------------------------------------
MsOS_DeleteQueue(MS_S32 s32QueueId)2417 MS_BOOL MsOS_DeleteQueue (MS_S32 s32QueueId)
2418 {
2419     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2420     {
2421         return FALSE;
2422     }
2423     else
2424     {
2425         s32QueueId &= MSOS_ID_MASK;
2426     }
2427 
2428     cyg_mbox_delete( _MsOS_Queue_Info[s32QueueId].stQueue);
2429     if(_MsOS_Queue_Info[s32QueueId].pu8MsgQueue)
2430     {
2431         MsOS_FreeMemory(_MsOS_Queue_Info[s32QueueId].pu8MsgQueue, gs32SystemPoolID);
2432     }
2433     cyg_mutex_destroy(&_MsOS_Queue_Info[s32QueueId].stMutex);
2434 
2435     cyg_mutex_lock( &_MsOS_Queue_Mutex);
2436     _MsOS_Queue_Info[s32QueueId].pu8MsgQueue = NULL;
2437     _MsOS_Queue_Info[s32QueueId].bUsed = FALSE;
2438     cyg_mutex_unlock( &_MsOS_Queue_Mutex);
2439     return TRUE;
2440 }
2441 
2442 //-------------------------------------------------------------------------------------------------
2443 /// Send a message to the end of the specified queue
2444 /// @param  s32QueueId  \b IN: Queue ID
2445 /// @param  pu8Message  \b IN: ptr to msg to send. NULL ptr is not allowed
2446 /// @param  u32Size     \b IN: msg size (byte)
2447 /// @param  u32WaitMs   \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the queue is full
2448 /// @return TRUE : succeed
2449 /// @return FALSE :  fail
2450 //-------------------------------------------------------------------------------------------------
MsOS_SendToQueue(MS_S32 s32QueueId,MS_U8 * pu8Message,MS_U32 u32Size,MS_U32 u32WaitMs)2451 MS_BOOL MsOS_SendToQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32Size, MS_U32 u32WaitMs)
2452 {
2453     MS_BOOL bRet = FALSE;
2454     MS_U32 *pu32MsgPos;
2455 
2456     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2457     {
2458         return FALSE;
2459     }
2460     else
2461     {
2462         s32QueueId &= MSOS_ID_MASK;
2463     }
2464 
2465     //coz cyg_mbox_get will return NULL for error
2466     if ( pu8Message==NULL)
2467     {
2468         return FALSE;
2469     }
2470 
2471     if(u32Size > _MsOS_Queue_Info[s32QueueId].u32AlignedMsgSize)
2472     {
2473         return FALSE;
2474     }
2475 
2476     if ( u32WaitMs != 0)
2477     {
2478         MS_ASSERT( MsOS_In_Interrupt() == FALSE );
2479     }
2480 
2481     if(u32WaitMs == 0)
2482     {
2483         if(cyg_mutex_trylock(&_MsOS_Queue_Info[s32QueueId].stMutex) == FALSE)
2484         {
2485             return FALSE;
2486         }
2487     }
2488     else
2489     {
2490         cyg_mutex_lock(&_MsOS_Queue_Info[s32QueueId].stMutex);
2491     }
2492 
2493     // Copy message.
2494     if(_MsOS_Queue_Info[s32QueueId].pu8MsgQueue)
2495     {
2496         pu32MsgPos = (MS_U32*)(_MsOS_Queue_Info[s32QueueId].pu8MsgQueue +
2497                             _MsOS_Queue_Info[s32QueueId].u32MsgWriteIdx *
2498                             (_MsOS_Queue_Info[s32QueueId].u32AlignedMsgSize + sizeof(MS_U32)));
2499         pu32MsgPos[0] = u32Size;
2500         memcpy(pu32MsgPos+1, pu8Message, u32Size);
2501     }
2502     else
2503     {
2504         cyg_mutex_unlock(&_MsOS_Queue_Info[s32QueueId].stMutex);
2505         return FALSE;
2506     }
2507 
2508     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
2509     {
2510         cyg_mbox_put( _MsOS_Queue_Info[s32QueueId].stQueue, pu32MsgPos);
2511         bRet = TRUE;
2512     }
2513     else if (u32WaitMs==0) //non-blocking
2514     {
2515         if ( cyg_mbox_tryput( _MsOS_Queue_Info[s32QueueId].stQueue, pu32MsgPos) )
2516         {
2517             bRet = TRUE;
2518         }
2519     }
2520     else //blocking wait with timeout
2521     {
2522         if ( cyg_mbox_timed_put( _MsOS_Queue_Info[s32QueueId].stQueue, pu32MsgPos,
2523                                  cyg_current_time()+u32WaitMs*TICK_PER_ONE_MS) )
2524         {
2525             bRet = TRUE;
2526         }
2527     }
2528 
2529     if(bRet)
2530     {
2531         _MsOS_Queue_Info[s32QueueId].u32MsgWriteIdx =
2532             (_MsOS_Queue_Info[s32QueueId].u32MsgWriteIdx + 1) %
2533             (CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE+1);
2534     }
2535 
2536     cyg_mutex_unlock(&_MsOS_Queue_Info[s32QueueId].stMutex);
2537     return bRet;
2538 }
2539 
2540 //-------------------------------------------------------------------------------------------------
2541 /// Receive a message from the specified queue
2542 /// @param  s32QueueId      \b IN: Queue ID
2543 /// @param  pu8Message      \b OUT: msg destination
2544 /// @param  u32IntendedSize \b IN: intended msg size (byte unit) to receive:
2545 /// @param  pu32ActualSize  \b OUT: actual msg size (byte unit) received
2546 /// @param  u32WaitMs       \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the queue is empty
2547 /// @return TRUE : succeed
2548 /// @return FALSE :  fail
2549 //-------------------------------------------------------------------------------------------------
MsOS_RecvFromQueue(MS_S32 s32QueueId,MS_U8 * pu8Message,MS_U32 u32IntendedSize,MS_U32 * pu32ActualSize,MS_U32 u32WaitMs)2550 MS_BOOL MsOS_RecvFromQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32IntendedSize, MS_U32 *pu32ActualSize, MS_U32 u32WaitMs)
2551 {
2552     MS_BOOL bRet = FALSE;
2553     void *pItem;
2554 
2555     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2556     {
2557         return FALSE;
2558     }
2559     else
2560     {
2561         s32QueueId &= MSOS_ID_MASK;
2562     }
2563 
2564     MS_ASSERT( MsOS_In_Interrupt() == FALSE );
2565 
2566     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
2567     {
2568         pItem = cyg_mbox_get( _MsOS_Queue_Info[s32QueueId].stQueue);
2569     }
2570     else if (u32WaitMs==0) //non-blocking
2571     {
2572         pItem = cyg_mbox_tryget( _MsOS_Queue_Info[s32QueueId].stQueue );
2573     }
2574     else //blocking wait with timeout
2575     {
2576         pItem = cyg_mbox_timed_get( _MsOS_Queue_Info[s32QueueId].stQueue,
2577                                     cyg_current_time()+u32WaitMs*TICK_PER_ONE_MS);
2578     }
2579 
2580     if ( pItem == NULL )
2581     {
2582         *pu32ActualSize = 0;
2583         bRet = FALSE;
2584     }
2585     else
2586     {
2587         if(u32IntendedSize < *(MS_U32*)pItem)
2588         {
2589             *pu32ActualSize = u32IntendedSize;
2590         }
2591         else
2592         {
2593             *pu32ActualSize = *(MS_U32*)pItem;
2594         }
2595         memcpy(pu8Message, ((MS_U32*)pItem)+1, *pu32ActualSize);
2596         bRet = TRUE;
2597     }
2598 
2599     return bRet;
2600 }
2601 
2602 //-------------------------------------------------------------------------------------------------
2603 /// Receive a message from the specified queue
2604 /// @param  s32QueueId      \b IN: Queue ID
2605 /// @param  pu8Message      \b OUT: msg destination
2606 /// @param  u32IntendedSize \b IN: intended msg size (byte unit) to receive:
2607 /// @param  pu32ActualSize  \b OUT: actual msg size (byte unit) received
2608 /// @return TRUE : succeed
2609 /// @return FALSE :  fail
2610 //-------------------------------------------------------------------------------------------------
MsOS_PeekFromQueue(MS_S32 s32QueueId,MS_U8 * pu8Message,MS_U32 u32IntendedSize,MS_U32 * pu32ActualSize)2611 MS_BOOL MsOS_PeekFromQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32IntendedSize, MS_U32 *pu32ActualSize)
2612 {
2613     MS_BOOL bRet = FALSE;
2614     void *pItem;
2615 
2616     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2617     {
2618         return FALSE;
2619     }
2620     else
2621     {
2622         s32QueueId &= MSOS_ID_MASK;
2623     }
2624 
2625     MS_ASSERT( MsOS_In_Interrupt() == FALSE );
2626 
2627     pItem= cyg_mbox_peek_item( _MsOS_Queue_Info[s32QueueId].stQueue );
2628 
2629     if ( pItem == NULL )
2630     {
2631         *pu32ActualSize = 0;
2632         bRet = FALSE;
2633     }
2634     else
2635     {
2636         if(u32IntendedSize < *(MS_U32*)pItem)
2637         {
2638             *pu32ActualSize = u32IntendedSize;
2639         }
2640         else
2641         {
2642             *pu32ActualSize = *(MS_U32*)pItem;
2643         }
2644         memcpy(pu8Message, ((MS_U32*)pItem)+1, *pu32ActualSize);
2645         bRet = TRUE;
2646     }
2647 
2648     return bRet;
2649 }
2650 
2651 //-------------------------------------------------------------------------------------------------
2652 // Get a Queue information
2653 // @param  s32QueueId      \b IN: Queue ID
2654 // @param  pu32QueueSize   \b OUT: ptr to queue size (DW)
2655 // @param  pu32MessageSize \b OUT: ptr to message size (DW)
2656 // @param  peAttribute     \b OUT: ptr to suspended mode: E_MSOS_FIFO / E_MSOS_PRIORITY
2657 // @param  pQueueName      \b OUT: ptr to Queue name
2658 // @return TRUE : succeed
2659 // @return FALSE : the Queue has not been created
2660 //-------------------------------------------------------------------------------------------------
MsOS_InfoQueue(MS_S32 s32QueueId,MS_U32 * pu32QueueSize,MS_U32 * pu32MessageSize,MsOSAttribute * peAttribute,char * pQueueName)2661 MS_BOOL MsOS_InfoQueue ( MS_S32 s32QueueId, MS_U32 *pu32QueueSize, MS_U32 *pu32MessageSize,
2662                       MsOSAttribute *peAttribute, char *pQueueName)
2663 {
2664     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2665     {
2666         return FALSE;
2667     }
2668     else
2669     {
2670         s32QueueId &= MSOS_ID_MASK;
2671     }
2672 
2673     //ToDo
2674     return FALSE;
2675 }
2676 
2677 //
2678 // Atomic operation
2679 //
MsOS_AtomicSet(MsOS_Atomic * pAtomic,MS_S32 s32Value)2680 void MsOS_AtomicSet(MsOS_Atomic *pAtomic, MS_S32 s32Value)
2681 {
2682     pAtomic->s32Value = s32Value;
2683 }
2684 
MsOS_AtomicRead(const MsOS_Atomic * pAtomic)2685 MS_S32 MsOS_AtomicRead(const MsOS_Atomic *pAtomic)
2686 {
2687     return pAtomic->s32Value;
2688 }
2689 
MsOS_AtomicAdd(MsOS_Atomic * pAtomic,MS_S32 s32Value)2690 void MsOS_AtomicAdd(MsOS_Atomic *pAtomic, MS_S32 s32Value)
2691 {
2692     cyg_interrupt_disable();
2693     pAtomic->s32Value += s32Value;
2694     cyg_interrupt_enable();
2695 }
2696 
MsOS_AtomicSub(MsOS_Atomic * pAtomic,MS_S32 s32Value)2697 void MsOS_AtomicSub(MsOS_Atomic *pAtomic, MS_S32 s32Value)
2698 {
2699     cyg_interrupt_disable();
2700     pAtomic->s32Value -= s32Value;
2701     cyg_interrupt_enable();
2702 }
2703 
MsOS_AtomicAddReturn(MsOS_Atomic * pAtomic,MS_S32 s32Value)2704 MS_S32 MsOS_AtomicAddReturn(MsOS_Atomic *pAtomic, MS_S32 s32Value)
2705 {
2706     MS_S32 s32Ret;
2707 
2708     cyg_interrupt_disable();
2709     pAtomic->s32Value += s32Value;
2710     s32Ret = pAtomic->s32Value;
2711     cyg_interrupt_enable();
2712 
2713     return s32Ret;
2714 }
2715 
MsOS_AtomicSubReturn(MsOS_Atomic * pAtomic,MS_S32 s32Value)2716 MS_S32 MsOS_AtomicSubReturn(MsOS_Atomic *pAtomic, MS_S32 s32Value)
2717 {
2718     MS_S32 s32Ret;
2719 
2720     cyg_interrupt_disable();
2721     pAtomic->s32Value -= s32Value;
2722     s32Ret = pAtomic->s32Value;
2723     cyg_interrupt_enable();
2724 
2725     return s32Ret;
2726 }
2727 
2728 
2729 //
2730 // Per-thread data
2731 //
2732 //-------------------------------------------------------------------------------------------------
2733 /// Per-thread data index creation
2734 /// @param  pu32Index  \b OUT: the new per-thread data index
2735 /// @return TRUE : succeed
2736 /// @return FALSE :  fail
2737 //-------------------------------------------------------------------------------------------------
MsOS_CreateThreadDataIndex(MS_U32 * pu32Index)2738 MS_BOOL MsOS_CreateThreadDataIndex(MS_U32 *pu32Index)
2739 {
2740     if(pu32Index != NULL)
2741     {
2742         *pu32Index = cyg_thread_new_data_index();
2743         return TRUE;
2744     }
2745 
2746     return FALSE;
2747 }
2748 
2749 //-------------------------------------------------------------------------------------------------
2750 /// Per-thread data index deletion
2751 /// @param  u32Index  \b IN: the per-thread data index
2752 /// @return TRUE : succeed
2753 /// @return FALSE :  fail
2754 //-------------------------------------------------------------------------------------------------
MsOS_DeleteThreadDataIndex(MS_U32 u32Index)2755 MS_BOOL MsOS_DeleteThreadDataIndex(MS_U32 u32Index)
2756 {
2757     cyg_thread_free_data_index(u32Index);
2758     return TRUE;
2759 }
2760 
2761 //-------------------------------------------------------------------------------------------------
2762 /// Set per-thread data by index
2763 /// @param  u32Index  \b IN: the per-thread data index
2764 /// @param  u32Data  \b IN: the per-thread data
2765 /// @return TRUE : succeed
2766 /// @return FALSE :  fail
2767 //-------------------------------------------------------------------------------------------------
MsOS_SetThreadData(MS_U32 u32Index,MS_U32 u32Data)2768 MS_BOOL MsOS_SetThreadData(MS_U32 u32Index, MS_U32 u32Data)
2769 {
2770     cyg_thread_set_data(u32Index, u32Data);
2771     return TRUE;
2772 }
2773 
2774 //-------------------------------------------------------------------------------------------------
2775 /// Get per-thread data by index
2776 /// @param  u32Index  \b IN: the per-thread data index
2777 /// @param  pu32Data  \b OUT: the per-thread data
2778 /// @return TRUE : succeed
2779 /// @return FALSE :  fail
2780 //-------------------------------------------------------------------------------------------------
MsOS_GetThreadData(MS_U32 u32Index,MS_U32 * pu32Data)2781 MS_BOOL MsOS_GetThreadData(MS_U32 u32Index, MS_U32 *pu32Data)
2782 {
2783     if(pu32Data != NULL)
2784     {
2785         *pu32Data = cyg_thread_get_data(u32Index);
2786         return TRUE;
2787     }
2788 
2789     return FALSE;
2790 }
2791 
2792 //
2793 // Condition Variables
2794 //
2795 //-------------------------------------------------------------------------------------------------
2796 /// Create a condition variable
2797 /// @param  s32MutexId  \b IN: associated mutex
2798 /// @param  pCondName  \b IN: condition variable name
2799 /// @return >=0 : assigned condition variable Id
2800 /// @return <0 : fail
2801 /// @note
2802 //-------------------------------------------------------------------------------------------------
MsOS_CreateCondition(MS_S32 s32MutexId,const char * pCondName)2803 MS_S32 MsOS_CreateCondition(MS_S32 s32MutexId, const char *pCondName)
2804 {
2805     MS_S32 s32Id;
2806     cyg_cond_t stCond;
2807 
2808     if((s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX)
2809     {
2810         return -1;
2811     }
2812     else
2813     {
2814         s32MutexId &= MSOS_ID_MASK;
2815     }
2816 
2817     cyg_mutex_lock(&_MsOS_Condition_Mutex);
2818     for(s32Id = 0; s32Id < MSOS_CONDITION_MAX; s32Id++)
2819     {
2820         if(_MsOS_Condition_Info[s32Id].bUsed == FALSE)
2821         {
2822             break;
2823         }
2824     }
2825 
2826     if(s32Id < MSOS_CONDITION_MAX)
2827     {
2828         _MsOS_Condition_Info[s32Id].bUsed = TRUE;
2829     }
2830     cyg_mutex_unlock(&_MsOS_Condition_Mutex);
2831 
2832     if(s32Id >= MSOS_CONDITION_MAX)
2833     {
2834         return -1;
2835     }
2836 
2837     //pCondName is not used for eCos
2838 
2839     cyg_cond_init(&stCond, &_MsOS_Mutex_Info[s32MutexId].stMutex);
2840 
2841     cyg_mutex_lock(&_MsOS_Condition_Mutex);
2842     _MsOS_Condition_Info[s32Id].stCond = stCond;
2843     cyg_mutex_unlock(&_MsOS_Condition_Mutex);
2844 
2845     s32Id |= MSOS_ID_PREFIX;
2846 
2847     return s32Id;
2848 }
2849 
2850 //-------------------------------------------------------------------------------------------------
2851 /// Delete the specified condition variable
2852 /// @param  s32CondId  \b IN: condition variable ID
2853 /// @return TRUE : succeed
2854 /// @return FALSE : fail
2855 /// @note
2856 //-------------------------------------------------------------------------------------------------
MsOS_DeleteCondition(MS_S32 s32CondId)2857 MS_BOOL MsOS_DeleteCondition(MS_S32 s32CondId)
2858 {
2859     if((s32CondId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX)
2860     {
2861         return FALSE;
2862     }
2863     else
2864     {
2865         s32CondId &= MSOS_ID_MASK;
2866     }
2867 
2868     cyg_cond_destroy(&_MsOS_Condition_Info[s32CondId].stCond);
2869 
2870     cyg_mutex_lock(&_MsOS_Condition_Mutex);
2871     _MsOS_Condition_Info[s32CondId].bUsed = FALSE;
2872     cyg_mutex_unlock(&_MsOS_Condition_Mutex);
2873 
2874     return TRUE;
2875 }
2876 
2877 //-------------------------------------------------------------------------------------------------
2878 /// Wait on a condition
2879 /// @param  s32CondId  \b IN: condition variable ID
2880 /// @param  u32WaitMs   \b IN: 1 ~ MSOS_WAIT_FOREVER: condition variable timeout
2881 /// @return TRUE : succeed
2882 /// @return FALSE : fail
2883 //-------------------------------------------------------------------------------------------------
MsOS_WaitCondition(MS_S32 s32CondId,MS_U32 u32WaitMs)2884 MS_BOOL MsOS_WaitCondition(MS_S32 s32CondId, MS_U32 u32WaitMs)
2885 {
2886     if(u32WaitMs == 0)
2887     {
2888         return FALSE;
2889     }
2890 
2891     if((s32CondId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX)
2892     {
2893         return FALSE;
2894     }
2895     else
2896     {
2897         s32CondId &= MSOS_ID_MASK;
2898     }
2899 
2900     MS_ASSERT(MsOS_In_Interrupt() == FALSE);
2901 
2902     if (u32WaitMs == MSOS_WAIT_FOREVER) //blocking wait
2903     {
2904         cyg_cond_wait(&_MsOS_Condition_Info[s32CondId].stCond);
2905         return TRUE;
2906     }
2907 
2908     cyg_cond_timed_wait(&_MsOS_Condition_Info[s32CondId].stCond,
2909             cyg_current_time() + u32WaitMs * TICK_PER_ONE_MS);
2910     return TRUE;
2911 }
2912 
2913 //-------------------------------------------------------------------------------------------------
2914 /// Signal a condition
2915 /// @param  s32CondId  \b IN: condition variable ID
2916 /// @return TRUE : succeed
2917 /// @return FALSE : fail
2918 //-------------------------------------------------------------------------------------------------
MsOS_SignalCondition(MS_S32 s32CondId)2919 MS_BOOL MsOS_SignalCondition(MS_S32 s32CondId)
2920 {
2921     if((s32CondId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX)
2922     {
2923         return FALSE;
2924     }
2925     else
2926     {
2927         s32CondId &= MSOS_ID_MASK;
2928     }
2929 
2930     cyg_cond_signal(&_MsOS_Condition_Info[s32CondId].stCond);
2931 
2932     return TRUE;
2933 }
2934 
2935 //-------------------------------------------------------------------------------------------------
2936 /// Broadcast a condition
2937 /// @param  s32CondId  \b IN: condition variable ID
2938 /// @return TRUE : succeed
2939 /// @return FALSE : fail
2940 //-------------------------------------------------------------------------------------------------
MsOS_BroadcastCondition(MS_S32 s32CondId)2941 MS_BOOL MsOS_BroadcastCondition(MS_S32 s32CondId)
2942 {
2943     if((s32CondId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX)
2944     {
2945         return FALSE;
2946     }
2947     else
2948     {
2949         s32CondId &= MSOS_ID_MASK;
2950     }
2951 
2952     cyg_cond_broadcast(&_MsOS_Condition_Info[s32CondId].stCond);
2953 
2954     return TRUE;
2955 }
2956 
2957 //
2958 // Spinlock
2959 // The spinlock of the eCos doesn't work in the preemptive multi-level queue scheduler.
2960 // Use scheduler control and IRQ dis/enable instead
2961 //
MsOS_CreateSpin(MsOSAttribute eAttribute,char * pSpinName)2962 MS_S32 MsOS_CreateSpin(MsOSAttribute eAttribute, char *pSpinName)
2963 {
2964     return 0;
2965 }
2966 
MsOS_DeleteSpin(MS_S32 s32SpinId)2967 MS_BOOL MsOS_DeleteSpin(MS_S32 s32SpinId)
2968 {
2969     return TRUE;
2970 }
2971 
MsOS_ObtainSpin(MS_S32 s32SpinId)2972 MS_BOOL MsOS_ObtainSpin(MS_S32 s32SpinId)
2973 {
2974     cyg_scheduler_lock();
2975     return TRUE;
2976 }
2977 
MsOS_ReleaseSpin(MS_S32 s32SpinId)2978 MS_BOOL MsOS_ReleaseSpin(MS_S32 s32SpinId)
2979 {
2980     cyg_scheduler_unlock();
2981     return TRUE;
2982 }
2983 
MsOS_ObtainSpinIrqSave(MS_S32 s32SpinId,MS_U32 * pu32Flag)2984 MS_BOOL MsOS_ObtainSpinIrqSave(MS_S32 s32SpinId, MS_U32 *pu32Flag)
2985 {
2986     CYG_INTERRUPT_STATE s;
2987 
2988     MS_ASSERT(pu32Flag != NULL);
2989 
2990     HAL_DISABLE_INTERRUPTS(s);
2991     *pu32Flag = s;
2992 
2993     return TRUE;
2994 }
2995 
MsOS_ReleaseSpinIrqSave(MS_S32 s32SpinId,MS_U32 u32Flag)2996 MS_BOOL MsOS_ReleaseSpinIrqSave(MS_S32 s32SpinId, MS_U32 u32Flag)
2997 {
2998     CYG_INTERRUPT_STATE s = u32Flag;
2999     HAL_RESTORE_INTERRUPTS(s);
3000 
3001     return TRUE;
3002 }
3003 
3004 
3005 //
3006 // Interrupt management
3007 //
3008 //-------------------------------------------------------------------------------------------------
3009 /// Attach the interrupt callback function to interrupt #
3010 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3011 /// @param  pIntCb  \b IN: Interrupt callback function
3012 /// @return TRUE : succeed
3013 /// @return FALSE :  fail
3014 //-------------------------------------------------------------------------------------------------
MsOS_AttachInterrupt(InterruptNum eIntNum,InterruptCb pIntCb)3015 MS_BOOL MsOS_AttachInterrupt (InterruptNum eIntNum, InterruptCb pIntCb)
3016 {
3017     cyg_mutex_lock(&_MsOS_HISR_Mutex);
3018 
3019     CHIP_AttachISR(eIntNum, pIntCb);
3020 
3021     cyg_mutex_unlock(&_MsOS_HISR_Mutex);
3022 
3023     return TRUE;
3024 }
3025 
3026 //-------------------------------------------------------------------------------------------------
3027 /// Detach the interrupt callback function from interrupt #
3028 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3029 /// @return TRUE : succeed
3030 /// @return FALSE :  fail
3031 //-------------------------------------------------------------------------------------------------
MsOS_DetachInterrupt(InterruptNum eIntNum)3032 MS_BOOL MsOS_DetachInterrupt (InterruptNum eIntNum)
3033 {
3034     cyg_mutex_lock(&_MsOS_HISR_Mutex);
3035 
3036     CHIP_DetachISR(eIntNum);
3037 
3038     cyg_mutex_unlock(&_MsOS_HISR_Mutex);
3039 
3040     return TRUE;
3041 }
3042 
3043 //-------------------------------------------------------------------------------------------------
3044 /// Enable (unmask) the interrupt #
3045 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3046 /// @return TRUE : succeed
3047 /// @return FALSE :  fail
3048 //-------------------------------------------------------------------------------------------------
MsOS_EnableInterrupt(InterruptNum eIntNum)3049 MS_BOOL MsOS_EnableInterrupt (InterruptNum eIntNum)
3050 {
3051     return CHIP_EnableIRQ(eIntNum);
3052 }
3053 
3054 //-------------------------------------------------------------------------------------------------
3055 /// Disable (mask) the interrupt #
3056 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3057 /// @return TRUE : succeed
3058 //-------------------------------------------------------------------------------------------------
MsOS_DisableInterrupt(InterruptNum eIntNum)3059 MS_BOOL MsOS_DisableInterrupt (InterruptNum eIntNum)
3060 {
3061     CHIP_DisableIRQ(eIntNum);
3062 
3063     return TRUE;
3064 }
3065 
3066 //-------------------------------------------------------------------------------------------------
3067 /// Disable all interrupts (including timer interrupt), the scheduler is disabled.
3068 /// @return Interrupt register value before all interrupts disable
3069 //-------------------------------------------------------------------------------------------------
MsOS_DisableAllInterrupts(void)3070 MS_U32 MsOS_DisableAllInterrupts(void)
3071 {
3072     MS_U32                 u32OldInterrupts;
3073     HAL_DISABLE_INTERRUPTS(u32OldInterrupts);
3074     return u32OldInterrupts;
3075 }
3076 
3077 //-------------------------------------------------------------------------------------------------
3078 /// Restore the interrupts from last MsOS_DisableAllInterrupts.
3079 /// @param  u32OldInterrupts \b IN: Interrupt register value from @ref MsOS_DisableAllInterrupts
3080 /// @return TRUE : succeed
3081 //-------------------------------------------------------------------------------------------------
MsOS_RestoreAllInterrupts(MS_U32 u32OldInterrupts)3082 MS_BOOL MsOS_RestoreAllInterrupts(MS_U32 u32OldInterrupts)
3083 {
3084     HAL_RESTORE_INTERRUPTS(u32OldInterrupts);
3085     return TRUE;
3086 }
3087 
3088 //-------------------------------------------------------------------------------------------------
3089 /// Enable all CPU interrupts.
3090 /// @return TRUE : succeed
3091 //-------------------------------------------------------------------------------------------------
MsOS_EnableAllInterrupts(void)3092 MS_BOOL MsOS_EnableAllInterrupts(void)
3093 {
3094     HAL_ENABLE_INTERRUPTS();
3095     return TRUE;
3096 }
3097 
3098 //-------------------------------------------------------------------------------------------------
3099 /// In Interuupt Context or not
3100 /// @return TRUE : Yes
3101 /// @return FALSE : No
3102 //-------------------------------------------------------------------------------------------------
MsOS_In_Interrupt(void)3103 MS_BOOL MsOS_In_Interrupt (void)
3104 {
3105     return CHIP_InISRContext();
3106 }
3107 //-------------------------------------------------------------------------------------------------
3108 /// Notify the interrupt complete #
3109 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3110 /// @return TRUE : succeed
3111 //-------------------------------------------------------------------------------------------------
MsOS_CompleteInterrupt(InterruptNum eIntNum)3112 MS_BOOL MsOS_CompleteInterrupt (InterruptNum eIntNum)
3113 {
3114     return TRUE;
3115     //return CHIP_CompleteIRQ(eIntNum);
3116 }
3117 
3118 #include <cyg/hal/hal_cache.h>
3119 //-------------------------------------------------------------------------------------------------
3120 /// Write back if dirty & Invalidate the cache lines in the given range
3121 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
3122 /// @param  u32Size  \b IN: size (must be 16-B aligned)
3123 /// @return TRUE : succeed
3124 /// @return FALSE : fail due to invalide parameter
3125 //-------------------------------------------------------------------------------------------------
3126 
MsOS_Dcache_Flush(MS_U32 u32Start,MS_U32 u32Size)3127 MS_BOOL MsOS_Dcache_Flush( MS_U32 u32Start, MS_U32 u32Size )
3128 {
3129     return MsOS_MPool_Dcache_Flush(u32Start,u32Size);
3130 }
3131 
3132 //-------------------------------------------------------------------------------------------------
3133 /// Invalidate the cache lines in the given range
3134 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
3135 /// @param  u32Size  \b IN: size (must be 16-B aligned)
3136 /// @return TRUE : succeed
3137 /// @return FALSE : fail due to invalide parameter
3138 //-------------------------------------------------------------------------------------------------
MsOS_Dcache_Invalidate(MS_U32 u32Start,MS_U32 u32Size)3139 MS_BOOL MsOS_Dcache_Invalidate( MS_U32 u32Start, MS_U32 u32Size )
3140 {
3141     MS_U32 u32OldIntr;
3142     if ( (u32Start % DCACHE_LINE_SIZE) || ( (u32Start & (MS_U32)KSEG1_BASE) != (MS_U32)KSEG0_BASE) )
3143     {
3144         return FALSE;
3145     }
3146     u32OldIntr = MsOS_DisableAllInterrupts();
3147     HAL_DCACHE_INVALIDATE( u32Start, u32Size);
3148     //flush EC's write FIFO
3149     MAsm_CPU_Sync();
3150     MsOS_RestoreAllInterrupts(u32OldIntr);
3151     return TRUE;
3152 }
3153 
3154 //-------------------------------------------------------------------------------------------------
3155 /// Write back if dirty the cache lines in the given range
3156 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
3157 /// @param  u32Size  \b IN: size (must be 16-B aligned)
3158 /// @return TRUE : succeed
3159 /// @return FALSE : fail due to invalide parameter
3160 //-------------------------------------------------------------------------------------------------
MsOS_Dcache_Writeback(MS_U32 u32Start,MS_U32 u32Size)3161 MS_BOOL MsOS_Dcache_Writeback( MS_U32 u32Start, MS_U32 u32Size )
3162 {
3163     MS_U32 u32OldIntr;
3164     if ( (u32Start % DCACHE_LINE_SIZE) || ( (u32Start & (MS_U32)KSEG1_BASE) != (MS_U32)KSEG0_BASE) )
3165     {
3166         return FALSE;
3167     }
3168     u32OldIntr = MsOS_DisableAllInterrupts();
3169     printf("WARNING: this ecos doesn't enable the dcache_store\b");
3170 //TODO:    HAL_DCACHE_STORE( u32Start, u32Size);
3171     //flush EC's write FIFO
3172     MAsm_CPU_Sync();
3173     MsOS_RestoreAllInterrupts(u32OldIntr);
3174     return TRUE;
3175 }
3176 
MsOS_VA2PA(MS_VIRT addr)3177 MS_PHY MsOS_VA2PA(MS_VIRT addr)
3178 {
3179     return MsOS_MPool_VA2PA(addr);
3180 }
3181 
MsOS_PA2KSEG0(MS_PHY addr)3182 MS_VIRT MsOS_PA2KSEG0(MS_PHY addr)
3183 {
3184     return MsOS_MPool_PA2KSEG0(addr);
3185 }
3186 
MsOS_PA2KSEG1(MS_PHY addr)3187 MS_VIRT MsOS_PA2KSEG1(MS_PHY addr)
3188 {
3189     return MsOS_MPool_PA2KSEG1(addr);
3190 }
3191 
3192 #define SHM_SIZE                (200*1024)
3193 #define MAX_CLIENT_NUM          320
3194 typedef struct
3195 {
3196     MS_U8       u8ClientName[MAX_CLIENT_NAME_LENGTH+ 1];
3197     MS_U32      u32Offset;
3198     MS_U32      u32Size;
3199     MS_U8       u8ClientId;    // 0 means "never used"
3200     MS_U8       u8RefCnt;
3201     MS_U8       u8Dummy[2];
3202 } MsOS_SHM_Context;
3203 
3204 typedef struct
3205 {
3206     MS_U32              u32MaxClientNum;
3207     MS_U32              u32ClientNum;
3208     MS_U32              u32ShmSize;
3209     MS_U32              u32Offset;
3210     MsOS_SHM_Context    context[MAX_CLIENT_NUM];
3211 } MsOS_SHM_Hdr;
3212 
3213 static int _shm_id = -1;
3214 static MS_U8 *_pu8ShareMem = NULL;
3215 static MsOS_SHM_Hdr _ShmHdr; // dummy storage
3216 
3217 // Share memory operation
3218 // MS_BOOL MsOS_SHM_Init(MS_U32 u32ShmSize)
MsOS_SHM_Init(void)3219 MS_BOOL MsOS_SHM_Init(void)
3220 {
3221     MS_BOOL bInit = FALSE;
3222     MS_U32 u32ShmSize;
3223 
3224     if (-1 != _shm_id)
3225     {
3226         return FALSE;
3227     }
3228 
3229     u32ShmSize = SHM_SIZE;
3230     u32ShmSize += sizeof(MsOS_SHM_Hdr);
3231     u32ShmSize += ((1<< 12)- 1);
3232     u32ShmSize = (u32ShmSize>> 12)<< 12; // make it 4KBytes alignment
3233 
3234     if (NULL == (_pu8ShareMem = (MS_U8*)malloc(u32ShmSize)))
3235     {
3236         printf("[%s][%d] fail\n", __FUNCTION__, __LINE__);
3237         return FALSE;
3238     }
3239     _shm_id = (int)_pu8ShareMem;
3240 
3241     bInit = TRUE;
3242     if (bInit)
3243     {
3244 #if 0
3245         MsOS_SHM_Hdr* pHdr;
3246 
3247         // printf("[%s][%d] Clear share memory header\n", __FUNCTION__, __LINE__);
3248         memset(_pu8ShareMem, 0, sizeof(MsOS_SHM_Hdr));
3249         pHdr = (MsOS_SHM_Hdr*) _pu8ShareMem;
3250 
3251         pHdr->u32MaxClientNum = MAX_CLIENT_NUM;
3252         pHdr->u32ClientNum = 0;
3253         pHdr->u32ShmSize = u32ShmSize;
3254         pHdr->u32Offset = (sizeof(MsOS_SHM_Hdr)+3)&~3;
3255 #else
3256         memset(&_ShmHdr, 0, sizeof(_ShmHdr)); // dummy storage
3257         _ShmHdr.u32MaxClientNum = MAX_CLIENT_NUM;
3258         _ShmHdr.u32ClientNum = 0;
3259         _ShmHdr.u32ShmSize = u32ShmSize;
3260         _ShmHdr.u32Offset = (sizeof(MsOS_SHM_Hdr)+7)&~7;
3261         memcpy(_pu8ShareMem, &_ShmHdr, sizeof(_ShmHdr));
3262 #endif
3263     }
3264     return TRUE;
3265 }
3266 
3267 // Share memory operation
MsOS_SHM_GetId(MS_U8 * pu8ClientName,MS_U32 u32BufSize,MS_U32 * pu32ShmId,MS_U32 * pu32Addr,MS_U32 * pu32BufSize,MS_U32 u32Flag)3268 MS_BOOL MsOS_SHM_GetId(MS_U8* pu8ClientName, MS_U32 u32BufSize, MS_U32* pu32ShmId, MS_U32* pu32Addr, MS_U32* pu32BufSize, MS_U32 u32Flag)
3269 {
3270     MsOS_SHM_Context* pContext = NULL;
3271     MsOS_SHM_Context* pClient = NULL;
3272     MS_U32 i;
3273     MS_U32 u32CopyLen;
3274 
3275     if (!_pu8ShareMem)
3276     {
3277         printf("[%s][%d] MsOS_SHM_Init should be invoked first\n", __FUNCTION__, __LINE__);
3278         return FALSE;
3279     }
3280 
3281     memcpy(&_ShmHdr, _pu8ShareMem, sizeof(_ShmHdr));
3282     pContext = (MsOS_SHM_Context*)_ShmHdr.context;
3283     for (i= 0; i< MAX_CLIENT_NUM; i++, pContext++)
3284     {
3285         if (0 == pContext->u8ClientId)
3286         {
3287             continue;
3288         }
3289         if (0== strcmp((const char*)pContext->u8ClientName, (const char*)pu8ClientName))
3290         {
3291             pClient = pContext;
3292             if (u32BufSize != pClient->u32Size)
3293             {
3294                 printf("[%s][%d] MsOS_SHM_GetId: inconsistent buffer size with other process\n", __FUNCTION__, __LINE__);
3295             }
3296             break;
3297         }
3298     }
3299     if ((NULL == pClient) && (MSOS_SHM_CREATE == u32Flag))
3300     {
3301         pContext = (MsOS_SHM_Context*)_ShmHdr.context;
3302         for (i= 0; i< MAX_CLIENT_NUM; i++, pContext++)
3303         {
3304             if (pContext->u8ClientId)
3305             {
3306                 continue;
3307             }
3308             if ((_ShmHdr.u32Offset + u32BufSize)> _ShmHdr.u32ShmSize)
3309             {
3310                 printf("[%s][%d] MsOS_SHM_GetId: shared memory buffer overflow\n", __FUNCTION__, __LINE__);
3311                 return FALSE;
3312             }
3313             _ShmHdr.u32ClientNum++;
3314             pClient = pContext;
3315             u32CopyLen = MIN((int)strlen((const char*)pu8ClientName), MAX_CLIENT_NAME_LENGTH);
3316             strncpy((char*)pClient->u8ClientName, (const char*)pu8ClientName, u32CopyLen);
3317             pClient->u32Size = u32BufSize;
3318             pClient->u8ClientId = i+ 1;
3319             pClient->u8RefCnt = 0;
3320             pClient->u32Offset = _ShmHdr.u32Offset;
3321             _ShmHdr.u32Offset += (u32BufSize+7)&~7;
3322             memcpy(_pu8ShareMem, &_ShmHdr, sizeof(_ShmHdr));
3323             break;
3324         }
3325     }
3326     if (NULL == pClient)
3327     {
3328         PRINT_INFO("[%s][%d] MsOS_SHM_Init: Unable to get available share memeory\n", __FUNCTION__, __LINE__);
3329         return FALSE;
3330     }
3331     *pu32ShmId = pClient->u8ClientId;
3332     *pu32BufSize = pClient->u32Size;
3333     *pu32Addr = (MS_U32)_pu8ShareMem + pClient->u32Offset;
3334     return TRUE;
3335 }
3336 
MsOS_SHM_FreeId(MS_U8 * pu8ClientName,MS_U32 u32ShmId)3337 MS_BOOL MsOS_SHM_FreeId(MS_U8* pu8ClientName, MS_U32 u32ShmId)
3338 {
3339     return TRUE;
3340 }
3341 
3342 //-------------------------------------------------------------------------------------------------
3343 /// Disable the CPU interrupt
3344 /// @return Interrupt register value before all interrupts disable
3345 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DisableInterrupt(void)3346 MS_U32 MsOS_CPU_DisableInterrupt (void)
3347 {
3348     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3349     return FALSE;
3350 }
3351 
3352 //-------------------------------------------------------------------------------------------------
3353 /// Enable the CPU interrupt
3354 /// @return TRUE : succeed
3355 //-------------------------------------------------------------------------------------------------
MsOS_CPU_EnableInterrupt(void)3356 MS_BOOL MsOS_CPU_EnableInterrupt (void)
3357 {
3358     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3359     return FALSE;
3360 }
3361 
3362 //-------------------------------------------------------------------------------------------------
3363 /// Restore the CPU interrupt from last MsOS_CPU_DisableInterrupts.
3364 /// @param  u32OldInterrupts \b IN: Interrupt register value from @ref MsOS_CPU_DisableInterrupts
3365 /// @return TRUE : succeed
3366 //-------------------------------------------------------------------------------------------------
MsOS_CPU_RestoreInterrupt(MS_U32 u32OldInterrupts)3367 MS_BOOL MsOS_CPU_RestoreInterrupt (MS_U32 u32OldInterrupts)
3368 {
3369     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3370     return FALSE;
3371 }
3372 
3373 //-------------------------------------------------------------------------------------------------
3374 /// Mask all the CPU interrupt
3375 /// @return TRUE : succeed
3376 //-------------------------------------------------------------------------------------------------
MsOS_CPU_MaskAllInterrupt(void)3377 MS_BOOL MsOS_CPU_MaskAllInterrupt (void)
3378 {
3379     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3380     return FALSE;
3381 }
3382 
3383 //-------------------------------------------------------------------------------------------------
3384 /// Mask the CPU interrupt
3385 /// @param  intr_num \b IN: Interrupt number in enumerator MHAL_INTERRUPT_TYPE
3386 /// @return TRUE : succeed
3387 //-------------------------------------------------------------------------------------------------
MsOS_CPU_MaskInterrupt(MHAL_INTERRUPT_TYPE intr_num)3388 MS_BOOL MsOS_CPU_MaskInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3389 {
3390     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3391     return FALSE;
3392 }
3393 
3394 //-------------------------------------------------------------------------------------------------
3395 /// UnMask the CPU interrupt
3396 /// @param  intr_num \b IN: Interrupt number in enumerator MHAL_INTERRUPT_TYPE
3397 /// @return TRUE : succeed
3398 //-------------------------------------------------------------------------------------------------
MsOS_CPU_UnMaskInterrupt(MHAL_INTERRUPT_TYPE intr_num)3399 MS_BOOL MsOS_CPU_UnMaskInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3400 {
3401     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3402     return FALSE;
3403 }
3404 
3405 //-------------------------------------------------------------------------------------------------
3406 /// Lock the CPU interrupt
3407 /// @return TRUE : succeed
3408 //-------------------------------------------------------------------------------------------------
MsOS_CPU_LockInterrupt(void)3409 MS_BOOL MsOS_CPU_LockInterrupt (void)
3410 {
3411     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3412     return FALSE;
3413 }
3414 
3415 //-------------------------------------------------------------------------------------------------
3416 /// UnLock the CPU interrupt
3417 /// @return TRUE : succeed
3418 //-------------------------------------------------------------------------------------------------
MsOS_CPU_UnLockInterrupt(void)3419 MS_BOOL MsOS_CPU_UnLockInterrupt (void)
3420 {
3421     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3422     return FALSE;
3423 }
3424 
3425 //-------------------------------------------------------------------------------------------------
3426 /// Attach the CPU interrupt callback function to interrupt #
3427 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3428 /// @param  pIntCb  \b IN: Interrupt callback function
3429 /// @param  dat  \b IN: Data
3430 /// @return TRUE : succeed
3431 //-------------------------------------------------------------------------------------------------
MsOS_CPU_AttachInterrupt(MHAL_INTERRUPT_TYPE intr_num,mhal_isr_t isr,MS_U32 dat)3432 MS_BOOL MsOS_CPU_AttachInterrupt (MHAL_INTERRUPT_TYPE intr_num, mhal_isr_t isr, MS_U32 dat)
3433 {
3434     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3435     return FALSE;
3436 }
3437 
3438 //-------------------------------------------------------------------------------------------------
3439 /// Detach the CPU interrupt callback function to interrupt #
3440 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3441 /// @param  pIntCb  \b IN: Interrupt callback function
3442 /// @param  dat  \b IN: Data
3443 /// @return TRUE : succeed
3444 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DetachInterrupt(MHAL_INTERRUPT_TYPE intr_num)3445 MS_BOOL MsOS_CPU_DetachInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3446 {
3447     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3448     return FALSE;
3449 }
3450 
3451 //-------------------------------------------------------------------------------------------------
3452 /// Attach the CPU exception callback function to interrupt #
3453 /// @param  eIntNum \b IN: Exception number in enumerator InterruptNum
3454 /// @param  pIntCb  \b IN: Exception callback function
3455 /// @param  dat  \b IN: Data
3456 /// @return TRUE : succeed
3457 //-------------------------------------------------------------------------------------------------
MsOS_CPU_AttachException(MHAL_EXCEPTION_TYPE expt_num,mhal_isr_t isr,MS_U32 dat)3458 MS_BOOL MsOS_CPU_AttachException (MHAL_EXCEPTION_TYPE expt_num, mhal_isr_t isr, MS_U32 dat)
3459 {
3460     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3461     return FALSE;
3462 }
3463 
3464 //-------------------------------------------------------------------------------------------------
3465 /// Detach the CPU exception callback function to interrupt #
3466 /// @param  eIntNum \b IN: Exception number in enumerator InterruptNum
3467 /// @param  pIntCb  \b IN: Exception callback function
3468 /// @param  dat  \b IN: Data
3469 /// @return TRUE : succeed
3470 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DetachExceptiont(MHAL_EXCEPTION_TYPE expt_num)3471 MS_BOOL MsOS_CPU_DetachExceptiont (MHAL_EXCEPTION_TYPE expt_num)
3472 {
3473     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3474     return FALSE;
3475 }
3476 //-------------------------------------------------------------------------------------------------
3477 /// Set EBASE
3478 /// @param  u32Addr \b IN: MIPS Code Start Address
3479 /// @return TRUE : succeed
3480 //-------------------------------------------------------------------------------------------------
MsOS_CPU_SetEBASE(MS_U32 u32Addr)3481 MS_BOOL MsOS_CPU_SetEBASE (MS_U32 u32Addr)
3482 {
3483     printf("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3484     return FALSE;
3485 }
3486 //-------------------------------------------------------------------------------------------------
3487 /// Sync data in EC-Brigde
3488 /// @return TRUE : succeed
3489 /// @return FALSE : fail
3490 //-------------------------------------------------------------------------------------------------
MsOS_Sync(void)3491 void MsOS_Sync(void)
3492 {
3493     MAsm_CPU_Sync();
3494 }
3495 
MsOS_FlushMemory(void)3496 void MsOS_FlushMemory(void)
3497 {
3498     HAL_MMIO_FlushMemory();
3499 }
3500 
MsOS_ReadMemory(void)3501 void MsOS_ReadMemory(void)
3502 {
3503     HAL_MMIO_ReadMemory();
3504 }
3505 
MsOS_GetKattribute(char * pAttr)3506 MS_U32 MsOS_GetKattribute(char *pAttr)
3507 {
3508     // This is for linux only, do nothing here
3509     return 0;
3510 }
3511 
3512 #endif
3513 
3514