Changes for L1 V20.03 onwards
[o-du/l2.git] / src / mt / mt_ss.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /********************************************************************20**
20
21      Name:     Multi-threaded System Services - Solaris
22
23      Type:     C source file
24
25      Desc:     C source code for the MTSS-Solaris implementation of
26                System Services.
27
28      File:     mt_ss.c
29
30 *********************************************************************21*/
31
32
33 \f
34 /* POSIX includes */
35 #ifndef _POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE         199309L
37 #endif
38 /* mt003.301 moved env files to use the __USE_UNIX98 flag in sys includes */
39
40 #include <fcntl.h>
41 #include <pthread.h>
42 #include <signal.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <sys/types.h>
46 #include <termios.h>
47 #include <time.h>
48 #include <unistd.h>
49 #include <sys/mman.h>
50  /* mt003.301: included sys/time.h
51   * for both solaris and linux
52   * */
53 #include <sys/time.h>
54  /* mt008.21: addition */
55 #include <errno.h>
56
57
58 \f
59 /* header include files (.h) */
60
61
62 #include "common_def.h"
63 #include "mt_ss.h"         /* MTSS specific */
64 #include "mt_err.h"        /* MTSS error defines */
65
66 #include "ss_queue.h"      /* queues */
67 #include "ss_task.h"       /* tasking */
68 #include "ss_msg.h"        /* messaging */
69 #include "ss_mem.h"        /* memory management interface */
70 #include "ss_gen.h"        /* general */
71 /* mt003.301 Additions - Task deregistration */
72 #include "ss_err.h"        /* error */
73 #include "cm_mem.h"        /* common memory manager */
74 /* mt001.301 : Additions */
75 #ifdef SS_THREAD_PROFILE
76 #include "ss_err.h"
77 #endif
78 #ifdef SS_LOCKLESS_MEMORY
79 #include "cm_llist.h"
80 #include "cm_hash.h"
81 #endif
82
83 /* multi-core support enhancement */
84 /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
85 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
86 #ifdef SS_LINUX
87 #include <sched.h>
88 #include <execinfo.h>
89 #else
90 #ifdef SUNOS
91 #include <sys/types.h>
92 #include <sys/processor.h>
93 #include <sys/procset.h>
94 #endif /* SUNOS */
95 #endif /* SS_LINUX */
96 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
97 /* mt001.301 : Additions */
98 #ifdef SS_WATCHDOG
99 #include <sys/types.h>
100 #include <sys/socket.h>
101 #include <netinet/in.h>
102 #include <arpa/inet.h>
103 #endif /* SS_WATCHDOG */
104
105 #ifdef SS_USE_WLS_MEM
106 #include <rte_common.h>
107 #include <rte_debug.h>
108 #include <rte_eal.h>
109 #endif
110
111 /* header/extern include files (.x) */
112
113 #include "gen.x"           /* general layer */
114 #include "ssi.x"           /* system services */
115
116 #include "cm5.x"           /* common timers */
117
118 #include "mt_ss.x"         /* MTSS specific */
119 #ifdef SS_LOCKLESS_MEMORY
120 #include "mt_ss_wl.x"         /* MTSS specific */
121 #endif /* SS_LOCKLESS_MEMORY */
122
123 #include "ss_queue.x"      /* queues */
124 #include "ss_task.x"       /* tasking */
125 #include "ss_timer.x"      /* timers */
126 #include "ss_strm.x"       /* STREAMS */
127 #include "ss_msg.x"        /* messaging */
128 #include "ss_mem.x"        /* memory management interface */
129 #include "ss_drvr.x"       /* driver tasks */
130 #include "ss_gen.x"        /* general */
131 #ifdef SS_LOCKLESS_MEMORY
132 #include "cm_llist.x"
133 #include "cm_hash.x"
134 #include "cm_mem_wl.x"        /* common memory manager */
135 #else
136 #include "cm_mem.x"        /* common memory manager */
137 #endif /* SS_LOCKLESS_MEMORY */
138 #include "cm_lte.x"        /* common memory manager */
139 /* mt001.301 : Additions */
140 #ifdef SS_LOGGER_SUPPORT
141 #include "cm_lib.x"
142 #endif /*  SS_LOGGER_SUPPORT */
143
144 /*mt005.301: Cavium Changes */
145 #ifdef SS_SEUM_CAVIUM
146 /* cvmx includes files */
147 #include "cvmx-config.h"
148 #include "cvmx.h"
149 #include "cvmx-pow.h"
150 #include "cvmx-tim.h"
151 #include "cvmx-fpa.h"
152 #include "cvmx-helper-fpa.h"
153 #include "cvmx-malloc.h"
154 #endif /* SS_SEUM_CAVIUM */
155
156 #ifdef L2_L3_SPLIT
157 #include "mt_plat_t33.h"
158 #include "mt_plat_t33.x"
159 #include "sys/syscall.h"
160 #endif
161
162 #if defined(RGL_SPECIFIC_CHANGES) || defined(INTEL_WLS) || defined(SS_USE_WLS_MEM)
163 #include <wls_lib.h>
164 #include <hugetlbfs.h>
165 #endif
166
167 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
168 S16 rgBatchProc (Void);
169 #endif
170 #ifdef RLC_MAC_DAT_REQ_RBUF
171 S16 rgDlDatReqBatchProc ARGS(( 
172          Void));
173 #endif
174 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
175 S16 rgBatchProc ARGS((
176     Void));
177 #endif  
178
179 #ifdef  TENB_T2K3K_SPECIFIC_CHANGES
180 /* general purpose debug zone  */
181 char            my_buffer2[4096 * 4] = { 0 };
182 char            my_buffer[4096] = { 0 };
183 int             my_buffer_idx = 0;
184
185
186 #define sigsegv_print(x, ...)    my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
187
188 struct sigcontext my_uc_mcontext = { 0 };
189
190
191 #include <unistd.h>
192 #include <signal.h>
193 #include <ucontext.h>
194 #include <dlfcn.h>
195
196
197 #define SIGSEGV_STACK_GENERIC
198 #define REGFORMAT "%x\n"
199
200 #ifdef XEON_SPECIFIC_CHANGES
201 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
202 #endif
203
204 void            dump_external(void);
205
206 static Void mtDelSigals(Void)
207 {
208    struct sigaction sa;
209
210    memset(&sa, 0, sizeof(struct sigaction));
211    sigemptyset(&sa.sa_mask);
212    sa.sa_handler = SIG_DFL;
213    sigaction(SIGSEGV, &sa, NULL);
214
215    memset(&sa, 0, sizeof(struct sigaction));
216    sigemptyset(&sa.sa_mask);
217    sa.sa_handler = SIG_DFL;
218    sigaction(SIGILL, &sa, NULL);
219
220    return;
221 }
222 static void signal_segv(int signum, siginfo_t * info, void *ptr)
223 {
224    static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
225    int             sz;
226    int             i;
227    ucontext_t     *ucontext = (ucontext_t *) ptr;
228 #ifdef XEON_SPECIFIC_CHANGES
229 #else
230    int            *p32 = (int *) 0x2fff0000;
231 #endif
232    void           *buffer[100];
233    char          **strings;
234
235    printf("\nsegv ooops @ %p\n", info->si_addr);
236    my_buffer2[0] = 1;
237
238    printf("\nSegmentation Fault!\n");
239    printf("\ninfo.si_signo = %d\n", signum);
240    printf("\ninfo.si_errno = %d\n", info->si_errno);
241    printf("\ninfo.si_code  = %d (%s)\n", info->si_code, si_codes[info->si_code]);
242    printf("\ninfo.si_addr  = %p\n", info->si_addr);
243
244    memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
245
246    i = 0;
247 #ifndef RGL_SPECIFIC_CHANGES
248    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
249    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
250    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
251    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
252    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
253    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
254    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
255    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
256    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
257    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
258    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
259    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
260    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
261    printf("\nreg[sp]       = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
262    printf("\nreg[lr]       = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
263    printf("\nreg[pc]       = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
264    printf("\nreg[cpsr]     = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
265 #endif
266
267    printf("\nStack trace (non-dedicated):\n");
268
269    sz = backtrace(buffer, 50);
270    strings = backtrace_symbols(buffer, sz);
271    for (i = 0; i < sz; ++i)
272       printf("%s\n", strings[i]);
273
274    printf("\nEnd of stack trace\n");
275
276 #ifdef XEON_SPECIFIC_CHANGES
277 #else
278    p32[0] = 1;
279 #endif
280
281    /* Lets first print our debug information */
282    printf("\nBefore dumping our Debug info\n");
283    mtStopHndlr();
284    printf("\nAfter dumping our Debug info\n");
285
286    /* Disable the signal and make the enodeb to dump. This will make
287     * eNB to generate the core with dumping the ccpu log
288     */
289    {
290       char           *abc = NULL;
291       mtDelSigals();
292       *abc = 100;
293    }
294    /* End printing debug information */
295    exit(1);
296    /*while (1);*/
297 }
298 #endif
299 /*** TBD: IMPORTANT ***
300  *** The following definition is temporary. This must be removed
301  *** when all products have been updated with latest ssi.h file OR
302  *** all ssi.h files have been updated to contain this definitions
303  ***/
304 /* New error class for FTHA added */
305 #ifndef ERRCLS_FTHA
306 #define ERRCLS_FTHA    0x8
307 #endif /* ERRCLS_FTHA */
308
309 typedef struct _SPThreadCreateArg
310 {
311    void *argument; /* argument that is to be passed to the actual pthread */
312    void *(*start_routine) (void *); /* function from which pthread starts */   
313 }SPThreadCreateArg;
314
315 void *pthreadCreateHdlr(void*  arg);
316
317 #ifdef SS_LOCKLESS_MEMORY
318 Buffer *mtTskBuffer1;
319 Buffer *mtTskBuffer2;
320
321 pthread_t tmpRegTidMap[20];
322 uint8_t stopBtInfo;
323 S16 SGlobMemInfoShow(void);
324 #endif /* SS_LOCKLESS_MEMORY */
325
326 #ifdef L2_L3_SPLIT
327 APP_CONTEXT AppContext;
328 S32 clusterMode;
329 #endif
330
331 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
332 unsigned int tlPost(void *handle);
333 #endif
334 \f
335 /* forward references */
336 /* mt003.301 Modifications - Moved to ss_gen.x */
337 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
338 Void *mtTskHdlrT2kL2 ARGS((Void*));
339 void mtSigSegvHndlr ARGS((void));
340 void mtSigUsr2Hndlr ARGS((void));
341 #endif
342
343 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
344 static Void *mtTskHdlr ARGS((void *));
345 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
346
347 static Void *mtTmrHdlr ARGS((void *));
348 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
349
350 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
351 static Void mtIntSigHndlr ARGS((int));
352 static Void mtExitClnup ARGS((void));
353
354 #ifdef CONAVL
355 static Void *mtConHdlr ARGS((void *));
356 #endif
357
358 #ifndef L2_L3_SPLIT
359 #ifdef SS_DRVR_SUPPORT
360 static Void *mtIsTskHdlr ARGS((void *));
361 #endif
362 #endif
363
364 /* mt020.201 - Addition for no command line available */
365 #ifndef NOCMDLINE
366 static Void mtGetOpts ARGS((void));
367 /* mt003.301 Additions - File Based task registration made
368  * common for both MULTICORE and NON-MULTICORE
369  */
370 static Bool fileBasedMemCfg = FALSE;
371 #endif
372
373 /* mt033.201 - addition of local function to print the statistics such as
374  * (size vs. numAttempts) and (allocations vs. deallocations)
375  */
376 #ifdef SSI_DEBUG_LEVEL1
377 static S16 SPrintRegMemStats ARGS((Region region));
378 #endif /* SSI_DEBUG_LEVEL1 */
379 \f
380 #ifdef SS_MULTICORE_SUPPORT
381 static SsSTskEntry* ssdAddTmrSTsk(Void);
382 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
383 #ifndef SS_LOCKLESS_MEMORY
384 #ifndef RGL_SPECIFIC_CHANGES
385 static S16 ssdInitMemInfo ARGS((void));
386 #endif
387 #endif
388 #endif
389
390 /* mt005.301: Cavium changes */
391 #ifdef SS_SEUM_CAVIUM
392 static Void *workRcvTsk ARGS((void *));
393 #endif /* SS_SEUM_CAVIUM */
394
395 #ifdef SS_THR_REG_MAP
396 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t  threadId,
397          Region region));
398 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t  threadId));
399 #endif /* SS_THR_REG_MAP */
400 \f
401 /* type declarations */
402
403 #ifdef SS_DRVR_SUPPORT
404 typedef struct mtIsFlag
405 {
406    uint16_t id;
407    uint8_t  action;
408
409 } MtIsFlag;
410 #endif
411
412
413 \f
414 /* public variable declarations */
415
416 Cntr cfgNumRegs = SS_MAX_REGS;
417 /* Set memory configuration as false.
418  * Set to true if memory configuration through file is successfull.
419  */
420 Bool memConfigured = FALSE;
421 /* mt022.201 - Modification for shared memory relay region and memcal tool */
422 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
423 {
424    {
425       SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
426       {
427          { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
428          { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
429          { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
430          { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
431          { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
432          { SS_POOL_STATIC, 0 }
433       }
434    }
435 #ifdef INTEL_WLS
436    ,
437       {
438          SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
439          {
440             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
441             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
442             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
443             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
444             { SS_POOL_STATIC, 0 }
445          }
446       }
447 #endif /* INTEL_WLS */
448
449 #ifdef SS_LOCKLESS_MEMORY
450    ,
451       {
452          SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
453          {
454             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
455             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
456             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
457             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
458             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
459             { SS_POOL_STATIC, 0 }
460          }
461       },
462       {
463          SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
464          {
465             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
466             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
467             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
468             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
469             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
470             { SS_POOL_STATIC, 0 }
471          }
472       },
473       {
474          SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
475          {
476             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
477             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
478             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
479             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
480             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
481             { SS_POOL_STATIC, 0 }
482          }
483       }, 
484       {
485          SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
486          {
487             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
488             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
489             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
490             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
491             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
492             { SS_POOL_STATIC, 0 }
493          }
494       },
495       {
496          SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
497          {
498             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
499             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
500             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
501             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
502             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
503             { SS_POOL_STATIC, 0 }
504          }
505       },
506       {
507          SS_DFLT_REGION + 6, SS_MAX_POOLS_PER_REG - 1,
508          {
509             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
510             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
511             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
512             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
513             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
514             { SS_POOL_STATIC, 0 }
515          }
516       }
517 #ifndef INTEL_WLS_MEM
518    ,
519       {
520          SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1,
521          {
522             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
523             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
524             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
525             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
526             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
527             { SS_POOL_STATIC, 0 }
528          }
529       }
530 #endif
531
532 #endif /* SS_LOCKLESS_MEMORY */
533 };
534 /* mt003.301 Modifications - File Based task registration made
535  * common for both MULTICORE and NON-MULTICORE
536  */
537
538 #ifdef SS_LOCKLESS_MEMORY
539 MtDynMemCfg mtDynMemoCfg =
540 {
541    SS_MAX_REGS,                                /* number of regions */
542    {
543       {
544          SS_DFLT_REGION,                         /* region id */
545          MT_MAX_BKTS,                            /* number of buckets */
546          {
547             /* block size, no. of blocks, Upper threshold, lower threshold */
548             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
549             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
550             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
551             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}, 
552             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
553          }
554       },
555       {
556          SS_DFLT_REGION + 1,                         /* region id */
557          MT_MAX_BKTS,                            /* number of buckets */
558          {
559             /* block size, no. of blocks, Upper threshold, lower threshold */
560             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
561             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
562             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
563             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
564             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD} 
565          }
566       },
567       {
568          SS_DFLT_REGION + 2,                         /* region id */
569          MT_MAX_BKTS,                            /* number of buckets */
570          {
571             /* block size, no. of blocks, Upper threshold, lower threshold */
572             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
573             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
574             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
575             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
576             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
577          }
578       },
579       {
580          SS_DFLT_REGION + 3,                         /* region id */
581          MT_MAX_BKTS,                            /* number of buckets */
582          {
583             /* block size, no. of blocks, Upper threshold, lower threshold */
584             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
585             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
586             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
587             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
588             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD} 
589          }
590       },
591       {
592          SS_DFLT_REGION + 4,                         /* region id */
593          MT_MAX_BKTS,                            /* number of buckets */
594          {
595             /* block size, no. of blocks, Upper threshold, lower threshold */
596             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
597             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
598             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
599             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
600             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
601          }
602       },
603       {
604          SS_DFLT_REGION + 5,                         /* region id */
605          MT_MAX_BKTS,                            /* number of buckets */
606          {
607             /* block size, no. of blocks, Upper threshold, lower threshold */
608             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
609             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
610             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
611             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
612             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
613          }
614       },
615       {
616          SS_DFLT_REGION + 6,                         /* region id */
617          MT_MAX_BKTS,                            /* number of buckets */
618          {
619             /* block size, no. of blocks, Upper threshold, lower threshold */
620             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
621             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
622             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
623             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
624             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
625          }
626       }
627 #ifndef INTEL_WLS_MEM
628       ,
629          {
630             SS_DFLT_REGION + 7,                         /* region id */
631             MT_MAX_BKTS,                            /* number of buckets */
632             {
633                /* block size, no. of blocks, Upper threshold, lower threshold */
634                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
635                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
636                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
637                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
638                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
639             }
640          }
641 #endif
642 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
643       ,
644          {
645             SS_DFLT_REGION + 7,                         /* region id */
646             MT_MAX_BKTS,                            /* number of buckets */
647             {
648                /* block size, no. of blocks, Upper threshold, lower threshold */
649                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
650                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
651                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
652                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD} 
653             }
654          }
655 #endif
656    }
657
658 };
659
660 MtGlobMemCfg mtGlobMemoCfg =
661 {
662    MT_MAX_BKTS,                            /* number of buckets */
663    {
664 #if 1
665       /* block size, no. of blocks, Upper threshold, lower threshold */
666       {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
667       {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
668       {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
669       {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
670       {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
671 #else
672       {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
673          {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
674          {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
675          {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
676 #endif
677    }
678 };
679 #endif /* SS_LOCKLESS_MEMORY */
680
681 /* mt022.201 - Modification for memory calculator tool */
682 /* mt018.201 - added memory configuration matrix */
683 MtMemCfg mtMemoCfg =
684 {
685 #ifdef  RY_ENBS5SHM
686    SS_MAX_REGS - 1,                            /* number of regions */
687 #else
688 #ifndef XEON_SPECIFIC_CHANGES  
689    SS_MAX_REGS,                                /* number of regions */
690 #else
691    2,
692 #endif  
693 #endif
694    {
695       {
696          SS_DFLT_REGION,                         /* region id */
697          MT_MAX_BKTS,                            /* number of buckets */
698          MT_HEAP_SIZE,                           /* heap size */
699          {
700 #ifndef XEON_SPECIFIC_CHANGES  
701             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
702             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
703             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
704             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
705             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
706 #else
707             {256, 491520}, /* 60 pages of 2M*/
708                {512, 12288},  /* 3 pages of 2M */
709                {2048, 99328}, /* 97 Pages of 2M */
710                {8192, 75008}, /* 293 Pages of 2M */
711                {16384, 4096}  /* 32 pages of 2M */
712 #endif        
713          }
714       },
715 #ifdef INTEL_WLS
716 #ifndef SS_LOCKLESS_MEMORY    
717       {
718          SS_DFLT_REGION + 1,                         /* region id */
719          MT_MAX_BKTS,                            /* number of buckets */
720          /*MT_HEAP_SIZE 7194304 */ 10485760,                           /* heap size */
721          {
722             //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
723             //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
724             //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
725             //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}    /* block size, no. of blocks */
726             {128,   500000},
727             {256,   500000},
728             {2048,  200000},
729             {4096,  40960},
730             {18432, 10240}
731          }
732       },
733 #endif /* SS_LOCKLESS_MEMORY */
734 #endif /* INTEL_WLS */
735 #ifdef SS_LOCKLESS_MEMORY
736       {
737          SS_DFLT_REGION + 1,                         /* region id */
738          MT_MAX_BKTS,                            /* number of buckets */
739          MT_HEAP_SIZE,                           /* heap size */
740          {
741             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
742             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
743             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
744             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
745             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
746          }
747       },
748       {
749          SS_DFLT_REGION + 2,                         /* region id */
750          MT_MAX_BKTS,                            /* number of buckets */
751          MT_HEAP_SIZE,                           /* heap size */
752          {
753             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
754             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
755             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
756             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
757             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
758          }
759       },
760       {
761          SS_DFLT_REGION + 3,                         /* region id */
762          MT_MAX_BKTS,                            /* number of buckets */
763          MT_HEAP_SIZE,                           /* heap size */
764          {
765             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
766             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
767             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
768             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
769             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
770          }
771       },
772       {
773          SS_DFLT_REGION + 4,                         /* region id */
774          MT_MAX_BKTS,                            /* number of buckets */
775          MT_HEAP_SIZE,                           /* heap size */
776          {
777             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
778             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
779             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
780             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
781             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
782          }
783       },
784       {
785          SS_DFLT_REGION + 5,                         /* region id */
786          MT_MAX_BKTS,                            /* number of buckets */
787          MT_HEAP_SIZE,                           /* heap size */
788          {
789             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
790             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
791             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
792             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
793             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
794          }
795       },
796       {
797          SS_DFLT_REGION + 6,                         /* region id */
798          MT_MAX_BKTS,                            /* number of buckets */
799          MT_HEAP_SIZE,                           /* heap size */
800          {
801             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
802             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
803             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
804             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
805             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
806          }
807       }
808 #ifndef INTEL_WLS_MEM
809       ,
810          {
811             SS_DFLT_REGION + 7,                         /* region id */
812             MT_MAX_BKTS,                            /* number of buckets */
813             MT_HEAP_SIZE,                           /* heap size */
814             {
815                {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
816                {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
817                {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
818                {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
819                {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
820             }
821          }
822 #endif
823 #endif /* SS_LOCKLESS_MEMORY */
824       STATIC_MEM_CFG
825    }
826 };
827 /* mt003.301 Modifications - File Based task registration made
828  * common for both MULTICORE and NON-MULTICORE
829  * bucket info, as different regions may request for different no.
830  * of blocks
831  */
832 MtBktCfg mtBktInfo[MT_MAX_BKTS];
833 S16 msArgc;              /* argc */
834 Txt **msArgv;            /* argv */
835 S16 msOptInd;            /* SGetOpt vars */
836 S8 *msOptArg;            /* SGetOpt vars */
837
838
839 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
840 typedef struct _MtRegMemSz
841 {
842    uint32_t   reqdSz;
843    uint8_t    *startAddr;
844 }MtRegMemSz;
845
846 #ifdef SS_USE_WLS_MEM
847 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
848 static S16 SPartitionWlsDynMem();
849 static S16 SAllocateWlsDynMem();
850 #endif
851 #ifdef INTEL_WLS
852 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
853 #endif
854 #endif
855
856 \f
857 /* private variable declarations */
858 /* mt018.201 - change mtCMMRegCfg as array of pointers */
859 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
860 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
861 /* mt003.301 - Fixed compilation warnings */
862 /*mt004.301-addede new veriable for FAP*/
863 /*mt010.301 - removed veriable defined for FA*/
864
865
866 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
867
868 #ifdef NTL_LIB
869 void mtSetNtlHdl(unsigned int hdl)
870 {
871    osCp.ntl.hdl =  hdl;
872 }
873
874 unsigned int mtGetNtlHdl()
875 {
876    return(osCp.ntl.hdl);
877 }
878
879 #endif  /* NTL_LIB */
880 void mtGetWlsHdl(void **hdlr)
881 {
882    *hdlr = osCp.wls.intf;
883 }       
884
885 #ifdef XEON_MULTIPLE_CELL_CHANGES
886 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
887 S16 smWrReadWlsConfigParams (Void);
888 #endif
889
890 /*WLS Memory Size variables*/
891 #ifdef INTEL_L1_V20_03_ONWARDS
892 uint64_t        nWlsMacMemorySize = 0;
893 uint64_t        nWlsPhyMemorySize = 0;
894 #endif
895
896 static int SOpenWlsIntf()
897 {
898    uint8_t i;
899    void *hdl = NULLP;
900 #define WLS_DEVICE_NAME "wls0"
901
902    char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", WLS_DEVICE_NAME, "--iova-mode=pa"};
903    printf("\nCalling rte_eal_init: ");
904    for (i = 0; i < RTE_DIM(my_argv); i++)
905    {
906       printf("%s ", my_argv[i]); 
907    }
908    printf("\n");
909
910    if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
911       rte_panic("\nCannot init EAL\n");
912
913
914 #ifdef XEON_SPECIFIC_CHANGES
915 #ifdef XEON_MULTIPLE_CELL_CHANGES
916    hdl = WLS_Open(gWrWlsDeviceName, 1);
917 #else
918    hdl = WLS_Open(WLS_DEVICE_NAME, 1);
919 #endif
920 #else
921
922 #ifdef INTEL_L1_V20_03_ONWARDS
923    hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, &nWlsMacMemorySize, &nWlsPhyMemorySize);
924    if(hdl == NULL)
925    {
926       printf("\nERROR: WLS_Open > DEVICE_NAME mismatch. WLS Device Name should be same as 'wls_dev_name' parameter in 'phycfg_xran.xml' file");
927    }
928 #else
929    hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
930 #endif /*INTEL_L1_V20_03_ONWARDS*/
931
932 #endif
933
934    osCp.wls.intf = hdl;
935
936    if(!osCp.wls.intf)
937    {
938       printf("\nCould not open WLS Interface \n");
939       return (0);
940    }
941
942    return (1);
943 }
944 #endif
945
946 /* mt028.201 */
947 #ifndef API_MAIN
948 \f
949 /*
950  *
951  *       Fun:   main
952  *
953  *       Desc:  This function is the entry point for the final binary. It
954  *              calls SInit() in the common code. It can be replaced by a
955  *              user function if required (SInit() must still be called).
956  *
957  *       Ret:   none on success
958  *              exit on failure
959  *
960  *       Notes:
961  *
962  *       File:  mt_ss.c
963  *
964  */
965    int main
966 (
967  int argc,                       /* argument count */
968  char **argv                     /* argument vector */
969  )
970 {
971
972 #ifdef XEON_MULTIPLE_CELL_CHANGES
973    /* Read the WLS parameters from the file and copy into global control block */
974    if(smWrReadWlsConfigParams() != ROK)
975    {
976       fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
977       return RFAILED;
978    } /* end of if statement */
979 #endif
980
981 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
982    if(!SOpenWlsIntf())
983       return (0);
984 #endif /* INTEL_WLS */
985
986    msArgc = argc;
987    msArgv = argv;
988    /* mt003.301 Modifications */
989    if( ROK != SInit())
990    {
991       printf("\n SInit failed, SSI could not start \n");
992       /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
993
994       return (0);
995    }
996    /*mt010.301  cleanup part exposed to user*/
997    SFini();
998    return (0);
999 }
1000
1001 #else
1002 \f
1003 /*
1004  *
1005  *       Fun:   ssMain
1006  *
1007  *       Desc:  This function is the entry point for the final binary. It
1008  *              calls SInit() in the common code. It can be replaced by a
1009  *              user function if required (SInit() must still be called).
1010  *
1011  *       Ret:   none on success
1012  *              exit on failure
1013  *
1014  *       Notes:
1015  *
1016  *       File:  mt_ss.c
1017  *
1018  */
1019    int ssMain
1020 (
1021  int argc,                       /* argument count */
1022  char **argv                     /* argument vector */
1023  )
1024 {
1025
1026
1027    msArgc = argc;
1028    msArgv = argv;
1029
1030
1031    SInit();
1032
1033    return (0);
1034 }
1035
1036 #endif
1037 /*
1038  *  initialization functions
1039  */
1040
1041 /*
1042  *
1043  *       Fun:   Initialize OS control point
1044  *
1045  *       Desc:  This function initializes MTSS-specific information
1046  *              in the OS control point.
1047  *
1048  *       Ret:   ROK      - ok
1049  *
1050  *       Notes:
1051  *
1052  *       File:  mt_ss.c
1053  *
1054  */
1055 S16 ssdInitGen(void)
1056 {
1057    struct sigaction act;
1058    sigset_t set;
1059 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1060    struct sigaction sa;
1061 #endif
1062
1063
1064    /*mt014.301 : 4GMX release related changes*/
1065 #ifdef SS_4GMX_UCORE
1066    uarmInit();
1067 #endif
1068    /* mt005.301 : Cavium changes */
1069 #ifdef SS_SEUM_CAVIUM
1070    /* set group mask for the core */
1071    cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
1072 #endif /* SS_SEUM_CAVIUM */
1073
1074    osCp.dep.sysTicks = 0;
1075
1076    /* mt020.201 - Addition for no command line available */
1077 #ifndef NOCMDLINE
1078    /* parse command line */
1079    mtGetOpts();
1080    /* mt003.301 Additions */
1081    if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
1082    {
1083       printf("\n File Based Memory configuration failed \n");
1084       return RFAILED;
1085    }
1086 #endif
1087
1088 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
1089 #ifndef SS_LOCKLESS_MEMORY
1090 #ifdef SS_MULTICORE_SUPPORT
1091    if(memConfigured == FALSE)
1092       ssdInitMemInfo();
1093 #endif
1094 #endif
1095 #endif
1096
1097    /* initialize the started semaphore */
1098    if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1099    {
1100       return RFAILED;
1101    }
1102
1103    /* mt028.201 added compile time flag to allow not to mask signals */
1104 #ifndef UNMASK_SIG
1105    /* mask all signals in the main thread */
1106    sigfillset(&set);
1107    sigdelset(&set, SIGINT);
1108 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1109    sigdelset(&set, SIGSEGV);
1110    sigdelset(&set, SIGUSR2);
1111    sigdelset(&set, SIGILL);
1112 #ifdef XEON_SPECIFIC_CHANGES
1113    sigdelset(&set, SIGABRT);
1114    sigdelset(&set, SIGTERM);
1115    sigdelset(&set, SIGHUP);
1116 #endif   
1117 #endif
1118    pthread_sigmask(SIG_SETMASK, &set, NULLP);
1119 #endif /* UNMASK_SIG */
1120
1121    /* install a SIGINT handler to shutdown */
1122    /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1123
1124    /*Initialize SIGSEGV Signal */
1125 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1126 #if 1
1127    memset(&sa, 0, sizeof(struct sigaction));
1128    sigemptyset(&sa.sa_mask);
1129    sa.sa_sigaction = signal_segv;
1130    sa.sa_flags = SA_SIGINFO;
1131 #ifndef XEON_SPECIFIC_CHANGES
1132    sigaction(SIGSEGV, &sa, NULL);
1133
1134    memset(&sa, 0, sizeof(struct sigaction));
1135    sigemptyset(&sa.sa_mask);
1136    sa.sa_sigaction = signal_segv;
1137    sa.sa_flags = SA_SIGINFO;
1138
1139    sigaction(SIGILL, &sa, NULL);
1140 #else
1141    if(sigaction(SIGILL, &sa, NULL) != 0)
1142    {
1143       printf("\nFailed to process sigaction for the SIGILL\n");
1144       return RFAILED;
1145    }
1146    if(sigaction(SIGSEGV, &sa, NULL) != 0)
1147    {
1148       printf("\nFailed to process sigaction for the SIGSEGV\n");
1149       return RFAILED;
1150    }
1151    if(sigaction(SIGABRT, &sa, NULL) != 0)
1152    {
1153       printf("\nFailed to process sigaction for the SIGABRT\n");
1154       return RFAILED;
1155    }
1156    if(sigaction(SIGTERM, &sa, NULL) != 0)
1157    {
1158       printf("\nFailed to process sigaction for the SIGTERM\n");
1159       return RFAILED;
1160    }
1161    if(sigaction(SIGHUP, &sa, NULL) != 0)
1162    {
1163       printf("\nFailed to process sigaction for the SIGHUP\n");
1164       return RFAILED;
1165    }
1166 #endif    
1167 #else
1168    signal (SIGSEGV, mtSigSegvHndlr);
1169    signal (SIGKILL, mtSigSegvHndlr);
1170    signal (SIGUSR2, mtSigUsr2Hndlr);
1171 #endif   
1172 #endif
1173
1174 #ifdef MLOG_XEON
1175    signal (SIGINT, mtStopHndlr);
1176 #else
1177
1178    act.sa_handler = mtIntSigHndlr;
1179    sigfillset(&act.sa_mask);
1180    act.sa_flags = 0;
1181    if (sigaction(SIGINT, &act, NULLP) != 0)
1182    {
1183       return RFAILED;
1184    }
1185 #endif
1186
1187    /* mt040.201 initialise random seed */
1188    osCp.dep.randSeed = time(NULLP);
1189
1190    return ROK;
1191 }
1192
1193 \f
1194 /*
1195  *
1196  *       Fun:   De-initialize OS control point
1197  *
1198  *       Desc:  This function reverses the initialization in ssdInitGen().
1199  *
1200  *       Ret:   ROK      - ok
1201  *
1202  *       Notes:
1203  *
1204  *       File:  mt_ss.c
1205  *
1206  */
1207 Void ssdDeinitGen(void)
1208 {
1209
1210
1211    sem_destroy(&osCp.dep.ssStarted);
1212
1213
1214    return;
1215 }
1216 #ifdef SS_LOCKLESS_MEMORY
1217 #ifdef USE_MALLOC
1218 /*
1219  *
1220  *       Fun:   ssPutDynMemBlkSet
1221  *
1222  *       Desc:  Returns the set of dynamic Blocks into the global region
1223  *
1224  *
1225  *       Ret:   ROK     - successful, 
1226  *              RFAILED - unsuccessful.
1227  *
1228  *       Notes: 
1229  *
1230  *       File:  cm_mem.c
1231  *
1232  */
1233 S16 ssPutDynMemBlkSet
1234 (
1235  uint8_t                    bktIdx,        /* Index to bucket list */
1236  CmMmBlkSetElement    *dynMemSetElem  /* Memory set element which is needs to be 
1237                                          added to global region */
1238  )
1239 {
1240    CmMmGlobRegCb        *globReg;
1241    CmMmGlobalBktCb      *bktCb;
1242    Data                 *blkPtr;
1243    uint8_t                    blkCnt;
1244
1245    globReg = osCp.globRegCb;
1246
1247 #if (ERRCLASS & ERRCLS_INT_PAR)
1248    if(bktIdx >= globReg->numBkts)
1249    {
1250       return RFAILED;
1251    }
1252 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1253
1254    bktCb = &(globReg->bktTbl[bktIdx]);
1255
1256    for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1257    {
1258       blkPtr = dynMemSetElem->nextBktPtr;
1259       dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1260       free((Void *)blkPtr);
1261    }
1262
1263    dynMemSetElem->nextBktPtr = NULLP;
1264    dynMemSetElem->numFreeBlks = 0;
1265
1266    return ROK;
1267 }
1268
1269 /*
1270  *
1271  *       Fun:   ssGetDynMemBlkSet
1272  *
1273  *       Desc:  Gets the set of dynamic memory blocks from the global region
1274  *
1275  *
1276  *       Ret:   ROK     - successful, 
1277  *              RFAILED - unsuccessful.
1278  *
1279  *       Notes: 
1280  *
1281  *       File:  cm_mem.c
1282  *
1283  */
1284 S16 ssGetDynMemBlkSet
1285 (
1286  uint8_t               bktIdx,        /* Index to bucket list */
1287  CmMmBlkSetElement     *dynMemSetElem  /* Memory set element which is updated 
1288                                           with new set values */
1289  )
1290 {
1291
1292    CmMmGlobRegCb        *globReg;
1293    CmMmGlobalBktCb      *bktCb;
1294    Data                **basePtr;
1295    Data                 *blkPtr;
1296    uint8_t                    blkCnt;
1297
1298    globReg = osCp.globRegCb;
1299
1300 #if (ERRCLASS & ERRCLS_INT_PAR)
1301    if(bktIdx >= globReg->numBkts)
1302    {
1303       return RFAILED;
1304    }
1305 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1306
1307    bktCb   = &(globReg->bktTbl[bktIdx]);
1308    basePtr = &(dynMemSetElem->nextBktPtr);
1309
1310    for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1311    {
1312       blkPtr = (Data *)malloc(bktCb->size);
1313       *basePtr = blkPtr;
1314       basePtr = (CmMmEntry **)blkPtr;
1315    }
1316
1317    dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1318
1319    return ROK;
1320
1321 } /* ssGetDynMemBlkSet */
1322
1323 #else
1324 /*
1325  *
1326  *       Fun:   ssPutDynMemBlkSet
1327  *
1328  *       Desc:  Returns the set of dynamic Blocks into the global region
1329  *
1330  *
1331  *       Ret:   ROK     - successful, 
1332  *              RFAILED - unsuccessful.
1333  *
1334  *       Notes: 
1335  *
1336  *       File:  cm_mem.c
1337  *
1338  */
1339 S16 ssPutDynMemBlkSet
1340 (
1341  uint8_t              bktIdx,               /* Index to bucket list */
1342  CmMmBlkSetElement    *dynMemSetElem,        /* Memory set element which is needs to be 
1343                                                 added to global region */
1344  uint32_t             doNotBlockForLock    /* Boolean whether to block for lock or not */
1345  )
1346 {
1347    CmMmGlobRegCb       *globReg;
1348    CmMmGlobalBktCb     *bktCb;
1349    CmLList             *lstNode;
1350    CmMmBlkSetElement   *globMemNode;
1351    S16                  lockRet = 0;
1352
1353
1354    globReg = osCp.globRegCb;
1355
1356 #if (ERRCLASS & ERRCLS_INT_PAR)
1357    if(bktIdx >= globReg->numBkts)
1358    {
1359       return RFAILED;
1360    }
1361 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1362
1363    bktCb = &(globReg->bktTbl[bktIdx]);
1364
1365    /* Lock the global region first. If the doNotBlockForLock is non-zero, the 
1366       try lock is used as it is not required to block as it will be taken
1367       in the next go else it will be blocked for lock as we have to get the
1368       blocks must */
1369    {
1370       SLock(&(bktCb->bucketLock));
1371    }
1372
1373    if(lockRet == 0)
1374    {
1375
1376       /* Get a free node from the free node linked list */
1377       lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1378       if(lstNode == NULLP)
1379       {
1380          SUnlock(&(bktCb->bucketLock));
1381          return RFAILED;
1382       }
1383
1384       cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1385
1386       /* Copy the content of the received element information on to free node 
1387        * and add it to valid linked list */
1388       globMemNode = (CmMmBlkSetElement *)lstNode->node;
1389       globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1390       globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1391       dynMemSetElem->numFreeBlks = 0;
1392       dynMemSetElem->nextBktPtr = NULLP;
1393
1394       cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1395
1396       SUnlock(&(bktCb->bucketLock));
1397    }
1398
1399    return ROK;
1400 }
1401
1402 /*
1403  *
1404  *       Fun:   ssGetDynMemBlkSet
1405  *
1406  *       Desc:  Gets the set of dynamic memory blocks from the global region
1407  *
1408  *
1409  *       Ret:   ROK     - successful, 
1410  *              RFAILED - unsuccessful.
1411  *
1412  *       Notes: The parameter doNotBlockForLock specifies whether to block for lock
1413  *              or not 
1414  *
1415  *       File:  cm_mem.c
1416  *
1417  */
1418 S16 ssGetDynMemBlkSet
1419 (
1420  uint8_t                     bktIdx,              /* Index to bucket list */
1421  CmMmBlkSetElement     *dynMemSetElem,       /* Memory set element which is updated 
1422                                                 with new set values */
1423  uint32_t                    doNotBlockForLock    /* Boolean whether to block for lock or not */
1424  )
1425 {
1426    CmMmGlobRegCb        *globReg;
1427    CmMmGlobalBktCb      *bktCb;
1428    CmLList              *lstNode;
1429    CmMmBlkSetElement    *globMemNode;
1430    S16                   lockRet = 0;
1431
1432
1433    globReg = osCp.globRegCb;
1434
1435 #if (ERRCLASS & ERRCLS_INT_PAR)
1436    if(bktIdx >= globReg->numBkts)
1437    {
1438       return RFAILED;
1439    }
1440 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1441
1442    bktCb = &(globReg->bktTbl[bktIdx]);
1443
1444    /* Lock the global region first. If the doNotBlockForLock is non-zero, the 
1445       try lock is used as it is not required to block as it will be taken
1446       in the next go else it will be blocked for lock as we have to get the
1447       blocks must */
1448    {
1449       SLock(&(bktCb->bucketLock));
1450    }
1451
1452    if(lockRet == 0)
1453    {
1454       lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1455
1456       if(lstNode == NULLP)
1457       {
1458          SUnlock(&(bktCb->bucketLock));
1459          return RFAILED;
1460       }
1461
1462       /* Delete the node from the valid linked list and copy the values of the
1463        * elements of structrues into pointer */
1464       cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1465       globMemNode = (CmMmBlkSetElement *)lstNode->node;
1466       dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1467       dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1468
1469       /* Add this node to the free node linked list */
1470       cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1471
1472       SUnlock(&(bktCb->bucketLock));
1473    }
1474
1475    return ROK;
1476 } /* ssGetDynMemBlkSet */
1477
1478
1479 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1480 uint32_t gDynMemAlrm[4];
1481 static uint32_t memoryCheckCounter;
1482
1483 uint32_t isMemThreshReached(Region reg)
1484 {
1485    CmMmGlobRegCb        *globReg;
1486    CmMmGlobalBktCb      *bktCb;
1487    uint8_t bktIdx= reg;
1488
1489    globReg = osCp.globRegCb;
1490
1491 #if (ERRCLASS & ERRCLS_INT_PAR)
1492    if(bktIdx >= globReg->numBkts)
1493    {
1494       return RFAILED;
1495    }
1496 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1497
1498    bktCb   = &(globReg->bktTbl[bktIdx]);
1499
1500    if(gDynMemAlrm[bktIdx])
1501    {
1502       //        printf ("\nunder memory   bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1503       SLock(&(bktCb->bucketLock));
1504       if(bktCb->listValidBktSet.count > 25)
1505       {
1506          gDynMemAlrm[bktIdx] = FALSE;
1507          //      printf ("\nrecoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1508       }
1509       SUnlock(&(bktCb->bucketLock));
1510       return RFAILED;
1511    }
1512    else
1513    {
1514
1515       if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1516       {
1517          //    printf ("\nCHECK  bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1518          SLock(&(bktCb->bucketLock));
1519          if(bktCb->listValidBktSet.count < 15 )
1520             gDynMemAlrm[bktIdx] = TRUE;
1521          memoryCheckCounter = 0;
1522          SUnlock(&(bktCb->bucketLock));
1523       }
1524    }
1525    return ROK;
1526 }
1527
1528 #endif /* USE_MALLOC */
1529 #endif /* SS_LOCKLESS_MEMORY */
1530
1531 #ifdef SS_USE_ICC_MEMORY
1532 /*
1533  *
1534  *       Fun:   Initialize region/pool tables
1535  *
1536  *       Desc:  This function initializes MTSS-specific information
1537  *              in the region/pool tables and configures the common
1538  *              memory manager for use.
1539  *
1540  *       Ret:   ROK      - ok
1541  *
1542  *       Notes:
1543  *
1544  *       File:  mt_ss.c
1545  *
1546  */
1547 Void * ssGetIccHdl(Region region)
1548 {
1549    CmMmDynRegCb *dynRegCb;
1550
1551    /* Klock work fix ccpu00148484 */
1552    if(!(region < SS_MAX_REGS))
1553    {
1554       return (NULLP);
1555    }
1556
1557    dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb; 
1558
1559    return (dynRegCb->iccHdl);
1560 }
1561 #endif /* SS_USE_ICC_MEMORY */
1562
1563 #ifdef T2K_MEM_LEAK_DBG
1564 RegionMemLeakInfo regMemLeakInfo;
1565 #endif /* T2K_MEM_LEAK_DBG */
1566
1567 #ifdef SS_USE_WLS_MEM
1568 static S16 SPartitionWlsDynMem()
1569 {
1570    uint32_t i;
1571    uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1572
1573    for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1574    {
1575       mtDynMemSz[i].startAddr = bktMemStrtAddr;
1576       bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1577    }
1578
1579    printf("\nGlobal Memory Info: \n");
1580    for (i = 0 ; i <  mtGlobMemoCfg.numBkts ; i++)
1581    {
1582       printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1583    }
1584    return ROK;
1585 }
1586
1587 static S16 SAllocateWlsDynMem()
1588 {
1589    uint32_t     reqdMemSz;
1590    uint32_t     i;
1591    reqdMemSz = 0;
1592    memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1593
1594    for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1595    {
1596       reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1597       mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1598    }
1599    osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1600 #ifdef INTEL_L1_V20_03_ONWARDS
1601     nWlsMacMemorySize+nWlsPhyMemorySize);   
1602 #elif INTEL_L1_V19_10
1603          WLS_MEMORY_SIZE);
1604 #else
1605    (reqdMemSz + (4 * 1024 * 1024)));
1606 #endif
1607    printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1608    SPartitionWlsDynMem();
1609    return ROK;
1610 }
1611
1612 #endif
1613
1614 #ifdef INTEL_WLS
1615
1616 S16 SPartitionWlsMemory()
1617 {
1618    uint32_t    i;
1619 #ifndef ALIGN_64BIT
1620    uint64_t    reqdSz;
1621    uint64_t   pageSize[1], hugePageSize;
1622 #else
1623    long int reqdSz;
1624    long int pageSize[1], hugePageSize;
1625 #endif
1626    uint32_t numHugePg;
1627 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1628
1629    uint8_t   *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1630
1631    gethugepagesizes(pageSize,1);
1632    hugePageSize = pageSize[0];
1633    for (i = 0; i < 1; i++)
1634    {
1635       mtRegMemSz[i].startAddr = regMemStrtAddr;
1636       //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1637
1638       numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1639       reqdSz    = numHugePg * hugePageSize;
1640       regMemStrtAddr += reqdSz;
1641 #ifdef T2K_MEM_LEAK_DBG
1642       /* Since wls is region 0 */
1643       regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1644       regMemLeakInfo.numActvRegions++;
1645 #endif /* T2K_MEM_LEAK_DBG */
1646    }
1647    //Store last region addr for validation
1648    mtRegMemSz[i].startAddr = regMemStrtAddr;
1649    return ROK;
1650 }
1651
1652 #ifdef SS_MEM_WL_DEBUG
1653 Void SChkAddrValid(int type, int region, PTR ptr)
1654 {
1655    char *tryPtr = NULL;
1656    if(type == 0) //Global
1657    {
1658       if(ptr < mtRegMemSz[0].startAddr || ptr >=
1659             (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1660       {
1661          printf("\n****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1662          *tryPtr = 0;
1663       }
1664    }
1665    else
1666    {
1667       if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1668       {
1669          printf("\n****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1670          *tryPtr = 0;
1671       }
1672
1673    }
1674 }
1675 #endif /* SS_MEM_WL_DEBUG */
1676
1677 S16 SPartitionStaticMemory(uint8_t  *startAddr)
1678 {
1679    int    i;
1680    uint32_t    reqdSz;
1681
1682    uint8_t   *regMemStrtAddr = (uint8_t *)startAddr;
1683
1684
1685    //for (i = 0; i < mtMemoCfg.numRegions; i++)
1686    for (i = 1; i < mtMemoCfg.numRegions; i++)
1687    {
1688       mtRegMemSz[i].startAddr = regMemStrtAddr;
1689       reqdSz    = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1690       regMemStrtAddr += reqdSz;
1691 #ifdef T2K_MEM_LEAK_DBG
1692       {  /* Since region 1 onwards are used for non wls */
1693          regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1694          regMemLeakInfo.numActvRegions++;
1695       }
1696 #endif /* T2K_MEM_LEAK_DBG */
1697    }
1698    return ROK;
1699 }
1700 S16 SAllocateWlsMem()
1701 {
1702
1703    uint32_t            reqdMemSz;
1704    uint32_t            i, j;
1705    MtRegCfg       *region;
1706
1707    reqdMemSz = 0;
1708    //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1709    memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1710
1711    for (i = 0; i < 1; i++)
1712    {
1713       /* allocate space for the region */
1714       region = &mtMemoCfg.region[i];
1715       reqdMemSz += region->heapsize;
1716       mtRegMemSz[i].reqdSz  += region->heapsize;
1717
1718       for (j = 0; j < region->numBkts; j++)
1719       {
1720          reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1721          mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1722       }
1723    }
1724    osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1725    //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1726 #ifndef ALIGN_64BIT
1727    printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz); 
1728 #else
1729    printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz); 
1730 #endif
1731    SPartitionWlsMemory();
1732    return ROK;
1733 }
1734 S16 SAllocateStaticMem()
1735 {
1736
1737    uint32_t            reqdMemSz;
1738    int            i, j;
1739    MtRegCfg       *region;
1740    uint8_t             *startAddr;
1741
1742    reqdMemSz = 0;
1743    //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1744
1745    //for (i = 0; i < mtMemoCfg.numRegions; i++)
1746    for (i = 1; i <  mtMemoCfg.numRegions; i++)
1747    {
1748       /* allocate space for the region */
1749       region = &mtMemoCfg.region[i];
1750       reqdMemSz += region->heapsize;
1751       mtRegMemSz[i].reqdSz  += region->heapsize;
1752
1753       for (j = 0; j < region->numBkts; j++)
1754       {
1755          reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1756          mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1757       }
1758    }
1759
1760    startAddr = malloc(reqdMemSz + (1024 * 10));
1761 #ifndef ALIGN_64BIT
1762    printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz); 
1763 #else
1764    printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz); 
1765 #endif
1766    SPartitionStaticMemory(startAddr);
1767    return ROK;
1768 }
1769 #endif /* INTEL_WLS */
1770
1771 \f
1772 \f
1773 /*
1774  *
1775  *       Fun:   Initialize region/pool tables
1776  *
1777  *       Desc:  This function initializes MTSS-specific information
1778  *              in the region/pool tables and configures the common
1779  *              memory manager for use.
1780  *
1781  *       Ret:   ROK      - ok
1782  *
1783  *       Notes:
1784  *
1785  *       File:  mt_ss.c
1786  *
1787  */
1788 S16 ssdInitMem(void)
1789 {
1790    /* mt018.201 - added local variable */
1791    uint8_t              i =0;
1792    uint16_t             j =0;
1793    uint8_t              k =0;
1794    MtRegCfg       *region = NULLP;
1795    Txt             errMsg[256] = {'\0'};
1796 #ifdef SS_LOCKLESS_MEMORY
1797    CmMmDynRegCb   *dynRegCb =0;
1798 #ifdef SS_USE_ICC_MEMORY
1799 #else
1800    CmMmGlobRegCb  *globReg = NULLP;
1801    Size            memSize =0;
1802 #endif
1803 #endif /* SS_LOCKLESS_MEMORY */
1804
1805
1806    /* Use the default SSI memory manager if the ICC memory manager is not 
1807     * avilable. If ICC memory manager is avilable, it will be used for
1808     * all sharable memory allocation and de-allocation */
1809 #ifdef SS_LOCKLESS_MEMORY
1810 #ifdef SS_USE_ICC_MEMORY
1811 #ifndef YS_PHY_3_8_2
1812 #endif
1813    for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1814    {
1815       dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1816       if(dynRegCb == NULLP)
1817       {
1818          return RFAILED;
1819       }
1820       for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1821       {
1822          dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1823       }
1824       dynRegCb->region = i;
1825       cmMmDynRegInit(dynRegCb);
1826       printf("\niccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1827       sleep(1);
1828    }
1829    /*   ysIccHdl = dynRegCb->iccHdl; */
1830
1831 #else
1832    /* Initialize the global region first */
1833    osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1834
1835    if(osCp.globRegCb == NULLP)
1836    {
1837       return RFAILED;
1838    }
1839
1840    globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1841
1842 #ifdef SS_USE_WLS_MEM
1843    SAllocateWlsDynMem();
1844 #endif
1845
1846    for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1847    {
1848       memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1849 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1850       globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1851       printf("\nStarting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1852 #else
1853 #ifndef INTEL_WLS      
1854       globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1855 #else
1856       globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1857 #endif
1858 #endif
1859       if(globReg->bktTbl[i].startAddr == NULLP)
1860       {
1861          return RFAILED;
1862       }
1863       globReg->bktTbl[i].poolId = i;
1864       globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1865       globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1866       globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1867    }
1868
1869    globReg->numBkts = mtGlobMemoCfg.numBkts;
1870    cmMmGlobRegInit(globReg);
1871
1872    /* Initialize the dynamic task regions and sanity check for the theshold 
1873     * values */
1874    for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1875    {
1876       dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1877       if(dynRegCb == NULLP)
1878       {
1879          return RFAILED;
1880       }
1881       for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1882       {
1883          if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold < 
1884                   mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1885                (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1886                (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1887          {
1888 #ifdef XEON_SPECIFIC_CHANGES
1889             free(dynRegCb);
1890 #endif            
1891             return RFAILED;
1892          }
1893          dynRegCb->bktTbl[k].poolId = k;
1894          dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1895          dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1896          dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1897          dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1898          if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1899          {
1900             dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1901          }
1902       }
1903       dynRegCb->region = i;
1904       dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1905       cmMmDynRegInit(dynRegCb);
1906    }
1907 #endif /* SS_USE_ICC_MEMORY */
1908 #endif /* SS_LOCKLESS_MEMORY */
1909
1910 #ifdef T2K_MEM_LEAK_DBG
1911    uint8_t reg =0; 
1912    /* Initailize mem leak tool memorys for debguing */
1913    regMemLeakInfo.numActvRegions=0;
1914    for(reg=0; reg <SS_MAX_REGS; reg++)
1915    {   
1916       regMemLeakInfo.gMemLeakInfo[reg] =  malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1917       memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1918             sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1919       regMemLeakInfo.regStartAddr[reg] = 0;
1920
1921
1922       regMemLeakInfo.regStartAddr[reg] = 0;
1923       if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1924       {
1925          printf("\n mutex init failed\n");
1926          return RFAILED;
1927       }
1928    }
1929 #endif
1930 #ifdef INTEL_WLS
1931    /* Now allocate WLS memory */
1932    SAllocateWlsMem();
1933    SAllocateStaticMem();
1934 #endif
1935    /* mt018.201 - CMM Initialization */
1936    for (i = 0; i < mtMemoCfg.numRegions; i++)
1937    {
1938       /* allocate space for the region control block */
1939       mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1940 #ifdef TENB_RTLIN_CHANGES
1941       mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1942 #endif
1943       if (mtCMMRegCb[i] == NULLP)
1944       {
1945          sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1946                for the Region:%d control block\n",i);
1947          SPrint(errMsg);
1948          for (k = 0; k < i; k++)
1949          {
1950             cmMmRegDeInit(mtCMMRegCb[k]);
1951             free(mtCMMRegCfg[k]->vAddr);
1952             free(mtCMMRegCb[k]);
1953             free(mtCMMRegCfg[k]);
1954          }
1955          return RFAILED;
1956       }
1957
1958       mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1959 #ifdef TENB_RTLIN_CHANGES
1960       mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1961 #endif
1962       if (mtCMMRegCfg[i] == NULLP)
1963       {
1964          for (k = 0; k < i; k++)
1965          {
1966             cmMmRegDeInit(mtCMMRegCb[k]);
1967             free(mtCMMRegCfg[k]->vAddr);
1968             free(mtCMMRegCb[k]);
1969             free(mtCMMRegCfg[k]);
1970          }
1971          free(mtCMMRegCb[i]);
1972          return RFAILED;
1973       }
1974
1975
1976       /* allocate space for the region */
1977       region = &mtMemoCfg.region[i];
1978       mtCMMRegCfg[i]->size = region->heapsize;
1979       for (j = 0; j < region->numBkts; j++)
1980       {
1981          /* mt033.201 - addition for including the header size while computing the total size */
1982 #ifdef SSI_DEBUG_LEVEL1
1983          mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1984                                  (region->bkt[j].numBlks);
1985 #else
1986          mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1987 #endif /* SSI_DEBUG_LEVEL1 */
1988       }
1989 #ifdef INTEL_WLS
1990       mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1991 #else
1992       mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1993             sizeof(Data));
1994 #endif
1995 #ifdef XEON_SPECIFIC_CHANGES
1996       CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n", 
1997             i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1998 #endif      
1999 #ifdef TENB_RTLIN_CHANGES
2000       mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
2001 #endif
2002
2003       if (mtCMMRegCfg[i]->vAddr == NULLP)
2004       {
2005          sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
2006                for the Region:%d \n",i);
2007          SPrint(errMsg);
2008          for (k = 0; k < i; k++)
2009          {
2010             cmMmRegDeInit(mtCMMRegCb[k]);
2011             free(mtCMMRegCfg[k]->vAddr);
2012             free(mtCMMRegCb[k]);
2013             free(mtCMMRegCfg[k]);
2014          }
2015          free(mtCMMRegCb[i]);
2016          free(mtCMMRegCfg[i]);
2017          return RFAILED;
2018       }
2019
2020
2021       /* set up the CMM configuration structure */
2022       mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
2023       mtCMMRegCfg[i]->chFlag = 0;
2024       mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
2025       mtCMMRegCfg[i]->numBkts = region->numBkts;
2026
2027       for (j = 0; j < region->numBkts; j++)
2028       {
2029          mtCMMRegCfg[i]->bktCfg[j].size    = region->bkt[j].blkSize;
2030          mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
2031       }
2032
2033       /* initialize the CMM */
2034 #ifdef SS_LOCKLESS_MEMORY
2035       if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2036 #else
2037          if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2038 #endif /* SS_LOCKLESS_MEMORY */
2039          {
2040             for (k = 0; k < i; k++)
2041             {
2042                cmMmRegDeInit(mtCMMRegCb[k]);
2043                free(mtCMMRegCfg[k]->vAddr);
2044                free(mtCMMRegCb[k]);
2045                free(mtCMMRegCfg[k]);
2046             }
2047             free(mtCMMRegCfg[i]->vAddr);
2048             free(mtCMMRegCb[i]);
2049             free(mtCMMRegCfg[i]);
2050             return RFAILED;
2051          }
2052
2053
2054       /* initialize the STREAMS module */
2055       /* mt019.201: STREAMS module will only apply to DFLT_REGION */
2056       if (region->regionId == 0)
2057       {
2058          if (ssStrmCfg(region->regionId, region->regionId) != ROK)
2059          {
2060             for (k = 0; k < i; k++)
2061             {
2062                cmMmRegDeInit(mtCMMRegCb[k]);
2063                free(mtCMMRegCfg[k]->vAddr);
2064                free(mtCMMRegCb[k]);
2065                free(mtCMMRegCfg[k]);
2066             }
2067             cmMmRegDeInit(mtCMMRegCb[i]);
2068             free(mtCMMRegCfg[i]->vAddr);
2069             free(mtCMMRegCb[i]);
2070             free(mtCMMRegCfg[i]);
2071             return RFAILED;
2072          }
2073       }
2074    }
2075    /* mt001.301 : Additions */
2076 #ifdef SS_MEM_LEAK_STS
2077    cmInitMemLeakMdl();
2078 #endif /* SS_MEM_LEAK_STS */
2079
2080    return ROK;
2081 }
2082
2083 \f
2084 /*
2085  *
2086  *       Fun:   De-initialize region/pool tables
2087  *
2088  *       Desc:  This function reverses the initialization in ssdInitMem().
2089  *
2090  *       Ret:   ROK      - ok
2091  *
2092  *       Notes:
2093  *
2094  *       File:  mt_ss.c
2095  *
2096  */
2097 Void ssdDeinitMem(void)
2098 {
2099    /* mt018.201 - added local variables */
2100    uint8_t     i;
2101
2102    /* mt008.301 Additions */
2103 #ifdef SS_MEM_LEAK_STS
2104    cmDeinitMemLeakMdl();
2105 #endif /* SS_MEM_LEAK_STS */
2106
2107    for (i = 0; i < mtMemoCfg.numRegions; i++)
2108    {
2109       cmMmRegDeInit(mtCMMRegCb[i]);
2110       free(mtCMMRegCfg[i]->vAddr);
2111       free(mtCMMRegCb[i]);
2112       free(mtCMMRegCfg[i]);
2113    }
2114
2115    return;
2116 }
2117
2118 \f
2119 /*
2120  *
2121  *       Fun:   Initialize task table
2122  *
2123  *       Desc:  This function initializes MTSS-specific information
2124  *              in the task table.
2125  *
2126  *       Ret:   ROK      - ok
2127  *
2128  *       Notes:
2129  *
2130  *       File:  mt_ss.c
2131  *
2132  */
2133 S16 ssdInitTsk(void)
2134 {
2135    /* mt001.301 : Additions */
2136    /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
2137 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2138    uint32_t tskInd = 0;
2139 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2140
2141
2142
2143    /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
2144 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2145    /* initialize system task information */
2146    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
2147    {
2148       osCp.sTskTbl[tskInd].dep.lwpId = 0;
2149    }
2150 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2151    return ROK;
2152 }
2153
2154 \f
2155 /*
2156  *
2157  *       Fun:   Deinitialize task table
2158  *
2159  *       Desc:  This function reverses the initialization perfomed in
2160  *              ssdInitTsk().
2161  *
2162  *       Ret:   ROK      - ok
2163  *
2164  *       Notes:
2165  *
2166  *       File:  mt_ss.c
2167  *
2168  */
2169 Void ssdDeinitTsk(void)
2170 {
2171
2172    return;
2173 }
2174
2175 \f
2176 #ifdef SS_DRVR_SUPPORT
2177 /*
2178  *
2179  *       Fun:   Initialize driver task table
2180  *
2181  *       Desc:  This function initializes MTSS-specific information
2182  *              in the driver task table.
2183  *
2184  *       Ret:   ROK      - ok
2185  *
2186  *       Notes:
2187  *
2188  *       File:  mt_ss.c
2189  *
2190  */
2191 S16 ssdInitDrvr(void)
2192 {
2193    S16 i;
2194 #ifndef L2_L3_SPLIT
2195    pthread_attr_t attr;
2196 #endif
2197
2198
2199
2200    /* initialize the dependent portion of the driver task entries */
2201    for (i = 0;  i < SS_MAX_DRVRTSKS;  i++)
2202    {
2203       osCp.drvrTskTbl[i].dep.flag = FALSE;
2204    }
2205
2206
2207    /* create pipe for communication between SSetIntPend() and
2208     *  the isTskHdlr thread.
2209     */
2210    if (pipe(osCp.dep.isFildes) != 0)
2211    {
2212       return RFAILED;
2213    }
2214
2215 #ifndef L2_L3_SPLIT
2216    /* create the isTskHdlr thread */
2217    pthread_attr_init(&attr);
2218    /* mt021.201 - Addition to set stack size */
2219    pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2220    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2221    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2222    if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2223    {
2224       /* mt020.201 - Addition for destroying thread attribute object attr */
2225       pthread_attr_destroy(&attr);
2226
2227       return RFAILED;
2228    }
2229 #endif   
2230
2231    /*mt014.301 : 4GMX release related changes*/
2232 #ifdef SS_4GMX_UCORE
2233    uarmDrvrInit();
2234 #endif
2235
2236 #ifdef L2_L3_SPLIT
2237    drvrTskInit();
2238 #endif
2239 #ifndef L2_L3_SPLIT
2240    /* mt020.201 - Addition for destroying thread attribute object attr */
2241    pthread_attr_destroy(&attr);
2242 #endif
2243
2244    return ROK;
2245 }
2246
2247 \f
2248 /*
2249  *
2250  *       Fun:   Deinitialize driver information
2251  *
2252  *       Desc:  This function reverses the initialization performed in
2253  *              ssdInitDrvr().
2254  *
2255  *       Ret:   ROK      - ok
2256  *
2257  *       Notes:
2258  *
2259  *       File:  mt_ss.c
2260  *
2261  */
2262 Void ssdDeinitDrvr(void)
2263 {
2264    /* mt008.301: Terminate the Driver Task on exit */
2265    while(pthread_cancel(osCp.dep.isTskHdlrTID));
2266
2267 #ifdef L2_L3_SPLIT
2268    TL_Close(AppContext.hUAII);
2269    if (clusterMode == RADIO_CLUSTER_MODE)
2270    {
2271       TL_Close(AppContext.hUAII_second);
2272    }
2273 #endif
2274
2275    return;
2276 }
2277 #endif /* SS_DRVR_SUPPORT */
2278
2279 \f
2280 /*
2281  *
2282  *       Fun:   Initialize timer table
2283  *
2284  *       Desc:  This function initializes MTSS-specific information
2285  *              in the timer table.
2286  *
2287  *       Ret:   ROK      - ok
2288  *
2289  *       Notes:
2290  *
2291  *       File:  mt_ss.c
2292  *
2293  */
2294 S16 ssdInitTmr(void)
2295 {
2296    pthread_attr_t attr;
2297    struct sched_param param_sched;
2298    /* mt010.21: addition */
2299    S32 i;
2300 #ifdef SS_MULTICORE_SUPPORT
2301    SsSTskEntry     *sTsk;
2302 #endif /* SS_MULTICORE_SUPPORT */
2303 #ifdef SS_THR_REG_MAP
2304    uint32_t threadCreated = FALSE;
2305 #endif /* SS_THR_REG_MAP */
2306
2307
2308
2309    osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2310    /* mt010.21: addition */
2311    osCp.dep.tmrTqCp.nxtEnt = 0;
2312    for (i=0; i< SS_MAX_TMRS; i++)
2313    {
2314       osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2315    }
2316
2317 #ifdef SS_MULTICORE_SUPPORT
2318    sTsk = ssdAddTmrSTsk();
2319    if(!sTsk)
2320    {
2321       return RFAILED;
2322    }
2323 #endif /* SS_MULTICORE_SUPPORT */
2324    /* create the timer handler thread */
2325    pthread_attr_init(&attr);
2326    /* mt021.201 - Addition to set stack size */
2327    pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2328    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2329    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2330    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2331    param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2332    pthread_attr_setschedparam(&attr, &param_sched);
2333
2334
2335 #ifdef SS_THR_REG_MAP
2336    /* When the thread is created, we check for the memory mapping table if
2337     * threadId can be placed in thread memory map table. If it is not able to place
2338     * threadId is stored in tmporary array. Once thread is created successful,
2339     * thread_cancel is sent for each thread which are created before. All the 
2340     * threads are made to wait on sema which is cancel point for thread.
2341     */
2342    while(threadCreated == FALSE)
2343    {
2344 #endif
2345       if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2346       {
2347          /* mt020.201 - Addition for destroying thread attribute object attr */
2348          pthread_attr_destroy(&attr);
2349
2350          return RFAILED;
2351       }
2352
2353 #ifdef SS_THR_REG_MAP
2354       threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID, 
2355             sTsk->region);
2356    }
2357 #endif /* SS_THR_REG_MAP */
2358 #ifdef SS_MEM_WL_DEBUG
2359    tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2360 #endif
2361
2362    /* mt020.201 - Addition for destroying thread attribute object attr */
2363    pthread_attr_destroy(&attr);
2364
2365
2366    return ROK;
2367 }
2368
2369 \f
2370 /*
2371  *
2372  *       Fun:   Deinitialize timer table
2373  *
2374  *       Desc:  This function reverses the initialization performed in
2375  *              ssdInitTmr().
2376  *
2377  *       Ret:   ROK      - ok
2378  *
2379  *       Notes:
2380  *
2381  *       File:  mt_ss.c
2382  *
2383  */
2384 Void ssdDeinitTmr(void)
2385 {
2386 #ifdef SS_MULTICORE_SUPPORT
2387    SsSTskEntry *sTsk;
2388    S16         ret;
2389 #endif /* SS_MULTICORE_SUPPORT */
2390
2391
2392 #ifdef SS_MULTICORE_SUPPORT
2393    ret = SLock(&osCp.sTskTblLock);
2394    if (ret != ROK)
2395    {
2396
2397 #if (ERRCLASS & ERRCLS_DEBUG)
2398       MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2399             "Could not lock system task table");
2400 #endif
2401       return;
2402    }
2403    sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2404    /* clean up the system task entry */
2405    sTsk->used = FALSE;
2406    sTsk->tskPrior = 0;
2407    sTsk->numTTsks = 0;
2408    SDestroyLock(&sTsk->lock);
2409    ssDestroyDmndQ(&sTsk->dQ);
2410
2411
2412    /* make this entry available in the system task table */
2413    sTsk->nxt = osCp.nxtSTskEntry;
2414    osCp.nxtSTskEntry = 0;
2415
2416    osCp.numSTsks--;
2417
2418    /* unlock the system task table */
2419    SUnlock(&osCp.sTskTblLock);
2420
2421 #endif /* SS_MULTICORE_SUPPORT */
2422    /* mt008.301: Terminate the timer thread on exit */
2423    while(pthread_cancel(osCp.dep.tmrHdlrTID));
2424    return;
2425 }
2426
2427
2428 \f
2429 /*
2430  *
2431  *       Fun:   ssdInitLog
2432  *
2433  *       Desc:  Pre-tst() initialization.
2434  *
2435  *       Ret:   ROK      - ok
2436  *
2437  *       Notes:
2438  *
2439  *       File:  mt_ss.c
2440  *
2441  */
2442 S16 ssdInitLog(void)
2443 {
2444    /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2445 #ifdef CONAVL
2446 #ifndef CONRD
2447    S32 flags;
2448    pthread_attr_t attr;
2449 #ifndef CONSTDIO
2450    struct termios tio;
2451 #endif /* CONSTDIO */
2452    S16 fd;
2453 #endif /* CONRD */
2454 #endif /* CONAVL */
2455
2456    /* mt008.301: ssdInitFinal changed to ssdInitLog */
2457
2458
2459 #ifdef CONAVL
2460
2461    osCp.dep.conInFp = (FILE *) stdin;
2462    osCp.dep.conOutFp = (FILE *) stdout;
2463    /* added compile time flag CONRD: mt017.21 */
2464 #ifndef CONRD
2465 #ifndef CONSTDIO
2466
2467    /* disable canonical input processing */
2468    fd = fileno(osCp.dep.conInFp);
2469    if ((tcgetattr(fd, &tio)) != 0)
2470    {
2471       printf("\nError: disable canonical input processing\n");
2472       return RFAILED;
2473    }
2474
2475    tio.c_lflag &= ~ICANON;
2476    tio.c_cc[VMIN] = 1;   /* wait for a minimum of 1 character input */
2477    tio.c_cc[VTIME] = 0;
2478    if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2479    {
2480       printf("\nError: while tcsetattr() processing\n");
2481       return RFAILED;
2482    }
2483
2484 #endif /* CONSTDIO */
2485
2486
2487    /* set up the input fd to block when no data is available */
2488    fd = fileno(osCp.dep.conInFp);
2489    flags = fcntl(fd, F_GETFL, &flags);
2490    flags &= ~O_NONBLOCK;
2491    if (fcntl(fd, F_SETFL, flags) == -1)
2492    {
2493       printf("\nError: while fcntl processing\n");
2494       return RFAILED;
2495    }
2496
2497
2498    /* create the console handler thread */
2499    pthread_attr_init(&attr);
2500    /* mt021.201 - Addition to set stack size */
2501    pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2502    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2503    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2504
2505
2506    if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2507    {
2508       /* mt020.201 - Addition for destroying thread attribute object attr */
2509       pthread_attr_destroy(&attr);
2510
2511       printf("\nError: Logging Thread creation failed \n");
2512       return RFAILED;
2513    }
2514
2515    /* mt020.201 - Addition for destroying thread attribute object attr */
2516    pthread_attr_destroy(&attr);
2517
2518 #endif /* CONRD */
2519 #endif /* CONAVL */
2520
2521
2522    return ROK;
2523 }
2524
2525 \f
2526 /*
2527  *
2528  *       Fun:   ssdDeinitLog
2529  *
2530  *       Desc:  This function reverses the initialization performed in
2531  *              ssdInitLog().
2532  *
2533  *       Ret:   ROK      - ok
2534  *
2535  *       Notes:
2536  *
2537  *       File:  mt_ss.c
2538  *
2539  */
2540 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2541 Void ssdDeinitLog(void)
2542 {
2543    /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2544 #ifdef CONAVL
2545 #ifndef CONRD
2546    /* mt008.301: Terminate the console reader on exit */
2547    while(pthread_cancel(osCp.dep.conHdlrTID));
2548 #endif /* CONRD */
2549 #endif /* CONVAL */
2550
2551    return;
2552 }
2553 /* mt001.301 : Additions */
2554 #ifdef SS_WATCHDOG
2555
2556
2557 S16 ssdInitWatchDog(uint16_t port)
2558 {
2559    uint8_t idx;
2560    Txt prntBuf[PRNTSZE];
2561    Pst     pst;
2562    Buffer *mBuf;
2563 #ifdef SS_WATCHDOG_IPV6
2564    struct sockaddr_in6 tmpaddr;
2565 #else
2566    struct sockaddr_in tmpaddr;
2567 #endif /* SS_WATCHDOG_IPV6 */
2568 #ifdef SS_MULTIPLE_PROCS
2569    ProcId procId = SS_WD_WDPROC;
2570    if (SAddProcIdLst(1, &procId) != ROK)
2571    {
2572       return RFAILED;
2573    }
2574 #endif /* SS_MULTIPLE_PROCS */
2575
2576
2577    SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2578
2579    /* Create a watch dog system task */
2580    SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2581
2582    /* Create a watch dog reveiver system task */
2583    SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2584
2585    /* Register and attach watch dog TAPA task */
2586 #ifdef SS_MULTIPLE_PROCS
2587    SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2588    SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2589 #else
2590    SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2591    SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2592 #endif /* SS_MULTIPLE_PROCS */
2593    /* Register and attach watch dog receiver TAPA task */
2594 #ifdef SS_MULTIPLE_PROCS
2595    SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2596    SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2597 #else
2598    SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2599    SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2600 #endif /* SS_MULTIPLE_PROCS */
2601
2602 #ifndef SS_MULTIPLE_PROCS
2603    osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2604    osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2605 #else
2606    osCp.wdCp.watchDgPst.srcProcId = procId;
2607    osCp.wdCp.watchDgPst.dstProcId = procId;
2608 #endif /* SS_MULTIPLE_PROCS */
2609
2610    /* Initialise the pst structure */
2611    ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2612    /* Initialize the watch dog timer resolution default is 1 sec */
2613
2614    cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2615    osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2616    osCp.wdCp.watchDgTqCp.tmrLen = 1;
2617    for(idx = 0; idx < 1; idx++)
2618    {
2619       osCp.wdCp.watchDgTs[idx].first = NULLP;
2620       osCp.wdCp.watchDgTs[idx].tail = NULLP;
2621    }
2622 #ifdef SS_MULTIPLE_PROCS
2623    SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2624 #else
2625    SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2626 #endif /* SS_MULTIPLE_PROCS */
2627
2628    /* Create the watch dog receiver socket */
2629    osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2630    if(osCp.wdCp.globWd.sock == -1)
2631    {
2632       sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2633       SPrint(prntBuf);
2634    }
2635
2636 #ifdef SS_WATCHDOG_IPV6
2637    tmpaddr.sin6_len = sizeof(tmpadDr);
2638    tmpaddr.sin6_family = AF_INET6;
2639    tmpaddr.sin6_addr = in6addr_any;
2640    tmpaddr.sin6_port = htons(port);
2641 #else
2642    tmpaddr.sin_family = AF_INET;
2643    tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2644    tmpaddr.sin_port = htons(port);
2645 #endif /* SS_WATCHDOG_IPV6 */
2646
2647    if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2648      )
2649    {
2650       sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2651       SPrint(prntBuf);
2652    }
2653
2654    if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2655    {
2656       return RFAILED;
2657    }
2658 #ifndef SS_MULTIPLE_PROCS
2659    pst.srcProcId = SFndProcId();
2660    pst.dstProcId = SFndProcId();
2661 #else
2662    pst.srcProcId = procId;
2663    pst.dstProcId = procId;
2664 #endif /* SS_MULTIPLE_PROCS */
2665    pst.event     = EVTSSHRTBTREQ;
2666    ssdInitWatchDgPst(&pst);
2667    SPstTsk(&pst, mBuf);
2668
2669    return ROK;
2670 }
2671
2672 S16 ssdInitWatchDgPst(Pst *pst)
2673 {
2674
2675    pst->selector  = SS_LOOSE_COUPLING;
2676
2677    pst->region    = DFLT_REGION;             /* region */
2678    pst->pool      = DFLT_POOL;                 /* pool */
2679
2680    pst->prior     = PRIOR0;                   /* priority */
2681    pst->route     = RTESPEC;                  /* route */
2682
2683    pst->dstEnt    = ENTHB;                   /* destination entity */
2684    pst->dstInst   = 0;
2685    pst->srcEnt    = ENTDW;                   /* source entity */
2686    pst->srcInst   = 0;
2687
2688    return ROK;
2689 }
2690
2691 #ifdef SS_MULTIPLE_PROCS
2692    S16 ssdWatchDgActvTmr
2693 (
2694  ProcId proc,
2695  Ent ent,
2696  Inst inst
2697  )
2698 #else
2699 S16 ssdWatchDgActvTmr(Void)
2700 #endif /* SS_MULTIPLE_PROCS */
2701 {
2702
2703    cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2704
2705    return ROK;
2706 }
2707
2708    Void ssdWatchDgTmrEvt
2709 (
2710  PTR       cb,        /* control block */
2711  S16       event      /* timer number */
2712  )
2713 {
2714    /* mt003.301 Fixed warings */
2715 #ifdef DEBUGP
2716    DateTime dt;
2717 #endif /* DEBUGP */
2718    Txt prntBuf[PRNTSZE];
2719    Bool restartTmr;
2720    int i;
2721
2722
2723    switch(event)
2724    {
2725       case SS_TMR_HRTBT:
2726 #ifdef DEBUGP
2727          SPrint("Timer Heartbeat Request Expired");
2728          SGetDateTime(&dt);
2729          sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2730          SPrint(prntBuf);
2731 #endif
2732          restartTmr=TRUE;
2733
2734          SLock(&osCp.wdCp.wdLock);
2735          for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2736          {
2737             if(osCp.wdCp.globWd.wdsta[i].status == 0)
2738             {
2739                sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2740                SPrint(prntBuf);
2741                if(osCp.wdCp.globWd.callback != 0)
2742                {
2743                   osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2744                }
2745             }
2746          }
2747          SUnlock(&osCp.wdCp.wdLock);
2748
2749          if(!osCp.wdCp.globWd.watchdogStop)
2750          {
2751             ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2752             ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2753          }
2754          break;
2755
2756       default:
2757          break;
2758    }
2759
2760 }
2761
2762    Void ssdStartWatchDgTmr
2763 (
2764  void     *cb,
2765  S16      event,
2766  uint16_t wait
2767  )
2768 {
2769    CmTmrArg    arg;
2770    int i;
2771 #ifdef DEBUGP
2772    DateTime dt;
2773    Txt prntBuf[PRNTSZE];
2774 #endif
2775
2776
2777    /* mt003.301 Modifications */
2778 #ifdef DEBUGP
2779    SGetDateTime(&dt);
2780    sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2781    if(event == SS_TMR_HRTBT)
2782    {
2783       SPrint("\nSTART SS_TMR_HRTBT");
2784       SPrint(prntBuf);
2785    }
2786 #endif
2787
2788    /* Re-init ACKs */
2789
2790    SLock(&osCp.wdCp.wdLock);
2791    for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2792    {
2793       osCp.wdCp.globWd.wdsta[i].status = 0;
2794    }
2795    SUnlock(&osCp.wdCp.wdLock);
2796
2797    arg.tq     = osCp.wdCp.watchDgTs;
2798    arg.tqCp   = &osCp.wdCp.watchDgTqCp;
2799    arg.timers = osCp.wdCp.watchDgTmr;
2800    arg.cb     = (PTR)NULLP;
2801    arg.evnt   = event;
2802    arg.wait   = osCp.wdCp.globWd.timeout = wait;
2803    arg.tNum   = NOTUSED;
2804    arg.max    = 1;
2805    cmPlcCbTq(&arg);
2806
2807    return;
2808 }
2809
2810    Void ssdStopWatchDgTmr
2811 (
2812  void *cb,
2813  S16  event
2814  )
2815 {
2816    CmTmrArg    arg;
2817 #ifdef DEBUGP
2818    DateTime dt;
2819    Txt prntBuf[PRNTSZE];
2820    int i;
2821 #endif
2822
2823    /* mt003.301 Modifications */
2824 #ifdef DEBUGP
2825    SGetDateTime(&dt);
2826    sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2827    if(event == SS_TMR_HRTBT)
2828    {
2829       SPrint("STOP SS_TMR_HRTBT");
2830       SPrint(prntBuf);
2831    }
2832    /* Re-init ACKs */
2833    SLock(&osCp.wdCp.wdLock);
2834    for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2835    {
2836       osCp.wdCp.globWd.wdsta[i].status = 0;
2837    }
2838    SUnlock(&osCp.wdCp.wdLock);
2839
2840 #endif
2841    arg.tq     = osCp.wdCp.watchDgTs;
2842    arg.tqCp   = &osCp.wdCp.watchDgTqCp;
2843    arg.timers = osCp.wdCp.watchDgTmr;
2844    arg.cb     = (PTR)NULLP;
2845    arg.evnt   = event;
2846    arg.wait   = NOTUSED;
2847    arg.tNum   = NOTUSED;
2848    arg.max    = 1;
2849    cmRmvCbTq(&arg);
2850
2851    return;
2852 }
2853
2854    S16 ssdSndHrtBtMsg
2855 (
2856  Bool      restart,
2857  uint32_t  type
2858  )
2859 {
2860    S16     ret = ROK;
2861 #ifdef DEBUGP
2862    DateTime dt;
2863    Txt prntBuf[PRNTSZE];
2864 #endif
2865    struct sockaddr_in tmpaddr;
2866    char hbMsg[SS_WD_HB_MSG_SIZE];
2867    int             n;
2868    int             err;
2869
2870
2871 #ifdef DEBUGP
2872    SGetDateTime(&dt);
2873    sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2874    SPrint(prntBuf);
2875 #endif
2876
2877    /* Pack the message */
2878    strcpy(hbMsg, "<HB>REQ</HB>");
2879
2880    /* Send the heartbeat messages to all the configured nodes */
2881    SLock(&osCp.wdCp.wdLock);
2882    for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2883    {
2884       if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2885       {
2886          continue;
2887       }
2888
2889       /* Identify the destination node */
2890 #ifdef SS_WATCHDOG_IPV6
2891       tmpaddr.sin6_len = sizeof(tmpaddr);
2892       tmpaddr.sin6_family = AF_INET6;
2893       tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2894       tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2895 #else
2896       tmpaddr.sin_family = AF_INET;
2897       tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2898       tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2899 #endif /* SS_WATCHDOG_IPV6 */
2900
2901       err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2902       if(err == -1)
2903       {
2904 #ifdef DEBUGP
2905          sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2906                inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2907          SPrint(prntBuf);
2908 #endif /* DEBUGP */
2909       }
2910       else
2911       {
2912 #ifdef DEBUGP
2913          sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2914          SPrint(prntBuf);
2915 #endif /* DEBUGP */
2916       }
2917    }
2918    SUnlock(&osCp.wdCp.wdLock);
2919
2920    return (ret);
2921 }
2922
2923 #endif /* SS_WATCHDOG */
2924
2925
2926 \f
2927 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2928 #ifndef NOCMDLINE
2929 /*
2930  *
2931  *       Fun:   mtGetOpts
2932  *
2933  *       Desc:  This function gets command line options.
2934  *
2935  *       Ret:
2936  *
2937  *       Notes:
2938  *
2939  *       File:  mt_ss.c
2940  *
2941  */
2942 static Void mtGetOpts(void)
2943 {
2944    S32 argc;
2945    S8 **argv;
2946    S16 ret;
2947    /* mt028.201 */
2948 #ifndef NOFILESYS
2949    FILE         *memOpt;             /* memory options file pointer */
2950    Txt pBuf[128];
2951    uint8_t i;
2952    /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2953    PTR numReg;
2954    PTR numBkts;
2955    PTR bktSz = NULLP;
2956    PTR heapSz=0;
2957    PTR bktNum;
2958    /*KWORK_FIX: Initializing the variable for avoidning corruption */
2959    PTR bktIdx = 0;
2960    /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2961    PTR bktUpdtCnt = 0;
2962    PTR regUpdtCnt = 0;
2963    PTR regId;
2964    PTR numPools;
2965    PTR poolIdx;
2966 #ifdef SS_LOCKLESS_MEMORY
2967    PTR bktSetSize;
2968    PTR bktRelThr;
2969    PTR bktAqurThr;
2970 #endif
2971    Txt line[256];
2972    Bool error = FALSE;
2973    Cntr   idx=0;
2974 #endif
2975
2976
2977
2978    msOptInd = 1;
2979
2980 #ifndef NOFILESYS
2981    osCp.dep.fileOutFp = (FILE *)NULLP;
2982
2983    /* initialize memOpt */
2984    memOpt = (FILE *) NULLP;
2985 #endif
2986
2987    argc = msArgc;
2988    argv = msArgv;
2989
2990    /* mt028.201 */
2991    while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2992    {
2993       switch (ret)
2994       {
2995 #ifndef NOFILESYS
2996          /* mt001.301 : Additions */
2997 #ifdef SS_MEM_LEAK_STS
2998          case 'm':
2999             cmMemOpenMemLkFile(msOptArg);
3000             break;
3001 #endif
3002          case 'o':
3003             osCp.dep.fileOutFp = fopen(msOptArg, "w");
3004             break;
3005          case 'f':
3006             fileBasedMemCfg = TRUE;
3007             memOpt = fopen(msOptArg, "r");
3008
3009             /* if file does not exist or could not be opened then use the
3010              * default memory configuration as defined in mt_ss.h
3011              */
3012             if (memOpt == (FILE *) NULLP)
3013             {
3014                sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3015                      be opened, using default mem configuration\n", msOptArg);
3016                SPrint(pBuf);
3017                break;
3018             }
3019             i = 0;
3020             while (fgets((Txt *)line, 256, memOpt) != NULLP)
3021             {
3022                if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3023                   continue;
3024                if(error == TRUE)
3025                   break;
3026                switch  (i)
3027                {
3028                   case 0:  /*** INPUT: Number of regions ***/
3029                      sscanf(line, "%ld", (long *) &numReg);
3030                      mtMemoCfg.numRegions = numReg;
3031                      if(mtMemoCfg.numRegions > SS_MAX_REGS)
3032                      {
3033                         printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3034                         error = TRUE;
3035                         break;
3036                      }
3037                      i++;
3038                      break;
3039                   case 1: /*** INPUT: Number of buckets and number of Pools ***/
3040                      sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3041                      if(numBkts > MT_MAX_BKTS)
3042                      {
3043                         printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3044                         error = TRUE;
3045                         break;
3046                      }
3047                      if(numPools > SS_MAX_POOLS_PER_REG)
3048                      {
3049                         printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3050                         error = TRUE;
3051                         break;
3052                      }
3053                      /*
3054                       * Delay updation from local variable to global
3055                       * structure of number of regions and heap data to
3056                       * counter error conditions present above.
3057                       */
3058                      for(idx = 0; idx < cfgNumRegs; idx++)
3059                      {
3060                         mtMemoCfg.region[idx].numBkts = numBkts;
3061                         cfgRegInfo[idx].region = idx;
3062                         cfgRegInfo[idx].numPools = numPools;
3063                         /*
3064                          * Initialize the pool info as static type with size zero
3065                          */
3066                         for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3067                         {
3068                            cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3069                            cfgRegInfo[idx].pools[poolIdx].size = 0;
3070                         }
3071                      }
3072                      i++;
3073                      break;
3074                   case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3075                      if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3076                      {
3077                         sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3078                      }
3079                      if(bktIdx >= numBkts)
3080                      {
3081                         printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3082                         error = TRUE;
3083                         break;
3084
3085                      }
3086                      mtBktInfo[bktIdx].blkSize  = bktSz;
3087                      bktUpdtCnt++;
3088                      if(bktUpdtCnt == numBkts)
3089                      {
3090                         i++; /*done reading bkt info, start reading individual region info*/
3091                         bktUpdtCnt = 0;
3092                      }
3093                      break;
3094                   case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3095                      sscanf(line,"%ld",(long *) &regId);
3096                      if(regId >= mtMemoCfg.numRegions)
3097                      {
3098                         printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3099 #ifndef XEON_SPECIFIC_CHANGES                       
3100                         error = TRUE;
3101 #endif                       
3102                         break;
3103                      }
3104                      mtMemoCfg.region[regId].regionId = regId;
3105                      i++;
3106                      break;
3107                   case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3108                      if(bktUpdtCnt < numBkts)
3109                      {
3110                         sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3111                         if(bktIdx >= numBkts)
3112                         {
3113                            printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3114                            error = TRUE;
3115                            break;
3116
3117                         }
3118                         if(bktIdx < MT_MAX_BKTS)
3119                         {
3120                            mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3121                            mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3122                            cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3123                            cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3124                         }
3125                         bktUpdtCnt++;
3126                         if(bktUpdtCnt == numBkts)
3127                         {
3128                            i++;
3129                            bktUpdtCnt = 0;
3130                         }
3131                      }
3132                      break;
3133                   case 5: /* INPUT: Heapsize ***/
3134                      sscanf(line, "%ld", (long *) &heapSz);
3135                      mtMemoCfg.region[regId].heapsize = heapSz;
3136                      regUpdtCnt++;
3137                      if(regUpdtCnt != mtMemoCfg.numRegions)
3138                      {
3139                         i = 3;   
3140                      }
3141                      else
3142                      {
3143                         i++;
3144                      }
3145                      break;
3146 #ifdef SS_LOCKLESS_MEMORY
3147                   case 6:
3148                      sscanf(line, "%ld", (long *) &numBkts);
3149                      mtGlobMemoCfg.numBkts = numBkts;
3150 #ifndef XEON_SPECIFIC_CHANGES                     
3151                      mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3152 #endif                     
3153
3154 #ifdef XEON_SPECIFIC_CHANGES
3155                      CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3156                            mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3157                      for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3158 #else                     
3159                         for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3160 #endif                        
3161                         {
3162                            mtDynMemoCfg.region[idx].regionId = idx;
3163                            mtDynMemoCfg.region[idx].numBkts = numBkts;
3164                         }
3165
3166                      bktUpdtCnt = 0;
3167                      i++;
3168                      break;
3169
3170                   case 7:
3171                      if(bktUpdtCnt < numBkts)
3172                      {
3173                         sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3174                               (long *) &bktSz, (long *) &bktNum,
3175                               (long *) &bktSetSize, (long *) &bktRelThr, 
3176                               (long *) &bktAqurThr);
3177                         /* Klock work fix ccpu00148484 */
3178                         if(bktIdx < SS_MAX_POOLS_PER_REG)
3179                         {
3180                            mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3181                            mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3182                            mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3183 #ifdef XEON_SPECIFIC_CHANGES
3184                            CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3185                                  bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3186                                  mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize); 
3187
3188                            if(bktIdx >= SS_MAX_POOLS_PER_REG)
3189                            {
3190                               printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3191                               error = TRUE;
3192                               break;
3193                            }
3194
3195 #endif                           
3196                            for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3197                            {
3198                               mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3199                               mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3200 #ifdef XEON_SPECIFIC_CHANGES
3201                               CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3202                                     bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3203                                     mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3204 #endif                           
3205                            } 
3206                         }
3207                         bktUpdtCnt++;
3208                      }
3209 #ifdef XEON_SPECIFIC_CHANGES
3210                      if(bktUpdtCnt == numBkts)
3211                      {   
3212                         i=8;
3213                      }
3214                      break;
3215
3216                   case 8: /* INPUT: Global Heapsize ***/
3217                      sscanf(line, "%ld", (long *) &heapSz);
3218                      mtGlobMemoCfg.heapSize = heapSz;
3219                      CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3220 #endif                           
3221                      break;
3222 #endif
3223                }
3224             }
3225             if(error == TRUE)
3226             {
3227                memConfigured = FALSE;
3228             }
3229             else
3230             {
3231                memConfigured = TRUE;
3232             }
3233             fclose (memOpt);
3234             break;
3235 #endif
3236
3237
3238          case 's':
3239             /* mt028.201: modification: multiple procs support related changes */
3240 #ifndef SS_MULTIPLE_PROCS
3241
3242 #ifdef ENB_RELAY
3243             osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3244 #else
3245             osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3246 #endif
3247
3248 #else /* SS_MULTIPLE_PROCS */
3249             {
3250                ProcId procId;
3251 #ifdef ENB_RELAY
3252                procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3253 #else
3254                procId = (ProcId) strtol(msOptArg, NULLP, 0);
3255 #endif
3256                SAddProcIdLst(1, &procId);
3257             }
3258
3259 #endif /* SS_MULTIPLE_PROCS */
3260             break;
3261
3262          case 'c':
3263             osCp.configFilePath = msOptArg;
3264             break;
3265
3266          case '?':
3267             /* fall through */
3268
3269
3270          default:
3271             break;
3272       }
3273    }
3274
3275    msOptInd = 1;
3276
3277
3278    return;
3279 }
3280 #endif
3281
3282 \f
3283 /*
3284  *
3285  *       Fun:   SGetOpt
3286  *
3287  *       Desc:  Get options from command line
3288  *
3289  *       Ret:   option  - success
3290  *              '?'     - fail
3291  *              EOF     - end of options
3292  *
3293  *       Notes: Handles command lines like the following
3294  *
3295  *              if opts = "abc:d"
3296  *                 then command line should look like this...
3297  *                    -a foo -b foo1 -c -d foo
3298  *
3299  *              code usage:
3300  *
3301  *              while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3302  *              {
3303  *                 switch(ret)
3304  *                 {
3305  *                    case 'l':
3306  *                       nloops = atoi(msArgv[msOptInd]);
3307  *                       break;
3308  *                    case 's':
3309  *                       state1 = atoi(msArgv[msOptInd]);
3310  *                    case '?':
3311  *                    default:
3312  *                       break;
3313  *                 }
3314  *              }
3315  *
3316  *       File:  mt_ss.c
3317  *
3318  */
3319    S16 SGetOpt
3320 (
3321  int argc,                   /* argument count */
3322  char **argv,                /* argument value */
3323  char *opts                  /* options */
3324  )
3325 {
3326    /* mt020.201 - Removed for no command line */
3327 #ifndef NOCMDLINE
3328    S16 sp;
3329    S16 c;
3330    S8 *cp;
3331 #endif
3332
3333
3334    /* mt020.201 - Addition for no command line */
3335 #ifdef NOCMDLINE
3336    UNUSED(argc);
3337    UNUSED(argv);
3338    UNUSED(opts);
3339
3340    return (EOF);
3341 #else
3342
3343    sp = 1;
3344    if (sp == 1)
3345    {
3346       /*mt013.301 : Changes as per coding standards*/
3347       if (msOptInd >= (S16) argc  ||  argv[msOptInd][0] == '\0')
3348       {
3349          return (EOF);
3350       }
3351       else
3352       {
3353          if (!strcmp(argv[msOptInd], "--"))
3354          {
3355             msOptInd++;
3356             return (EOF);
3357          }
3358          else if (argv[msOptInd][0] != '-')
3359          {
3360             msOptInd++;
3361             return ('?');
3362          }
3363       }
3364    }
3365
3366    c = argv[msOptInd][sp];
3367    if (c == ':'  ||  (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3368    {
3369       if (argv[msOptInd][++sp] == '\0')
3370       {
3371          msOptInd++;
3372          sp = 1;
3373       }
3374
3375       return ('?');
3376    }
3377
3378    if (*++cp == ':')
3379    {
3380       if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3381       else
3382       {
3383          if (++msOptInd >= (S16) argc)
3384          {
3385             sp = 1;
3386             return ('?');
3387          }
3388          else msOptArg = argv[msOptInd++];
3389
3390          sp = 1;
3391       }
3392    }
3393    else
3394    {
3395       if (argv[msOptInd][++sp] == '\0')
3396       {
3397          sp = 1;
3398          msOptInd++;
3399       }
3400
3401       msOptArg = NULLP;
3402    }
3403
3404
3405    return (c);
3406
3407 #endif /* NOCMDLINE */
3408 }
3409
3410 \f
3411 /*
3412  *
3413  *       Fun:   ssdStart
3414  *
3415  *       Desc:  This function starts system services execution; the
3416  *              permanent tasks are started and the system enters a
3417  *              ready state.
3418  *
3419  *       Ret:   Void
3420  *
3421  *       Notes:
3422  *
3423  *       File:  mt_ss.c
3424  *
3425  */
3426 Void ssdStart(void)
3427 {
3428    S16 i;
3429
3430
3431
3432
3433    /* mt025.201 - Modification for adding lock to timer handler */
3434    for (i = 0;  i <= SS_MAX_STSKS + 5;  i++)
3435    {
3436       sem_post(&osCp.dep.ssStarted);
3437    }
3438
3439
3440    return;
3441 }
3442
3443 \f
3444 /*
3445  *     indirect interface functions to system services service user
3446  */
3447
3448 \f
3449 /*
3450  *
3451  *       Fun:   ssdAttachTTsk
3452  *
3453  *       Desc:  This function sends the initial tick message to a TAPA
3454  *              task if the task is a permanent task.
3455  *
3456  *       Ret:   ROK      - ok
3457  *
3458  *       Notes:
3459  *
3460  *       File:  mt_ss.c
3461  *
3462  */
3463    S16 ssdAttachTTsk
3464 (
3465  SsTTskEntry *tTsk           /* pointer to TAPA task entry */
3466  )
3467 {
3468    Buffer *mBuf;
3469    SsMsgInfo *mInfo;
3470    S16 ret;
3471
3472    if (tTsk->tskType == SS_TSK_PERMANENT)
3473    {
3474       /* Send a permanent tick message to this task, to start
3475        * execution.
3476        */
3477       ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3478       if (ret != ROK)
3479       {
3480 #if (ERRCLASS & ERRCLS_DEBUG)
3481          MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3482 #endif
3483          return RFAILED;
3484       }
3485
3486       mInfo = (SsMsgInfo *)mBuf->b_rptr;
3487       mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3488
3489       /* set up post structure */
3490       /* mt028.201: modification: multiple procs support related changes */
3491 #ifndef SS_MULTIPLE_PROCS
3492       mInfo->pst.dstProcId = SFndProcId();
3493       mInfo->pst.srcProcId = SFndProcId();
3494 #else /* SS_MULTIPLE_PROCS */
3495       mInfo->pst.dstProcId = tTsk->proc;
3496       mInfo->pst.srcProcId = tTsk->proc;
3497 #endif /* SS_MULTIPLE_PROCS */
3498       mInfo->pst.selector  = SEL_LC_NEW;
3499       mInfo->pst.region    = DFLT_REGION;
3500       mInfo->pst.pool      = DFLT_POOL;
3501       mInfo->pst.prior     = PRIOR3;
3502       mInfo->pst.route     = RTESPEC;
3503       mInfo->pst.event     = 0;
3504       mInfo->pst.dstEnt    = tTsk->ent;
3505       mInfo->pst.dstInst   = tTsk->inst;
3506       mInfo->pst.srcEnt    = tTsk->ent;
3507       mInfo->pst.srcInst   = tTsk->inst;
3508
3509       ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3510             (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3511
3512       if (ret != ROK)
3513       {
3514          SPutMsg(mBuf);
3515
3516 #if (ERRCLASS & ERRCLS_DEBUG)
3517          MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3518                "Could not write to demand queue");
3519 #endif
3520          return RFAILED;
3521       }
3522    }
3523
3524
3525    return ROK;
3526 }
3527
3528 \f
3529 /*
3530  *
3531  *       Fun:   ssdDetachTTsk
3532  *
3533  *       Desc:  Does nothing.
3534  *
3535  *       Ret:   ROK      - ok
3536  *
3537  *       Notes:
3538  *
3539  *       File:  mt_ss.c
3540  *
3541  */
3542    S16 ssdDetachTTsk
3543 (
3544  SsTTskEntry *tTsk           /* pointer to TAPA task entry */
3545  )
3546 {
3547
3548    return ROK;
3549 }
3550
3551 \f
3552 /*
3553  *
3554  *       Fun:   ssdCreateSTsk
3555  *
3556  *       Desc:  This function creates a system task. A thread is started
3557  *              on the system task handler function defined later.
3558  *
3559  *       Ret:   ROK      - ok
3560  *
3561  *       Notes:
3562  *
3563  *       File:  mt_ss.c
3564  *
3565  */
3566    S16 ssdCreateSTsk
3567 (
3568  SsSTskEntry *sTsk           /* pointer to system task entry */
3569  )
3570 {
3571    S16  ret;
3572    pthread_attr_t attr;
3573    /* struct sched_param param_sched;*/
3574
3575 #ifdef SS_THR_REG_MAP
3576    uint32_t threadCreated = FALSE;
3577 #endif
3578
3579
3580
3581 #ifdef SS_SINGLE_THREADED
3582    /* mt001.301 : Additions */
3583 #ifndef SS_WATCHDOG
3584 #ifdef SS_MULTICORE_SUPPORT
3585    if (osCp.numSTsks > 1)
3586 #else
3587       if (osCp.numSTsks > 0)
3588 #endif /* SS_MULTICORE_SUPPORT */
3589 #else
3590 #ifdef SS_MULTICORE_SUPPORT
3591          if (osCp.numSTsks > 3)
3592 #else
3593             if (osCp.numSTsks > 2)
3594 #endif /* SS_MULTICORE_SUPPORT */
3595 #endif /* SS_WATCHDOG */
3596             {
3597                return ROK;
3598             }
3599 #endif
3600
3601
3602    /* set the current executing entity and instance IDs to
3603     * 'not configured'. create the lock to access them.
3604     */
3605    sTsk->dep.ent = ENTNC;
3606    sTsk->dep.inst = INSTNC;
3607
3608
3609    /* create the thread */
3610    pthread_attr_init(&attr);
3611    ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3612
3613    printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3614 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3615    if (sTsk->tskPrior == 0)
3616    {
3617       printf("\nCreating RT thread #######################\n");
3618 #ifdef SS_THR_REG_MAP
3619       /* When the thread is created, we check for the memory mapping table if
3620        * threadId can be placed in thread memory map table. If it is not able to place
3621        * threadId is stored in tmporary array. Once thread is created successful,
3622        * thread_cancel is sent for each thread which are created before. All the 
3623        * threads are made to wait on sema which is cancel point for thread.
3624        */
3625       while(threadCreated == FALSE)
3626       {
3627 #endif
3628          ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3629          if (ret != 0)
3630          {
3631             DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3632             pthread_attr_destroy(&attr);
3633
3634 #if (ERRCLASS & ERRCLS_DEBUG)
3635             MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3636 #endif
3637
3638             return RFAILED;
3639          }
3640 #ifdef SS_THR_REG_MAP
3641          threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId, 
3642                sTsk->region);
3643       }
3644 #endif
3645    }
3646    else
3647 #endif
3648    {
3649 #ifdef SS_THR_REG_MAP
3650       /* When the thread is created, we check for the memory mapping table if
3651        * threadId can be placed in thread memory map table. If it is not able to place
3652        * threadId is stored in tmporary array. Once thread is created successful,
3653        * thread_cancel is sent for each thread which are created before. All the 
3654        * threads are made to wait on sema which is cancel point for thread.
3655        */
3656       while(threadCreated == FALSE)
3657       {
3658 #endif
3659          ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3660          if (ret != 0)
3661          {
3662
3663             /* mt020.201 - Addition for destroying thread attribute object attr */
3664             pthread_attr_destroy(&attr);
3665
3666 #if (ERRCLASS & ERRCLS_DEBUG)
3667             MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3668 #endif
3669
3670             return RFAILED;
3671          }
3672 #ifdef SS_THR_REG_MAP
3673          threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId, 
3674                sTsk->region);
3675       }
3676 #endif
3677    }
3678
3679
3680    /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
3681 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3682    {
3683       static uint32_t stLwpId = 3;
3684       sTsk->dep.lwpId = ++stLwpId;
3685    }
3686 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3687
3688    /* mt020.201 - Addition for destroying thread attribute object attr */
3689    pthread_attr_destroy(&attr);
3690
3691    return ROK;
3692 }
3693
3694
3695    int SCreatePThread
3696 (
3697  pthread_t* tid,
3698  pthread_attr_t* attr,
3699  void *(*start_routine) (void *),
3700  void* arg
3701  )
3702 {
3703    int retVal = 0;
3704 #ifdef SS_THR_REG_MAP
3705    uint32_t threadCreated = FALSE;
3706 #endif
3707
3708    SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3709    /* Klock work fix ccpu00148484 */
3710    if(threadArg == NULLP)
3711    {
3712       return RFAILED;
3713    }
3714    threadArg->argument = arg;
3715    threadArg->start_routine = start_routine;
3716
3717
3718    printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3719    {
3720 #ifdef SS_THR_REG_MAP
3721       /* When the thread is created, we check for the memory mapping table if
3722        * threadId can be placed in thread memory map table. If it is not able to place
3723        * threadId is stored in tmporary array. Once thread is created successful,
3724        * thread_cancel is sent for each thread which are created before. All the 
3725        * threads are made to wait on sema which is cancel point for thread.
3726        */
3727       while(threadCreated == FALSE)
3728       {
3729 #endif
3730          /*pthreadCreateHdlr */
3731          if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3732          {
3733
3734             return (retVal);
3735          }
3736 #ifdef SS_THR_REG_MAP
3737          threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3738       }
3739 #endif
3740    }
3741
3742    return (retVal);
3743 }
3744
3745
3746 /*
3747  *
3748  *       Fun:   Set Pthread Attributes
3749  *
3750  *       Desc:  This function is used to set various explicit
3751  *              pthread attributes like, priority scheduling,etc
3752  *
3753  *       Ret:   ROK      - ok
3754  *
3755  *       Notes:
3756  *
3757  *       File:  mt_ss.c
3758  *
3759  */
3760
3761    static S16 ssdSetPthreadAttr
3762 (
3763  S32              tskPrior,
3764  pthread_attr_t  *attr
3765  )
3766 {
3767    struct sched_param    param;
3768
3769
3770    SMemSet(&param, 0, sizeof(param));
3771
3772 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3773    param.sched_priority = 100 - 1 - tskPrior;
3774 #else
3775    param.sched_priority = 100 - 10 - tskPrior;
3776 #endif
3777
3778 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3779    /* TODO:: This can be avoided by reducing the priority
3780     * of iccserv thread in l1_master.sh*/
3781 #ifdef L2_L3_SPLIT
3782    if (clusterMode == RADIO_CLUSTER_MODE)
3783    {
3784       if(tskPrior == PRIOR1)
3785       {/* DL RLC */
3786          param.sched_priority = 91;
3787       }
3788    }
3789
3790 #endif
3791 #endif
3792
3793    printf("\nSet priority %u\n", param.sched_priority);
3794
3795    /* Set Scheduler to explicit, without this non of the below
3796       pthread attr works */
3797 #ifdef  TENB_RTLIN_CHANGES
3798    pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3799 #endif
3800
3801    pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3802    pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3803    pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3804 #ifdef TENB_RTLIN_CHANGES
3805    pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3806 #endif
3807    pthread_attr_setschedparam(attr, &param);
3808
3809    return  (ROK);
3810
3811 } /* ssdSetPthreadAttr */
3812
3813 /************* multi-core support **************/
3814 /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
3815 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3816
3817 /*
3818  *
3819  *       Fun:   Get the current core/cpu affinity for a thread/lwp
3820  *
3821  *       Desc:  This function is used to get the current processor/core
3822  *              affinity for a a system task (thread/lwp). It sets the
3823  *              affinity based on the mode supplied by the caller.
3824  *
3825  *       Ret:   ROK      - ok
3826  *              RFAILED  - failed, general (optional)
3827  *
3828  *       Notes:
3829  *
3830  *       File:  ss_task.c
3831  *
3832  */
3833    S16 ssdGetAffinity
3834 (
3835  SSTskId *tskId,                  /* filled in with system task ID */
3836  uint32_t *coreId                      /* the core/processor id to which the affinity is set */
3837  )
3838 {
3839
3840    uint32_t tskInd;
3841
3842 #ifdef SS_LINUX
3843
3844    pthread_t tId =0;
3845    cpu_set_t cpuSet;
3846    uint32_t cpuInd = 0;
3847    /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3848 #else
3849 #ifdef SUNOS
3850    uint32_t lwpId = *tskId;
3851 #endif /*SUNOS*/
3852 #endif /*SS_LINUX*/
3853 #ifdef SS_LINUX
3854    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
3855    {
3856       if (osCp.sTskTbl[tskInd].tskId == *tskId)
3857       {
3858          tId = osCp.sTskTbl[tskInd].dep.tId;
3859          break;
3860       } /* end if */
3861    } /* end for */
3862
3863    /* if tskId is not found in the tskTbl */
3864    if (tskInd == SS_MAX_STSKS)
3865    {
3866       MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3867       return RFAILED;
3868    }
3869
3870
3871    /* initialize the cpu mask */
3872    CPU_ZERO( &cpuSet);
3873
3874    /* set thread affinity for linux */
3875    if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3876    {
3877 #if (ERRCLASS & ERRCLS_DEBUG)
3878       MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3879 #endif
3880       return RFAILED;
3881    } /* end if pthread_setaffinity fails */
3882
3883    for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3884    {
3885       if (CPU_ISSET (cpuInd, & cpuSet))
3886       {
3887          *coreId = cpuInd;
3888          break;
3889       } /* end if */
3890    } /* end for */
3891
3892 #else
3893 #ifdef SUNOS
3894    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
3895    {
3896       if (osCp.sTskTbl[tskInd].tskId == *tskId)
3897       {
3898          lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3899          break;
3900       } /* end if */
3901    } /* end for */
3902
3903    /* if tskId is not found in the tskTbl */
3904    if (tskInd == SS_MAX_STSKS)
3905    {
3906       MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3907       return RFAILED;
3908    }
3909
3910    /* set thread affinity for Solaris */
3911    if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3912    {
3913 #if (ERRCLASS & ERRCLS_DEBUG)
3914       MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3915 #endif
3916       return RFAILED;
3917    } /* end if processor_bind fails */
3918
3919 #endif /* SUNOS */
3920 #endif /* SS_LINUX */
3921
3922    return ROK;
3923
3924 } /* ssdGetAffinity */
3925
3926
3927 /*
3928  *
3929  *       Fun:   Set the core/cpu affinity for a thread/lwp
3930  *
3931  *       Desc:  This function is used to set processor/core affinity for a
3932  *              a system task (thread/lwp). It sets the affinity based on the
3933  *              mode supplied by the caller.
3934  *
3935  *       Ret:   ROK      - ok
3936  *              RFAILED  - failed, general (optional)
3937  *
3938  *       Notes:
3939  *
3940  *       File:  ss_task.c
3941  *
3942  */
3943    S16 ssdSetAffinity
3944 (
3945  SSTskId *tskId,                  /* filled in with system task ID */
3946  uint32_t coreId                       /* the core/processor id to which the affinity has to be set */
3947  )
3948 {
3949
3950    uint32_t tskInd = 0;
3951 #ifdef SS_LINUX
3952
3953    pthread_t tId = 0;
3954    cpu_set_t cpuSet;
3955    /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3956 #else
3957 #ifdef SUNOS
3958    uint32_t lwpId = *tskId;
3959 #endif /*SUNOS*/
3960 #endif /*SS_LINUX*/
3961
3962
3963 #ifdef SS_LINUX
3964    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
3965    {
3966       /* Here tskId can not be used as index as the task may be terminated if
3967          there is a TERM even for that tsk, thus breaking the task Id numbering
3968          sequence  */
3969       if (osCp.sTskTbl[tskInd].tskId == *tskId)
3970       {
3971          tId = osCp.sTskTbl[tskInd].dep.tId;
3972          break;
3973       } /* end if */
3974    } /* end for */
3975
3976    /* if tskId is not found in the tskTbl */
3977    if (tskInd == SS_MAX_STSKS)
3978    {
3979       MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3980       return RFAILED;
3981    }
3982
3983    /* initialize the cpu mask */
3984    CPU_ZERO( &cpuSet);
3985
3986    /* set the cpu mask */
3987    CPU_SET(coreId, &cpuSet);
3988
3989    /* set thread affinity for linux */
3990    if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3991    {
3992 #if (ERRCLASS & ERRCLS_DEBUG)
3993       MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
3994 #endif
3995       return RFAILED;
3996    } /* end if pthread_setaffinity fails */
3997
3998 #else
3999 #ifdef SUNOS
4000    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
4001    {
4002       /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable  in dep */
4003       if (osCp.sTskTbl[tskInd].tskId == *tskId)
4004       {
4005          lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4006          break;
4007       } /* end if */
4008    } /* end for */
4009
4010    /* if tskId is not found in the tskTbl */
4011    if (tskInd == SS_MAX_STSKS)
4012    {
4013       MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4014       return RFAILED;
4015    }
4016
4017    /* set thread affinity for Solaris */
4018    if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4019    {
4020 #if (ERRCLASS & ERRCLS_DEBUG)
4021       MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4022 #endif
4023       return RFAILED;
4024    } /* end if processor_bind fails */
4025
4026 #endif /* SUNOS */
4027 #endif /* SS_LINUX */
4028    return ROK;
4029 } /* ssdSetAffinity */
4030
4031 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4032 /************ end multi-core support *************/
4033
4034 \f
4035 /*
4036  *
4037  *       Fun:   ssdDestroySTsk
4038  *
4039  *       Desc:  This function destroys a system task. A terminate
4040  *              event message is sent to the thread function.
4041  *
4042  *       Ret:   ROK      - ok
4043  *
4044  *       Notes:
4045  *
4046  *       File:  mt_ss.c
4047  *
4048  */
4049    S16 ssdDestroySTsk
4050 (
4051  SsSTskEntry *sTsk           /* pointer to system task entry */
4052  )
4053 {
4054    Buffer *mBuf;
4055    SsMsgInfo *mInfo;
4056
4057
4058
4059
4060    /* we send a message to this system task to tell it to die */
4061    if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4062    {
4063
4064 #if (ERRCLASS & ERRCLASS_DEBUG)
4065       MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4066 #endif
4067
4068       return RFAILED;
4069    }
4070
4071    mInfo = (SsMsgInfo *)mBuf->b_rptr;
4072    mInfo->eventInfo.event = SS_EVNT_TERM;
4073
4074    if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4075    {
4076       SPutMsg(mBuf);
4077
4078 #if (ERRCLASS & ERRCLASS_DEBUG)
4079       MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4080             "Could not write to demand queue");
4081 #endif
4082
4083       return RFAILED;
4084    }
4085
4086
4087    return ROK;
4088 }
4089
4090 /* mt023.201 - Added SThreadYield function to yield CPU
4091  *
4092  *       Fun:   SThreadYield
4093  *
4094  *       Desc:  This function defers thread execution to any other ready
4095  *              thread.
4096  *
4097  *       Ret:   ROK      - ok
4098  *              RFAILED  - failure
4099  *
4100  *       Notes:
4101  *
4102  *       File:  mt_ss.c
4103  *
4104  */
4105 S16 SThreadYield(void)
4106 {
4107
4108
4109    /* mt024.201 - seperated Linux and other UNIX implementations
4110     */
4111 #ifdef SS_LINUX
4112    {
4113       struct timeval tw;
4114
4115       /* Set sleep value to 0 to yield CPU */
4116       tw.tv_sec=0;
4117       tw.tv_usec=0;
4118
4119       return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4120    }
4121 #else /* other UNICes */
4122
4123    return (sleep(0) == 0 ? ROK : RFAILED);
4124
4125 #endif /* SS_LINUX */
4126
4127 }
4128
4129 \f
4130 /*
4131  *
4132  *       Fun:   Register timer
4133  *
4134  *       Desc:  This function is used to register a timer
4135  *              function for the service user. System services
4136  *              will invoke the timer activation function
4137  *              passed to it at the specified intervals.
4138  *
4139  *       Ret:   ROK      - ok
4140  *
4141  *       Notes: Timing is handled by the common timers. The
4142  *              ticks are handled by a thread that uses
4143  *              nanosleep() and thus timing precision will not
4144  *              be very accurate.
4145  *
4146  *       File:  mt_ss.c
4147  *
4148  */
4149    S16 ssdRegTmr
4150 (
4151  SsTmrEntry *tmr             /* pointer to timer entry */
4152  )
4153 {
4154    CmTmrArg arg;
4155
4156
4157
4158
4159    /* initialize common timers */
4160    cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4161
4162
4163    /* start the timer */
4164    arg.tq = osCp.dep.tmrTq;
4165    arg.tqCp = &osCp.dep.tmrTqCp;
4166    arg.timers = tmr->dep.timers;
4167    arg.cb = (PTR) tmr;
4168    arg.evnt = TMR_DEF;
4169    arg.wait = 0;
4170    arg.tNum = NOTUSED;
4171    arg.max = TMR_DEF_MAX;
4172    arg.wait = tmr->interval;
4173    cmPlcCbTq(&arg);
4174
4175
4176    return ROK;
4177 }
4178
4179 \f
4180 /*
4181  *
4182  *       Fun:   Deregister timer
4183  *
4184  *       Desc:  This function is used to deregister a timer function.
4185  *
4186  *       Ret:   ROK      - ok
4187  *
4188  *       Notes:
4189  *
4190  *       File:  mt_ss.c
4191  *
4192  */
4193    S16 ssdDeregTmr
4194 (
4195  SsTmrEntry *tmr             /* pointer to timer entry */
4196  )
4197 {
4198    CmTmrArg arg;
4199
4200
4201
4202
4203    /* stop the timer */
4204    arg.tq = osCp.dep.tmrTq;
4205    arg.tqCp = &osCp.dep.tmrTqCp;
4206    arg.timers = tmr->dep.timers;
4207    arg.cb = (PTR) tmr;
4208    arg.evnt = TMR_DEF;
4209    arg.wait = 0;
4210    arg.tNum = NOTUSED;
4211    arg.max = TMR_DEF_MAX;
4212    arg.wait = tmr->interval;
4213    cmRmvCbTq(&arg);
4214
4215
4216    return ROK;
4217 }
4218
4219 \f
4220 /*
4221  *
4222  *       Fun:   Critical error
4223  *
4224  *       Desc:  This function is called when a critical error occurs.
4225  *
4226  *       Ret:   ROK      - ok
4227  *
4228  *       Notes:
4229  *
4230  *       File:  mt_ss.c
4231  *
4232  */
4233    S16 ssdError
4234 (
4235  Seq seq,                    /* sequence number */
4236  Reason reason               /* reset reason */
4237  )
4238 {
4239    S16 i;
4240    pthread_t tId;
4241    Txt errBuf[256];
4242
4243
4244
4245
4246    /* get calling task ID */
4247    tId = pthread_self();
4248
4249
4250    /* set up the message to display */
4251    sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4252          "reason = %d\n\n", (uint8_t)tId, seq, reason);
4253    SPrint(errBuf);
4254
4255
4256    /* delete all system tasks */
4257    for (i = 0;  i < SS_MAX_STSKS;  i++)
4258    {
4259       if (osCp.sTskTbl[i].used
4260             &&  !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4261       {
4262          pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4263       }
4264    }
4265
4266
4267    /* delete self */
4268    pthread_exit(NULLP);
4269
4270
4271    /* won't reach here */
4272    return ROK;
4273 }
4274
4275 \f
4276 /*
4277  *
4278  *       Fun:   Log error
4279  *
4280  *       Desc:  This function is called to log an error.
4281  *
4282  *       Ret:   ROK      - ok
4283  *
4284  *       Notes:
4285  *
4286  *       File:  mt_ss.c
4287  *
4288  */
4289    Void ssdLogError
4290 (
4291  Ent ent,                    /* Calling layer's entity id */
4292  Inst inst,                  /* Calling layer's instance id */
4293  ProcId procId,              /* Calling layer's processor id */
4294  Txt *file,                  /* file name where error occured */
4295  S32 line,                   /* line in file where error occured */
4296  ErrCls errCls,              /* error class */
4297  ErrCode errCode,            /* layer unique error code */
4298  ErrVal errVal,              /* error value */
4299  Txt *errDesc                /* description of error */
4300  )
4301 {
4302 #ifndef DEBUGNOEXIT
4303    S16 i;
4304    pthread_t tId;
4305 #endif
4306    Txt *errClsMsg;
4307    Txt errBuf[512];
4308
4309
4310
4311
4312    /* get calling task ID */
4313 #ifndef DEBUGNOEXIT
4314    tId = pthread_self();
4315 #endif
4316
4317
4318    switch(errCls)
4319    {
4320       case ERRCLS_ADD_RES:
4321          errClsMsg = "ERRCLS_ADD_RES";
4322          break;
4323
4324       case ERRCLS_INT_PAR:
4325          errClsMsg = "ERRCLS_INT_PAR";
4326          break;
4327
4328       case ERRCLS_DEBUG:
4329          errClsMsg = "ERRCLS_DEBUG";
4330          break;
4331
4332          /* mt028.201 : Addition - ERRCLS_FTHA changes */
4333       case ERRCLS_FTHA:
4334          errClsMsg = "ERRCLS_FTHA";
4335          break;
4336
4337       default:
4338          errClsMsg = "INVALID ERROR CLASS!";
4339          break;
4340    }
4341
4342
4343    /*mt009.301 Fixed 64BIT compilation warnings*/
4344 #ifdef ALIGN_64BIT
4345    sprintf(errBuf,
4346          "\nmtss(posix): sw error:  ent: %03d  inst: %03d  proc id: %03d \n"
4347          "file: %s line: %03d errcode: %05d errcls: %s\n"
4348          "errval: %05d  errdesc: %s\n",
4349          ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4350 #else
4351    sprintf(errBuf,
4352          "\nmtss(posix): sw error:  ent: %03d  inst: %03d  proc id: %03d \n"
4353          "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4354          "errval: %05ld  errdesc: %s\n",
4355          ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4356 #endif
4357    SDisplay(0, errBuf);
4358    /* mt001.301 : Additions */
4359 #ifdef SS_LOGGER_SUPPORT
4360    SWrtLogBuf(errBuf);
4361 #endif /* SS_LOGGER_SUPPORT  */
4362
4363
4364 #ifndef DEBUGNOEXIT
4365    /* debug errors halt the system */
4366    if (errCls == ERRCLS_DEBUG)
4367    {
4368       /* mt001.301 : Additions */
4369 #ifdef SS_LOGGER_SUPPORT
4370       SCleanUp();
4371 #endif /* SS_LOGGER_SUPPORT  */
4372       /* delete all system tasks */
4373       for (i = 0;  i < SS_MAX_STSKS;  i++)
4374       {
4375          if (osCp.sTskTbl[i].used
4376                &&  !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4377          {
4378             pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4379          }
4380       }
4381
4382
4383       /* delete self */
4384       pthread_exit(NULLP);
4385    }
4386 #endif
4387
4388
4389    return;
4390 }
4391
4392 #ifdef ENB_RELAY
4393 \f
4394 /*
4395  *
4396  *       Fun:   Register driver task
4397  *
4398  *       Desc:  This function is called to register the handlers for a
4399  *              driver task.
4400  *
4401  *       Ret:   ROK      - ok
4402  *
4403  *       Notes:
4404  *
4405  *       File:  mt_ss.c
4406  *
4407  */
4408    S16 ssdRegDrvrTsk
4409 (
4410  SsDrvrTskEntry *drvrTsk         /* driver task entry */
4411  )
4412 {
4413
4414
4415    return ROK;
4416 }
4417 /* mt001.30 : Additions */
4418 /*
4419  *
4420  *       Fun:   Deregister driver task
4421  *
4422  *       Desc:  This function is called to deregister the handlers for a
4423  *              driver task.
4424  *
4425  *       Ret:   ROK      - ok
4426  *
4427  *       Notes:
4428  *
4429  *       File:  mt_ss.c
4430  *
4431  */
4432    S16 ssdDeregDrvrTsk
4433 (
4434  SsDrvrTskEntry *drvrTsk         /* driver task entry */
4435  )
4436 {
4437
4438
4439    return ROK;
4440 }
4441 #endif
4442
4443
4444
4445 \f
4446 /*
4447  * mt003.301 Additions - SDeRegTTsk fix
4448  */
4449 #ifdef SS_MULTIPLE_PROCS
4450    S16 ssdProcTTskTerm
4451 (
4452  ProcId procIdx,
4453  SsTTskEntry *tTsk,
4454  SsIdx idx
4455  )
4456 #else /*SS_MULTIPLE_PROCS*/
4457    S16 ssdProcTTskTerm
4458 (
4459  SsTTskEntry *tTsk,
4460  SsIdx idx
4461  )
4462 #endif /*SS_MULTIPLE_PROCS*/
4463 {
4464 #ifdef SS_MULTIPLE_PROCS
4465    ProcId proc;
4466 #endif
4467    Ent ent;
4468    Inst inst;
4469    SsSTskEntry *sTsk;
4470    S16 n;
4471    S16  ret;
4472
4473
4474
4475    ent = tTsk->ent;
4476    inst = tTsk->inst;
4477    /* We check the sTsk element; if it is not NULLP, the
4478     *  task is attached. So we have to detach it before
4479     *  deregistering the task.
4480     */
4481    ret = SLock(&osCp.sTskTblLock);
4482    if (ret != ROK)
4483    {
4484       MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4485       return RFAILED;
4486    }
4487    SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4488    if (ret != ROK)
4489    {
4490 #if (ERRCLASS & ERRCLS_DEBUG)
4491       MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4492 #endif
4493       if ( SUnlock(&osCp.sTskTblLock) != ROK)
4494       {
4495 #if (ERRCLASS & ERRCLS_DEBUG)
4496          MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4497          return RFAILED;
4498 #endif
4499       }
4500
4501       return RFAILED;
4502    }
4503
4504 #ifdef SS_MULTIPLE_PROCS
4505    proc = tTsk->proc;
4506    if (tTsk->initTsk != NULLP)
4507    {
4508 #ifndef USE_MEMCAL
4509       (Void)(*(tTsk->initTsk))(proc, ent, inst,
4510             DFLT_REGION,
4511             NRM_TERM,
4512             &(osCp.tTskTbl[idx].xxCb));
4513 #else
4514       (Void)(*(tTsk->initTsk))(proc, ent, inst,
4515             SS_STATIC_REGION,
4516             NRM_TERM,
4517             &(osCp.tTskTbl[idx].xxCb));
4518 #endif /* USE_MEMCAL */
4519    }
4520 #endif /* SS_MULTIPLE_PROCS */
4521
4522    if (tTsk->sTsk != NULLP)
4523    {
4524       sTsk = tTsk->sTsk;
4525
4526       sTsk->dep.ent = ent;
4527       sTsk->dep.inst = inst;
4528
4529       for (n = 0;  n < SS_MAX_TTSKS;  n++)
4530       {
4531          if (sTsk->tTsks[n] == idx)
4532          {
4533             sTsk->tTsks[n] = SS_INVALID_IDX;
4534             sTsk->numTTsks--;
4535             break;
4536          }
4537       }
4538
4539       /* call the implementation to detach the task */
4540       ssdDetachTTsk(tTsk);
4541       /* 100178 */
4542       sTsk->dep.ent = ENTNC;
4543       sTsk->dep.inst = INSTNC;
4544    }
4545
4546    /* Now we empty the entry for this task and update the table
4547     *  information
4548     */
4549 #ifdef SS_MULTIPLE_PROCS
4550    osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4551 #else /* SS_MULTIPLE_PROCS */
4552    osCp.tTskIds[ent][inst] = SS_TSKNC;
4553 #endif /* SS_MULTIPLE_PROCS */
4554
4555    tTsk->used    = FALSE;
4556 #ifdef SS_MULTIPLE_PROCS
4557    tTsk->proc    = PROCNC;
4558 #endif /* SS_MULTIPLE_PROCS */
4559    tTsk->ent     = ENTNC;
4560    tTsk->inst    = INSTNC;
4561    tTsk->tskType = TTUND;
4562    tTsk->initTsk = NULLP;
4563    tTsk->actvTsk = NULLP;
4564    tTsk->sTsk    = NULLP;
4565
4566    tTsk->nxt = osCp.nxtTTskEntry;
4567    osCp.nxtTTskEntry = idx;
4568    osCp.numTTsks--;
4569
4570 #ifdef SS_MULTIPLE_PROCS
4571    /* mark the control block for this task as invalid */
4572    osCp.tTskTbl[idx].xxCb = NULLP;
4573 #endif
4574
4575    SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4576    if ( SUnlock(&osCp.sTskTblLock) != ROK)
4577    {
4578 #if (ERRCLASS & ERRCLS_DEBUG)
4579       MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4580 #endif
4581       return RFAILED;
4582    }
4583    return ROK;
4584 }
4585
4586 //#ifndef SPLIT_RLC_DL_TASK
4587 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4588 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK) 
4589 Void ysMtTskHdlr(Void);
4590 Void ysMtPollPhyMsg(uint8_t region);
4591 Void ysMtRcvPhyMsg(Void);
4592    Void *mtTskHdlrT2kL2
4593 (
4594  Ptr tskPtr                      /* pointer to task entry */
4595  )
4596 {
4597    S16 ret;
4598
4599
4600    /* wait for SS to come up */
4601    /* It is required to block on this semaphore before starting actual processing of 
4602       the thread becasue the creator of this thread might want to cance it without
4603       doing any processing. When this semaphore is released, means the creator gives
4604       the go ahead for actual processing and we should never come back to this point */
4605    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4606       continue;
4607
4608 #ifdef YS_PHY_3_8_2
4609    tlSetReady(NULL);
4610 #endif
4611
4612    while(1)
4613    {
4614       ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4615                           * (processes L1 msgs) */
4616    }
4617
4618    return (NULLP);
4619 }
4620 #else
4621 Void ysMtTskHdlr(Void);
4622 Void YsPhyRecvMsg();
4623    Void *mtTskHdlrT2kL2
4624 (
4625  Ptr tskPtr                      /* pointer to task entry */
4626  )
4627 {
4628    S16 ret;
4629    SsSTskEntry *sTsk;
4630
4631    /* get out the system task entry from the parameter */
4632    sTsk = (SsSTskEntry *) tskPtr;
4633
4634    /* wait for SS to come up */
4635    /* It is required to block on this semaphore before starting actual processing of 
4636       the thread becasue the creator of this thread might want to cance it without
4637       doing any processing. When this semaphore is released, means the creator gives
4638       the go ahead for actual processing and we should never come back to this point */
4639    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4640       continue;
4641
4642 #ifndef RGL_SPECIFIC_CHANGES
4643 #ifdef YS_PHY_3_8_2
4644    tlSetReady(NULL);
4645 #endif
4646 #endif
4647
4648    while(1)
4649    {
4650 #ifdef V5GTF_SPECIFIC_CHANGES
4651       YsPhyRecvMsg();      
4652 #else      
4653       ysMtTskHdlr(); /* blocks, waiting for messages for L2
4654                       * (processes L1 msgs) */
4655 #endif
4656       /* get a message from the demand queue */
4657       /* RT Processing */
4658 #ifdef RLC_MAC_DAT_REQ_RBUF
4659       rgDlDatReqBatchProc();
4660 #endif
4661
4662       ret = mtTskHdlMsg(sTsk); 
4663       if (ret != ROK)
4664       {
4665          /* exit the for loop here */
4666          break;
4667       }
4668 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4669       rgBatchProc();
4670 #endif  
4671    }
4672
4673    return (NULLP);
4674 }
4675 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4676 #endif
4677
4678 void *pthreadCreateHdlr(void * arg)
4679 {
4680    S16 ret;
4681    SPThreadCreateArg*  pthreadCreateArg = (SPThreadCreateArg*)arg;
4682    /* mt038.201 changed how sem_wait is called  */
4683    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4684       continue;
4685
4686    pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4687    return ROK;
4688 }
4689 \f
4690 /*
4691  *
4692  *       Fun:   Task handler
4693  *
4694  *       Desc:  This is the system task handler function. It blocks on
4695  *              the system task's demand queue. On receiving a message,
4696  *              it identifies the target TAPA task, verifies that the
4697  *              TAPA task belongs to this system task and if so, calls
4698  *              the activation function of that TAPA task with the
4699  *              received message. The task activation function or the
4700  *              timer activation function may be called.
4701  *
4702  *       Ret:   (thread function)
4703  *
4704  *       Notes:
4705  *
4706  *       File:  mt_ss.c
4707  *
4708  */
4709    Void *mtTskHdlr
4710 (
4711  Ptr tskPtr                      /* pointer to task entry */
4712  )
4713 {
4714    S16 ret = ROK;
4715    SsSTskEntry *sTsk;
4716
4717    /* get out the system task entry from the parameter */
4718    sTsk = (SsSTskEntry *) tskPtr;
4719
4720
4721    /* wait for SS to come up */
4722
4723    /* mt038.201 changed how sem_wait is called  */
4724    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4725       continue;
4726 #ifdef XEON_SPECIFIC_CHANGES
4727    printf("\n**********MT Task Handler********\n");
4728 #endif   
4729    while (1)
4730    {
4731       /* Wait for a message from the demand queue */
4732 #ifdef SS_CDMNDQ_SUPPORT
4733       ret = ssCDmndQWait(&sTsk->dQ);
4734 #else
4735       ret = ssDmndQWait(&sTsk->dQ);
4736 #endif
4737       if (ret != ROK)
4738          continue;
4739
4740       ret = mtTskHdlMsg(sTsk); 
4741       if (ret != ROK)
4742       {
4743          break;
4744       }
4745    }
4746
4747    return (NULLP);
4748 }
4749
4750 \f
4751 /*
4752  *
4753  *       Fun:   Task handler
4754  *
4755  *       Desc:  This is the system task handler function. It blocks on
4756  *              the system task's demand queue. On receiving a message,
4757  *              it identifies the target TAPA task, verifies that the
4758  *              TAPA task belongs to this system task and if so, calls
4759  *              the activation function of that TAPA task with the
4760  *              received message. The task activation function or the
4761  *              timer activation function may be called.
4762  *
4763  *       Ret:   (thread function)
4764  *
4765  *       Notes:
4766  *
4767  *       File:  mt_ss.c
4768  *
4769  */
4770    S16 mtTskHdlMsg
4771 (
4772  SsSTskEntry *sTsk
4773  )
4774 {
4775    S16 i =0;
4776    S16 ret =0;
4777    SsIdx idx =0;
4778    SsTTskEntry *tTsk=NULLP;
4779    Buffer *mBuf=NULLP;
4780 #ifdef SS_PERF
4781    Buffer *mBuf2=NULLP;
4782 #endif
4783    SsMsgInfo *mInfo=NULLP;
4784    Pst nPst;
4785    /* mt028.201: modification: multiple procs support related changes */
4786 #ifndef SS_MULTIPLE_PROCS
4787 #ifdef SS_MT_TMR
4788    PAIFTMRS16 tmrActvFnMt = NULLP;
4789 #endif
4790    /* mt015.301 Initialized the timer activation functions with NULLP */
4791    PFS16 tmrActvFn = NULLP;
4792 #else
4793    PAIFTMRS16 tmrActvFn =NULLP;
4794    uint16_t procIdIdx =0;
4795 #endif /* SS_MULTIPLE_PROCS */
4796    /* mt003.301 Modifications */
4797 #ifdef SS_THREAD_PROFILE
4798    EpcTime et1,et2;
4799 #endif /* SS_THREAD_PROFILE */
4800
4801
4802    ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4803    if (ret != ROK)
4804    {
4805       /* nothing to receive */
4806       return ROK;
4807    }
4808
4809    /* if we can't lock this system task entry, return the message */
4810    ret = SLock(&sTsk->lock);
4811    if (ret != ROK)
4812    {
4813
4814 #if (ERRCLASS & ERRCLS_DEBUG)
4815       MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4816             "Could not lock system task entry");
4817 #endif
4818       SPutMsg(mBuf);
4819       return ROK;
4820    }
4821
4822    /* mt034.201 */
4823 #ifdef SS_PERF
4824    do 
4825    {
4826       mBuf2 = mBuf->b_next;
4827 #endif
4828       /* find out what kind of message this is */
4829       mInfo = (SsMsgInfo *)mBuf->b_rptr;
4830 #ifdef SS_MEM_WL_DEBUG
4831       mtTskBuffer1 = mBuf2;
4832       if(mBuf2)
4833          mtTskBuffer2 = mBuf2->b_next;
4834
4835       if(mInfo == 0x5050505)
4836       {
4837          stopBtInfo = TRUE;
4838          SGlobMemInfoShow();
4839          cmAnalyseBtInfo((PTR) mBuf,4);
4840          SGlobMemInfoShow();
4841          printf("\n In trouble .... \n");
4842       }
4843       else if (mInfo == 0x2020202)
4844       {
4845          stopBtInfo = TRUE;
4846          cmAnalyseBtInfo((PTR) mBuf,1);
4847          printf("\n In trouble .... \n");
4848       }
4849 #endif /* SS_MEM_WL_DEBUG */
4850       switch (mInfo->eventInfo.event)
4851       {
4852          /* this is a termination event, we die */
4853          case SS_EVNT_TERM:
4854             /* release the message */
4855             SPutMsg(mBuf);
4856
4857             /* Unlock the system task entry and lock the system
4858              *  task table to clean our entry up.
4859              */
4860             SUnlock(&sTsk->lock);
4861
4862             ret = SLock(&osCp.sTskTblLock);
4863             if (ret != ROK)
4864             {
4865
4866 #if (ERRCLASS & ERRCLS_DEBUG)
4867                MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
4868                      "Could not lock system task table");
4869 #endif
4870                /* what to do here? */
4871                return ROK;
4872             }
4873
4874             /* clean up the system task entry */
4875             sTsk->used = FALSE;
4876             sTsk->tskPrior = 0;
4877             /* mt003.301 Modifications - SDeRegTTsk */
4878             /* sTsk->numTTsks = 0; */
4879             SDestroyLock(&sTsk->lock);
4880             ssDestroyDmndQ(&sTsk->dQ);
4881
4882             /* lock for current executing TAPA task ID */
4883
4884             /* make this entry available in the system task table */
4885             sTsk->nxt = osCp.nxtSTskEntry;
4886             for (i = 0;  i < SS_MAX_STSKS;  i++)
4887             {
4888                if (sTsk == &osCp.sTskTbl[i])
4889                {
4890                   osCp.nxtSTskEntry = i;
4891                   break;
4892                }
4893             }
4894
4895             osCp.numSTsks--;
4896
4897             /* unlock the system task table */
4898             SUnlock(&osCp.sTskTblLock);
4899
4900             return RFAILED;
4901
4902
4903             /* this is a data message or a permanent task keep-alive message */
4904          case SS_EVNT_DATA:
4905          case SS_EVNT_PERMTICK:
4906             /* message to a task. find the destination task */
4907             /* mt028.201: modification: multiple procs support related changes */
4908 #ifdef SS_MULTIPLE_PROCS
4909             procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
4910
4911             if (procIdIdx == SS_INV_PROCID_IDX)
4912             {
4913                SPutMsg(mBuf);
4914                break;
4915             }
4916
4917             idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
4918 #else /* SS_MULTIPLE_PROCS */
4919             idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
4920 #endif /* SS_MULTIPLE_PROCS */
4921
4922             /* verify that it hasn't been deregistered */
4923             if (idx == SS_TSKNC)
4924             {
4925                SPutMsg(mBuf);
4926                break;
4927             }
4928
4929             /* verify that this system task is still running it */
4930             tTsk = &osCp.tTskTbl[idx];
4931             if (tTsk->sTsk != sTsk)
4932             {
4933                SPutMsg(mBuf);
4934                break;
4935             }
4936
4937             /* set the current executing TAPA task ID */
4938             sTsk->dep.ent = mInfo->pst.dstEnt;
4939             sTsk->dep.inst = mInfo->pst.dstInst;
4940
4941             /* copy the Pst structure into a local duplicate */
4942             for (i = 0;  i < (S16) sizeof(Pst);  i++)
4943                *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
4944
4945             /* Give the message to the task activation function. If
4946              *  its a normal data message, we pass it, if this is a
4947              *  keep-alive message for a permanent task then we pass
4948              *  NULLP in place of the message to the task activation
4949              *  function.
4950              */
4951             if (mInfo->eventInfo.event == SS_EVNT_DATA)
4952             {
4953 #ifndef RGL_SPECIFIC_CHANGES
4954 #ifdef SS_TSKLOG_ENABLE
4955                uint32_t t = MacGetTick();
4956 #endif
4957 #endif
4958                /* mt003.301 Modifications */
4959 #if SS_THREAD_PROFILE
4960                tTsk->curEvent = nPst.event;
4961                SGetEpcTime(&et1);
4962 #endif /* SS_THREAD_PROFILE */
4963                tTsk->actvTsk(&nPst, mBuf);
4964 #ifndef RGL_SPECIFIC_CHANGES
4965 #ifdef SS_TSKLOG_ENABLE
4966                SStopTask(t,PID_SSI_TSK);
4967 #endif
4968 #endif
4969 #if SS_THREAD_PROFILE
4970                SGetEpcTime(&et2);
4971                tTsk->curEvtTime = (uint32_t)(et2 - et1);
4972                tTsk->totTime += (uint64_t)tTsk->curEvtTime;
4973 #endif /* SS_THREAD_PROFILE */
4974             }
4975             else
4976             {
4977 #if (ERRCLASS & ERRCLS_DEBUG)
4978                /* this message should only come to a permanent task */
4979                if (tTsk->tskType != SS_TSK_PERMANENT)
4980                {
4981                   MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
4982                   break;
4983                }
4984 #endif
4985                tTsk->actvTsk(&nPst, NULLP);
4986
4987                /* We need to re-send this message back to ourselves so
4988                 *  the permanent task continues to run.
4989                 */
4990                /* Check if this task got deregistered or detached
4991                 *  by the activation function; if so, there's nothing
4992                 *  more to do here, otherwise go ahead.
4993                 */
4994                ret = ROK;
4995                if (tTsk->used == TRUE  &&  tTsk->sTsk != NULLP)
4996                {
4997                   ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
4998                         ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
4999                         mInfo->pst.prior);
5000                }
5001
5002                /* failure here is a real problem */
5003                if (ret != ROK)
5004                {
5005 #if (ERRCLASS & ERRCLS_DEBUG)
5006                   MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5007                         "Could not write to demand queue");
5008 #endif
5009                   SPutMsg(mBuf);
5010                }
5011             }
5012
5013             /* unset the current executing TAPA task ID */
5014             sTsk->dep.ent = ENTNC;
5015             sTsk->dep.inst = INSTNC;
5016             break;
5017
5018
5019          case SS_EVNT_TIMER:
5020             /* timer event. find the timer entry */
5021             idx = mInfo->eventInfo.u.tmr.tmrIdx;
5022
5023             /* lock the timer table, coz we're going to peek in it */
5024             ret = SLock(&osCp.tmrTblLock);
5025             if (ret != ROK)
5026             {
5027
5028 #if (ERRCLASS & ERRCLS_DEBUG)
5029                MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5030                      "Could not lock timer table");
5031 #endif
5032                SPutMsg(mBuf);
5033                break;
5034             }
5035
5036             /* Verify that this timer entry is still around and that it
5037              *  belongs to our task.
5038              */
5039             if (osCp.tmrTbl[idx].used == FALSE
5040                   /* mt028.201: modification: multiple procs support related changes */
5041 #ifdef SS_MULTIPLE_PROCS
5042                   ||  osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5043 #endif /* SS_MULTIPLE_PROCS */
5044                   ||  osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5045                   ||  osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5046             {
5047                SUnlock(&osCp.tmrTblLock);
5048                SPutMsg(mBuf);
5049                break;
5050             }
5051
5052             /* mt005.21: addition */
5053             /* set the current executing TAPA task ID */
5054             sTsk->dep.ent = mInfo->pst.dstEnt;
5055             sTsk->dep.inst = mInfo->pst.dstInst;
5056
5057 #ifndef SS_MULTIPLE_PROCS
5058 #ifdef SS_MT_TMR
5059             /*mt006.301 Adding Initializing the tmrActvFnMt*/
5060             tmrActvFnMt = NULLP;
5061             if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5062             {
5063                tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5064             }
5065             else
5066 #endif
5067 #endif
5068             {
5069                tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5070             }
5071
5072             /* unlock the timer table */
5073             SUnlock(&osCp.tmrTblLock);
5074
5075             /* activate the timer function */
5076             /* mt028.201: modification: multiple procs support related changes */
5077 #ifndef SS_MULTIPLE_PROCS
5078 #ifdef SS_MT_TMR
5079             if (tmrActvFnMt)
5080             {
5081                tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5082                      osCp.tmrTbl[idx].ownerInst);
5083             }
5084             else
5085 #endif
5086             {
5087                tmrActvFn();
5088             }
5089 #else
5090             tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5091                   osCp.tmrTbl[idx].ownerInst);
5092 #endif /* SS_MULTIPLE_PROCS */
5093
5094             /*mt005.21: addition */
5095             /* unset the current executing TAPA task ID */
5096             sTsk->dep.ent = ENTNC;
5097             sTsk->dep.inst = INSTNC;
5098
5099
5100             /* return the message buffer */
5101             SPutMsg(mBuf);
5102             break;
5103             /*
5104              * mt003.301 - SDeRegTTsk fix
5105              */
5106          case SS_EVNT_TTSK_TERM:
5107 #ifdef SS_MULTIPLE_PROCS
5108             procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5109
5110             if (procIdIdx == SS_INV_PROCID_IDX)
5111             {
5112                SPutMsg(mBuf);
5113                break;
5114             }
5115
5116             idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5117 #else /* SS_MULTIPLE_PROCS */
5118             idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5119 #endif /* SS_MULTIPLE_PROCS */
5120
5121             /* verify that it hasn't been deregistered */
5122             if (idx == SS_TSKNC)
5123             {
5124                SPutMsg(mBuf);
5125                break;
5126             }
5127
5128             /* verify that this system task is still running it */
5129             tTsk = &osCp.tTskTbl[idx];
5130             if (tTsk->sTsk != sTsk)
5131             {
5132                SPutMsg(mBuf);
5133                break;
5134             }
5135 #ifdef SS_MULTIPLE_PROCS
5136             ssdProcTTskTerm(procIdIdx, tTsk, idx);
5137 #else
5138             ssdProcTTskTerm(tTsk, idx);
5139 #endif
5140             SPutMsg(mBuf);
5141             break;
5142
5143          default:
5144 #if (ERRCLASS & ERRCLS_DEBUG)
5145             MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5146                   "Illegal event");
5147 #endif
5148             break;
5149       }
5150 #ifdef SS_PERF
5151       mBuf = mBuf2;
5152    } while (mBuf != NULLP);
5153 #endif
5154
5155    /* unlock the system task entry */
5156    SUnlock(&sTsk->lock);
5157
5158 #ifndef SS_PERF
5159    /* yield for other threads */
5160    /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5161    SThreadYield();
5162 #endif
5163
5164    return ROK;
5165 }
5166
5167 Bool g_usettitmr;
5168 /*
5169  *       Fun:   mtTmrHdlrPublic
5170  */
5171 Void mtTmrHdlrPublic()
5172 {
5173    if (SLock(&osCp.tmrTblLock) != ROK)
5174    {
5175 #if (ERRCLASS & ERRCLS_DEBUG)
5176       MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5177 #endif
5178       return;
5179    }
5180    cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5181    /* unlock the timer table */
5182    SUnlock(&osCp.tmrTblLock);
5183 }
5184
5185 \f
5186 /*
5187  *
5188  *       Fun:   mtTmrHdlr
5189  *
5190  *       Desc:  The timer handler thread function. Counts time
5191  *              and invokes the common timer function on each
5192  *              tick.
5193  *
5194  *       Ret:   (thread function)
5195  *
5196  *       Notes:
5197  *
5198  *       File:  mt_ss.c
5199  *
5200  */
5201 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5202    static Void *mtTmrHdlr
5203 (
5204  void *parm                        /* unused */
5205  )
5206 {
5207    /*mt004.301-addede new region*/
5208    /* mt010.301 Removed SS_FAP portion and
5209     * enabled oroginal code in function mtTmrHdlr */
5210
5211    struct timespec ts;
5212    uint32_t time_int;
5213    uint32_t i, cnt, oldTicks, newTicks;
5214    struct timeval tv1,tv2;
5215    /* mt038.201 added return */
5216    S16 ret;
5217    /* mt039.201 changes for nanosleep */
5218    struct timespec tsN;
5219    static uint32_t err_in_usec;
5220
5221    /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5222
5223
5224    UNUSED(parm);
5225
5226    /* mt027.201 - Modification for SRegCfgTmr support */
5227    /* check SS_TICKS_SEC */
5228    if (SS_1MS < SS_TICKS_SEC)
5229    {
5230       MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5231    }
5232
5233    /* mt025.201 - Addition to stop timer handler till task registration is done */
5234    /* wait for SS to come up */
5235    /* mt038.201 changed how sem_wait is called  */
5236    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5237       continue;
5238
5239    /* mt027.201 - Modification for SRegCfgTmr support */
5240    /* set up parameter to nanosleep() for SS_TICKS_SEC */
5241    ts.tv_sec = 0;
5242    ts.tv_nsec = (MT_TICK_CNT * 1000);
5243    /* mt039.201 changes for nanosleep */
5244    tsN.tv_sec = 0;
5245    tsN.tv_nsec = 0;
5246
5247    err_in_usec =  0;
5248
5249    if (gettimeofday(&tv1, NULL) == -1)
5250    {
5251 #if (ERRCLASS & ERRCLS_DEBUG)
5252       MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5253             "Error in clock_gettime");
5254 #endif
5255    }
5256
5257    /* infinite loop */
5258    for (; ;)
5259    {
5260 #if 1
5261       if (g_usettitmr)
5262       {
5263 #ifndef STUB_TTI_HANDLING_5GTF        
5264          printf("\nReturning from mtTmrHdlr()\n");
5265          return NULL;
5266 #endif        
5267       }
5268 #endif
5269       /* mt039.201 changes for nanosleep */
5270       /* sleep for MT_TICK_CNT milli seconds */
5271       ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5272       while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5273       {
5274          ts.tv_nsec = tsN.tv_nsec;
5275          tsN.tv_nsec = 0;
5276          continue;
5277       }
5278
5279       if (gettimeofday(&tv2,NULL) == -1)
5280       {
5281 #if (ERRCLASS & ERRCLS_DEBUG)
5282          MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5283                "Error in clock_gettime");
5284 #endif
5285       }
5286
5287       /*mt013.301 : changed check while calculating timer to fix
5288        * diffrence between MTSS time and real unix time
5289        */
5290       if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5291       {
5292          time_int = (tv2.tv_usec - tv1.tv_usec);
5293       }
5294       else if (tv2.tv_sec > tv1.tv_sec)
5295       {
5296          time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5297       }
5298       else /*  ts2 < ts1, this will not happen in normal scenario */
5299       {
5300          /* to make sure cnt = 1  */
5301          err_in_usec = 0;
5302          time_int = MT_TICK_CNT;
5303       }
5304
5305       oldTicks = osCp.dep.sysTicks;
5306       osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5307       err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5308       newTicks = osCp.dep.sysTicks;
5309       tv1.tv_usec = tv2.tv_usec;
5310       tv1.tv_sec = tv2.tv_sec;
5311
5312       cnt = newTicks - oldTicks;
5313
5314       while(err_in_usec >= MT_TICK_CNT)
5315       {
5316          cnt++;
5317          err_in_usec -= MT_TICK_CNT;
5318       }
5319       if( cnt >= MT_MAX_TICK_CNT_VAL)
5320          cnt = MT_MIN_TICK_CNT_VAL;
5321       /* call the common timer tick handler */
5322       for (i = 0; i < cnt; i++)
5323       {
5324          /* mt008.301: cmPrcTmr is guarded with a lock */
5325          /* lock the timer table */
5326          if (SLock(&osCp.tmrTblLock) != ROK)
5327          {
5328 #if (ERRCLASS & ERRCLS_DEBUG)
5329             MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5330 #endif
5331             continue;
5332          }
5333          cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5334          /* unlock the timer table */
5335          SUnlock(&osCp.tmrTblLock);
5336       }
5337    }
5338
5339    /* mt009.21: addition */
5340    return ( (Void *) NULLP);
5341    /* will not reach here */
5342 }
5343
5344 \f
5345 /*
5346  *
5347  *       Fun:   mtTimeout
5348  *
5349  *       Desc:  Process timer event. Called from the common timer
5350  *              code when a timeout occurs.
5351  *
5352  *       Ret:   Void
5353  *
5354  *       Notes:
5355  *
5356  *       File:  mt_ss.c
5357  *
5358  */
5359    Void mtTimeout
5360 (
5361  PTR tCb,                        /* control block */
5362  S16 evnt                        /* event */
5363  )
5364 {
5365    Buffer *mBuf;
5366    SsMsgInfo *mInfo;
5367    CmTmrArg arg;
5368    SsTmrEntry *tEnt;
5369    SsTTskEntry *tTsk;
5370    SsIdx idx;
5371 #ifndef TENB_RTLIN_CHANGES
5372    S16 ret;
5373 #endif
5374    /* mt028.201: modification: multiple procs support related changes */
5375 #ifdef SS_MULTIPLE_PROCS
5376    uint16_t procIdIdx;
5377 #endif /* SS_MULTIPLE_PROCS */
5378 #ifdef RGL_SPECIFIC_CHANGES
5379 #ifdef MSPD_MLOG_NEW
5380    uint32_t t = GetTIMETICK();
5381 #endif
5382 #endif
5383
5384
5385
5386    /* get the timer entry */
5387    tEnt = (SsTmrEntry *) tCb;
5388
5389
5390    /* if the timer was deleted, this will be NULL, so drop it */
5391    if (tEnt == NULL)
5392    {
5393       return;
5394    }
5395
5396    /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5397
5398
5399    /* Hmmmm, the timer might have been deleted while we've been
5400     *  working at getting here, so we just skip this.
5401     */
5402    if (tEnt->used == FALSE)
5403    {
5404       return;
5405    }
5406
5407
5408    /* Set up and send a timer message to the destination tasks'
5409     * demand queue.
5410     */
5411 #ifndef SS_MULTICORE_SUPPORT
5412    if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5413 #else
5414 #ifdef RGL_SPECIFIC_CHANGES
5415       if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5416 #else
5417          if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5418 #endif
5419 #endif
5420          {
5421
5422 #if (ERRCLASS & ERRCLS_DEBUG)
5423             MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5424 #endif
5425
5426             return;
5427          }
5428
5429    mInfo = (SsMsgInfo *)mBuf->b_rptr;
5430    mInfo->eventInfo.event = SS_EVNT_TIMER;
5431    mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5432
5433    mInfo->pst.dstEnt = tEnt->ownerEnt;
5434    mInfo->pst.dstInst = tEnt->ownerInst;
5435    mInfo->pst.srcEnt = tEnt->ownerEnt;
5436    mInfo->pst.srcInst = tEnt->ownerInst;
5437    /* mt028.201: modification: multiple procs support related changes */
5438 #ifndef SS_MULTIPLE_PROCS
5439    mInfo->pst.dstProcId = SFndProcId();
5440    mInfo->pst.srcProcId = SFndProcId();
5441 #else /* SS_MULTIPLE_PROCS */
5442    mInfo->pst.dstProcId = tEnt->ownerProc;
5443    mInfo->pst.srcProcId = tEnt->ownerProc;
5444 #endif /* SS_MULTIPLE_PROCS */
5445    mInfo->pst.selector = SEL_LC_NEW;
5446 #ifndef SS_MULTICORE_SUPPORT
5447    mInfo->pst.region = DFLT_REGION;
5448 #else
5449 #endif
5450    mInfo->pst.pool = DFLT_POOL;
5451    mInfo->pst.prior = PRIOR0;
5452    mInfo->pst.route = RTESPEC;
5453    mInfo->pst.event = 0;
5454
5455
5456 #ifndef TENB_RTLIN_CHANGES
5457    /* get a semaphore for the TAPA task table */
5458    SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5459    if (ret != ROK)
5460    {
5461       SPutMsg(mBuf);
5462
5463 #if (ERRCLASS & ERRCLS_DEBUG)
5464       MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5465 #endif
5466
5467       return;
5468    }
5469 #endif
5470
5471
5472    /* find the owner TAPA task */
5473    /* mt028.201: modification: multiple procs support related changes */
5474 #ifdef SS_MULTIPLE_PROCS
5475    procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5476    idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5477 #else /* SS_MULTIPLE_PROCS */
5478    idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5479 #endif /* SS_MULTIPLE_PROCS */
5480    if (idx == SS_TSKNC)
5481    {
5482 #ifndef TENB_RTLIN_CHANGES
5483       SS_RELEASE_SEMA(&osCp.tTskTblSem);
5484 #endif
5485       SPutMsg(mBuf);
5486       return;
5487    }
5488
5489
5490    /* ensure that the TAPA task is hale and hearty */
5491    tTsk = &osCp.tTskTbl[idx];
5492    if (!tTsk->used)
5493    {
5494 #ifndef TENB_RTLIN_CHANGES
5495       SS_RELEASE_SEMA(&osCp.tTskTblSem);
5496 #endif
5497       SPutMsg(mBuf);
5498       return;
5499    }
5500    /* Klock work fix ccpu00148484 */
5501    /* write the timer message to the queue of the destination task */
5502    /* mt008.301 : check sTsk before putting into it's DQ */
5503    if (tTsk->sTsk == NULLP)
5504    {
5505 #ifndef TENB_RTLIN_CHANGES
5506       SS_RELEASE_SEMA(&osCp.tTskTblSem);
5507 #endif
5508       SPutMsg(mBuf);
5509
5510 #if (ERRCLASS & ERRCLS_DEBUG)
5511       MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5512             "Could not write to demand queue");
5513 #endif
5514
5515       return;
5516    }
5517 #ifdef SS_LOCKLESS_MEMORY
5518    mInfo->pst.region = tTsk->sTsk->region;
5519    mInfo->region = tTsk->sTsk->region;
5520 #endif /* SS_LOCKLESS_MEMORY */
5521    if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5522             (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5523    {
5524 #ifndef TENB_RTLIN_CHANGES
5525       SS_RELEASE_SEMA(&osCp.tTskTblSem);
5526 #endif
5527       SPutMsg(mBuf);
5528
5529 #if (ERRCLASS & ERRCLS_DEBUG)
5530       MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5531             "Could not write to demand queue");
5532 #endif
5533
5534       return;
5535    }
5536    /* Fix for ccpu00130657 */
5537 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5538    if (tTsk->sTsk->tskPrior == PRIOR0)
5539    {
5540 #ifdef INTEL_WLS
5541       WLS_WakeUp(mtGetWlsHdl());
5542 #else
5543       tlPost(NULLP);
5544 #endif
5545    }
5546 #endif
5547
5548    /* release the semaphore for the TAPA task table */
5549 #ifndef TENB_RTLIN_CHANGES
5550    SS_RELEASE_SEMA(&osCp.tTskTblSem);
5551 #endif
5552
5553
5554    /* restart the timer */
5555    arg.tq = osCp.dep.tmrTq;
5556    arg.tqCp = &osCp.dep.tmrTqCp;
5557    arg.timers = tEnt->dep.timers;
5558    arg.cb = (PTR) tEnt;
5559    arg.evnt = TMR_DEF;
5560    arg.wait = 0;
5561    arg.tNum = NOTUSED;
5562    arg.max = TMR_DEF_MAX;
5563    arg.wait = tEnt->interval;
5564    cmPlcCbTq(&arg);
5565 #ifdef RGL_SPECIFIC_CHANGES
5566 #ifdef MSPD_MLOG_NEW
5567    MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5568 #endif
5569 #endif
5570    return;
5571 }
5572
5573 \f
5574 #ifdef CONAVL
5575 /*
5576  *
5577  *       Fun:   mtConHdlr
5578  *
5579  *       Desc:  This thread reads the console and hands over any
5580  *              data read to a user function.
5581  *
5582  *       Ret:   (thread function)
5583  *
5584  *       Notes:
5585  *
5586  *       File:  mt_ss.c
5587  *
5588  */
5589    static Void *mtConHdlr
5590 (
5591  Ptr parm                        /* unused */
5592  )
5593 {
5594    int fd;
5595    Data data;
5596
5597
5598    /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5599
5600
5601    UNUSED(parm);
5602
5603
5604    /* check if we have a console input file handle */
5605    if (osCp.dep.conInFp == NULLP)
5606    {
5607       /* die */
5608       return (NULLP);
5609    }
5610
5611    fd = fileno(osCp.dep.conInFp);
5612
5613    /* infinite loop */
5614    for (; ;)
5615    {
5616       if ((read(fd, &data, 1)) != 1)
5617       {
5618          continue;
5619       }
5620
5621
5622       /* call rdConQ, defined by the system service user */
5623       //rdConQ(data);
5624    }
5625
5626
5627    /* not reached */
5628 }
5629 #endif /* CONAVL */
5630
5631 #ifndef L2_L3_SPLIT
5632 #ifdef SS_DRVR_SUPPORT
5633 /*
5634  *
5635  *       Fun:   Interrupt service task handler
5636  *
5637  *       Desc:  This is the interrupt service task handler. It blocks
5638  *              on a pipe from which it reads an isFlag structure. The
5639  *              structure indicates which interrupt service task is to
5640  *              be executed. The thread identifies the task, calls the
5641  *              isTsk function and sends itself a message to repeat
5642  *              this operation until it receives a message to cease.
5643  *
5644  *       Ret:   ROK      - ok
5645  *
5646  *       Notes:
5647  *
5648  *       File:  mt_ss.c
5649  *
5650  */
5651 /* mt009.21: addition */
5652    static Void *mtIsTskHdlr
5653 (
5654  Ptr tskPtr                      /* pointer to task entry */
5655  )
5656 {
5657 #if (ERRCLASS & ERRCLS_DEBUG)
5658    int ret;
5659 #endif
5660    MtIsFlag isFlag;
5661
5662    for (; ;)
5663    {
5664       if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5665       {
5666          continue;
5667       }
5668
5669       switch (isFlag.action)
5670       {
5671          case MT_IS_SET:
5672             osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5673
5674             /* call the interrupt service task activation function */
5675             osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5676
5677             /* send self a message to keep doing this */
5678             isFlag.action = MT_IS_RESET;
5679
5680 #if (ERRCLASS & ERRCLS_DEBUG)
5681             ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5682             if (ret != sizeof(isFlag))
5683             {
5684                MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5685                      "write() to pipe failed");
5686             }
5687 #else
5688             write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5689 #endif
5690
5691             break;
5692
5693
5694          case MT_IS_UNSET:
5695             osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5696             break;
5697
5698
5699          case MT_IS_RESET:
5700             if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5701             {
5702                /* call the interrupt service task activation function */
5703                osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5704
5705 #if (ERRCLASS & ERRCLS_DEBUG)
5706                /* send self a message to do this again */
5707                ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5708
5709                if (ret != sizeof(isFlag))
5710                {
5711                   MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5712                         "write() to pipe failed");
5713                }
5714 #else
5715                write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5716 #endif
5717
5718             }
5719             break;
5720
5721
5722          default:
5723             /* where did THIS come from?? */
5724             break;
5725       }
5726    }
5727    /* mt009.21: addition */
5728    return ( (Void *) NULLP);
5729
5730    /* not reached */
5731 }
5732 #endif /* SS_DRVR_SUPPORT */
5733 #endif /* L2_L3_SPLIT */
5734
5735 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5736 \f
5737 /*
5738  *
5739  *       Fun:   mtIntSigHndlr
5740  *
5741  *       Desc:  Exit function, shuts down.
5742  *
5743  *       Ret:   Void
5744  *
5745  *       Notes:
5746  *
5747  *       File:  mt_ss.c
5748  *
5749  */
5750 Void mtIntSigHndlr(int arg)
5751 {
5752
5753    osCp.dep.sigEvnt=TRUE;
5754
5755 #ifdef MSPD
5756 #ifdef TENB_RTLIN_CHANGES
5757    mtStopHndlr();
5758 #endif
5759 #endif
5760
5761    return;
5762 }
5763
5764 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5765 /*
5766  *
5767  *       Fun:   mtExitClnup
5768  *
5769  *       Desc:   function, shuts down.
5770  *
5771  *       Ret:   Void
5772  *
5773  *       Notes:
5774  *
5775  *       File:  mt_ss.c
5776  *
5777  */
5778 Void mtExitClnup(void)
5779 {
5780    Ticks ticks;
5781    S8 buf[128];
5782
5783
5784    SGetSysTime(&ticks);
5785 #ifdef ALIGN_64BIT
5786    sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5787 #else
5788    sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5789 #endif
5790 #ifdef SS_HISTOGRAM_SUPPORT
5791    SDisplay(0, buf);
5792 #endif
5793
5794    osCp.dep.sigEvnt=FALSE;
5795 #ifndef NOFILESYS
5796    if (osCp.dep.fileOutFp)
5797    {
5798       fclose(osCp.dep.fileOutFp);
5799    }
5800 #endif
5801
5802    exit(0);
5803 }
5804
5805 Ticks TtiCount = 0;
5806 Void SIncrementTtiCount(Void)
5807 {
5808    TtiCount++;
5809 }
5810
5811 Ticks SGetTtiCount(Void)
5812 {
5813    return TtiCount;
5814 }
5815
5816 /*
5817  *
5818  *       Fun:   SDisplay
5819  *
5820  *       Desc:  This function displays a string to a given output
5821  *              channel.
5822  *
5823  *       Ret:   ROK      - ok
5824  *
5825  *       Notes: Buffer should be null terminated.
5826  *
5827  *              channel 0 is reserved for backwards compatibility
5828  *              with SPrint
5829  *
5830  *       File:  mt_ss.c
5831  *
5832  */
5833    S16 SDisplay
5834 (
5835  S16 chan,                   /* channel */
5836  Txt *buf                    /* buffer */
5837  )
5838 {
5839
5840    /* mt020.201 - Fixed typo */
5841 #if (ERRCLASS & ERRCLS_INT_PAR)
5842    if (buf == NULLP)
5843    {
5844       MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
5845       return RFAILED;
5846    }
5847 #endif
5848
5849 #ifndef XEON_SPECIFIC_CHANGES
5850 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5851    ssMemlog(buf, strlen(buf));
5852    return ROK;
5853 #endif
5854 #endif
5855
5856    /* mt012.301 :FIX for LOG RELATED ISSUE  */
5857 #ifdef CONAVL
5858    if(chan==1)
5859    {
5860       printf("%s",buf);
5861    }
5862    else
5863    {
5864       if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
5865    }
5866 #endif
5867
5868
5869 #ifndef NOFILESYS
5870    if (osCp.dep.fileOutFp)
5871       fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
5872    /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
5873 #ifdef FLUSHBUFF
5874
5875    fflush(osCp.dep.fileOutFp);
5876
5877 #endif
5878 #endif
5879
5880    return ROK;
5881 }
5882
5883 /*mt010.301 */
5884 /*
5885  *
5886  *       Fun:   SFini
5887  *
5888  *       Desc:  function, shuts down.
5889  *
5890  *       Ret:   Void
5891  *
5892  *       Notes:
5893  *
5894  *       File:  mt_ss.c
5895  *
5896  */
5897 S16 SFini(void)
5898 {
5899
5900    /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
5901       a loop to overcome the child processes being killed upon exiting the
5902       thread */
5903 #ifdef SS_LINUX  /* this should have already been defined */
5904    /* mt010.301 removed flag SLES9_PLUS */
5905    /* wait forever for children */
5906    for (;;)
5907    {
5908       pause();
5909       if(osCp.dep.sigEvnt==TRUE)
5910       {
5911          mtExitClnup();
5912       }
5913    }
5914
5915 #endif
5916    pthread_exit(NULLP);
5917    return (0);
5918 }
5919 \f
5920 /*
5921  *
5922  *       Fun:   Set date and time
5923  *
5924  *       Desc:  This function is used to set the calendar
5925  *              date and time.
5926  *
5927  *       Ret:   ROK      - ok
5928  *
5929  *       Notes: Unimplemented
5930  *
5931  *       File:  mt_ss.c
5932  *
5933  */
5934    S16 SSetDateTime
5935 (
5936  REG1 DateTime *dt           /* date and time */
5937  )
5938 {
5939
5940    UNUSED(dt);
5941
5942
5943    return ROK;
5944 }
5945
5946 \f
5947 /*
5948  *
5949  *       Fun:   Get date and time
5950  *
5951  *       Desc:  This function is used to determine the calendar
5952  *              date and time. This information may be used for
5953  *              some management functions.
5954  *
5955  *       Ret:   ROK      - ok
5956  *              RFAILED  - error
5957  *
5958  *       Notes:
5959  *
5960  *       File:  mt_ss.c
5961  *
5962  */
5963    S16 SGetDateTime
5964 (
5965  REG1 DateTime *dt           /* date and time */
5966  )
5967 {
5968    /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
5969    /* time_t tt; --*/
5970 #ifndef SS_LINUX
5971    struct timespec ptime;
5972 #else
5973    struct timeval ptime;
5974 #endif
5975
5976    struct tm tme;
5977
5978
5979
5980 #if (ERRCLASS & ERRCLS_INT_PAR)
5981    if (dt == NULLP)
5982    {
5983       MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
5984       return RFAILED;
5985    }
5986 #endif
5987
5988
5989    /*-- mt035.201 --*/
5990    /*--
5991      time(&tt);
5992      localtime_r(&tt, &tme);
5993      --*/
5994 #ifndef SS_LINUX
5995    clock_gettime(CLOCK_REALTIME, &ptime);
5996 #else
5997    gettimeofday(&ptime, NULL);
5998 #endif
5999    localtime_r(&ptime.tv_sec, &tme);
6000
6001    dt->month = (uint8_t) tme.tm_mon + 1;
6002    dt->day = (uint8_t) tme.tm_mday;
6003    dt->year = (uint8_t) tme.tm_year;
6004    dt->hour = (uint8_t) tme.tm_hour;
6005    dt->min = (uint8_t) tme.tm_min;
6006    dt->sec = (uint8_t) tme.tm_sec;
6007    dt->tenths = 0;
6008
6009 #ifdef SS_DATETIME_USEC
6010 #ifndef SS_LINUX
6011    dt->usec = ptime.tv_nsec / 1000;
6012 #else
6013    dt->usec = ptime.tv_usec;
6014 #endif
6015 #endif /*-- SS_DATETIME_USEC --*/
6016
6017    return ROK;
6018 }
6019
6020 /*
6021  * Get time from epoch in milliseconds
6022  *
6023  *       Fun:   Get time from epoch in milliseconds
6024  *
6025  *       Desc:  This function is used to get the time from epoch in milli seconds.
6026  *              This information may be used for calculating a layer's activation function
6027  *              execution time used for thread profiling.
6028  *
6029  *       Ret:   ROK      - ok
6030  *              RFAILED  - error
6031  *
6032  *       Notes:
6033  *
6034  *       File:  mt_ss.c
6035  */
6036 /* mt003.301 Modifications */
6037    S16 SGetEpcTime
6038 (
6039  EpcTime *et           /* date and time */
6040  )
6041 {
6042    /* mt003.301 Modifications */
6043    static uint64_t now;
6044    uint64_t  to_sec  = 1000000;
6045    uint64_t  to_nsec = 1000;
6046 #ifndef SS_LINUX
6047    struct timespec ptime;
6048 #else
6049    struct timeval ptime;
6050 #endif
6051
6052
6053
6054 #if (ERRCLASS & ERRCLS_INT_PAR)
6055    if (et == NULLP)
6056    {
6057       return RFAILED;
6058    }
6059 #endif
6060
6061
6062 #ifndef SS_LINUX
6063    clock_gettime(CLOCK_REALTIME, &ptime);
6064 #else
6065    gettimeofday(&ptime, NULL);
6066 #endif /* SS_LINUX */
6067
6068    now = (ptime.tv_sec * to_sec);
6069
6070 #ifndef SS_LINUX
6071    now += (ptime.tv_nsec / to_nsec);
6072 #else /* SS_LINUX */
6073    now += (ptime.tv_usec);
6074
6075 #endif /* SS_LINUX */
6076    now = (now / to_nsec);
6077
6078    *et = now;
6079
6080    return ROK;
6081 }
6082
6083
6084 \f
6085 /*
6086  *
6087  *       Fun:   Get system time
6088  *
6089  *       Desc:  This function is used to determine the system time.
6090  *
6091  *       Ret:   ROK      - ok
6092  *
6093  *       Notes: osCp.dep.sysTicks is updated by the timer thread.
6094  *
6095  *       File:  mt_ss.c
6096  *
6097  */
6098    S16 SGetSysTime
6099 (
6100  Ticks *sysTime              /* system time */
6101  )
6102 {
6103
6104
6105 #if (ERRCLASS & ERRCLS_INT_PAR)
6106    if (sysTime == NULLP)
6107    {
6108       MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6109       return RFAILED;
6110    }
6111 #endif
6112
6113
6114    *sysTime = osCp.dep.sysTicks;
6115
6116
6117    return ROK;
6118 }
6119
6120 /* mt021.201 - Addition of SGetRefTime function */
6121 /*
6122  *
6123  *       Fun:   Get referenced time
6124  *
6125  *       Desc:  This function is used to determine the time in seconds
6126  *              and microseconds from a reference time.  The reference
6127  *              time is expressed in seconds from UTC EPOC, January 1,
6128  *              1970.
6129  *
6130  *       Ret:   ROK      - ok
6131  *              RFAILED  - fail
6132  *
6133  *       Notes: Macros are defined for reference times:
6134  *                 SS_REFTIME_01_01_1970
6135  *                 SS_REFTIME_01_01_2002
6136  *
6137  *       File:  mt_ss.c
6138  *
6139  */
6140    S16 SGetRefTime
6141 (
6142  uint32_t refTime,             /* reference time */
6143  uint32_t *sec,
6144  uint32_t *usec
6145  )
6146 {
6147
6148 #ifndef SS_LINUX
6149    struct timespec ptime;
6150 #else
6151    struct timeval ptime;
6152 #endif
6153
6154
6155 #ifndef SS_LINUX
6156    clock_gettime(CLOCK_REALTIME, &ptime);
6157 #else
6158    gettimeofday(&ptime, NULL);
6159 #endif
6160
6161 #if (ERRCLASS & ERRCLS_INT_PAR)
6162    if (sec == NULLP || usec == NULLP)
6163    {
6164       MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6165       return RFAILED;
6166    }
6167    /* mt022.201 - Modification to fix compile warning */
6168    if (refTime > (uint32_t)(ptime.tv_sec))
6169    {
6170       MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6171       return RFAILED;
6172    }
6173 #endif
6174
6175    *sec = ptime.tv_sec - refTime;
6176 #ifndef SS_LINUX
6177    *usec = ptime.tv_nsec / 1000;
6178 #else
6179    *usec = ptime.tv_usec;
6180 #endif
6181
6182    return ROK;
6183
6184 }
6185
6186 \f
6187 /*
6188  *
6189  *       Fun:   Get Random Number
6190  *
6191  *       Desc:  Invoked by layer when a pseudorandom number is required.
6192  *
6193  *       Ret:   ROK      - ok
6194  *
6195  *       Notes: Suggested approach uses shuffled Linear Congruential
6196  *              Operators as described in Byte magazine October
6197  *              1984; "Generating and Testing Pseudorandom Numbers"
6198  *
6199  *       File:  mt_ss.c
6200  *
6201  */
6202    S16 SRandom
6203 (
6204  Random *value               /* random number */
6205  )
6206 {
6207
6208
6209 #if (ERRCLASS & ERRCLS_INT_PAR)
6210    if (value == NULLP)
6211    {
6212       /* mt011.21: addition */
6213       MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6214       return RFAILED;
6215    }
6216 #endif
6217
6218
6219    *value = (Random) rand_r(&osCp.dep.randSeed);
6220
6221
6222    return ROK;
6223 }
6224
6225 \f
6226 /*
6227  *
6228  *       Fun:   Exit Task
6229  *
6230  *       Desc:  This function exits from a task.
6231  *
6232  *       Ret:   ROK      - ok
6233  *
6234  *       Notes: Currently does nothing.
6235  *
6236  *       File:  mt_ss.c
6237  *
6238  */
6239 S16 SExitTsk(void)
6240 {
6241
6242
6243    return ROK;
6244 }
6245
6246 \f
6247 /*
6248  *
6249  *       Fun:   Exit Interrupt
6250  *
6251  *       Desc:  This function exits from an interrupt.
6252  *
6253  *       Ret:   ROK      - ok
6254  *
6255  *       Notes: Currently does nothing.
6256  *
6257  *       File:  mt_ss.c
6258  *
6259  */
6260 S16 SExitInt(void)
6261 {
6262
6263
6264    return ROK;
6265 }
6266
6267 \f
6268 /*
6269  *
6270  *       Fun:   Hold Interrupt
6271  *
6272  *       Desc:  This function prohibits interrupts from being enabled until
6273  *              release interrupt. This function should be called when
6274  *              interrupts are disabled and prior to any call to system
6275  *              services either by entry to an interrupt service routine or
6276  *              by explicit call to disable interrupt.
6277  *
6278  *       Ret:   ROK      - ok
6279  *
6280  *       Notes: Currently does nothing
6281  *
6282  *       File:  mt_ss.c
6283  *
6284  */
6285 S16 SHoldInt(void)
6286 {
6287
6288
6289    return ROK;
6290 }
6291
6292 \f
6293 /*
6294  *
6295  *       Fun:   Release Interrupt
6296  *
6297  *       Desc:  This function allows interrupts to be enabled.
6298  *
6299  *       Ret:   ROK      - ok
6300  *
6301  *       Notes: Currently does nothing.
6302  *
6303  *       File:  mt_ss.c
6304  *
6305  */
6306 S16 SRelInt(void)
6307 {
6308
6309
6310    return ROK;
6311 }
6312
6313 \f
6314 /*
6315  *
6316  *       Fun:   SEnbInt
6317  *
6318  *       Desc:  Enable interrupts
6319  *
6320  *       Ret:   ROK on success
6321  *              RFAILED on error
6322  *
6323  *       Notes: Currently does nothing.
6324  *
6325  *       File:  mt_ss.c
6326  *
6327  */
6328 inline S16 SEnbInt(void)
6329 {
6330
6331
6332    return ROK;
6333 }
6334
6335 \f
6336 /*
6337  *
6338  *       Fun:   SDisInt
6339  *
6340  *       Desc:  Disable interrupts
6341  *
6342  *       Ret:   ROK on success
6343  *              RFAILED on error
6344  *
6345  *       Notes: Currently does nothing.
6346  *
6347  *       File:  mt_ss.c
6348  *
6349  */
6350 inline S16 SDisInt(void)
6351 {
6352
6353
6354    return ROK;
6355 }
6356
6357 \f
6358 /*
6359  *
6360  *       Fun:   Get Vector
6361  *
6362  *       Desc:  This function gets the function address stored at the
6363  *              specified interrupt vector.
6364  *
6365  *       Ret:   ROK      - ok
6366  *
6367  *       Notes: Currently does nothing.
6368  *
6369  *       File:  mt_ss.c
6370  *
6371  */
6372    S16 SGetVect
6373 (
6374  VectNmb vectNmb,                /* vector number */
6375  PIF *vectFnct                   /* vector function */
6376  )
6377 {
6378
6379
6380    UNUSED(vectNmb);
6381    UNUSED(vectFnct);
6382
6383
6384    return ROK;
6385 }
6386
6387 \f
6388 /*
6389  *
6390  *       Fun:   Put Vector
6391  *
6392  *       Desc:  This function installs the specified function at the
6393  *              specified interrupt vector.
6394  *
6395  *       Ret:   ROK      - ok
6396  *
6397  *       Notes: Currently does nothing.
6398  *
6399  *       File:  mt_ss.c
6400  *
6401  */
6402    S16 SPutVect
6403 (
6404  VectNmb vectNmb,                /* vector number */
6405  PIF vectFnct                    /* vector function */
6406  )
6407 {
6408
6409
6410    UNUSED(vectNmb);
6411    UNUSED(vectFnct);
6412
6413
6414    return ROK;
6415 }
6416
6417 /* mt028.201: modification: multiple procs support related changes */
6418 #ifndef SS_MULTIPLE_PROCS
6419 \f
6420 /*
6421  *
6422  *       Fun:   SGetEntInst
6423  *
6424  *       Desc:  This function gets the current entity and instance.
6425  *
6426  *       Ret:   ROK      - ok
6427  *              RFAILED  - failed, general (optional)
6428  *
6429  *       Notes: This function may be called by the OS or Layer 1
6430  *              hardware drivers.
6431  *
6432  *       File:  mt_ss.c
6433  *
6434  */
6435    S16 SGetEntInst
6436 (
6437  Ent *ent,                       /* entity */
6438  Inst *inst                      /* instance */
6439  )
6440 {
6441    S16 i;
6442    S16 ret;
6443    pthread_t tId;
6444    SsSTskEntry *sTsk;
6445
6446
6447
6448
6449 #if (ERRCLASS & ERRCLS_INT_PAR)
6450    /* check pointers */
6451    if (ent == NULLP  ||  inst == NULLP)
6452    {
6453       MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6454       return RFAILED;
6455    }
6456 #endif
6457
6458
6459    /* get the thread id */
6460    tId = pthread_self();
6461
6462
6463    /* find the system task in whose context we're running */
6464    sTsk = NULLP;
6465    ret = SLock(&osCp.sTskTblLock);
6466    if (ret != ROK)
6467    {
6468       return RFAILED;
6469    }
6470    for (i = 0;  i < SS_MAX_STSKS;  i++)
6471    {
6472       if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6473       {
6474          sTsk = &osCp.sTskTbl[i];
6475          break;
6476       }
6477    }
6478    if (sTsk != NULLP)
6479    {
6480       *ent = sTsk->dep.ent;
6481       *inst = sTsk->dep.inst;
6482    }
6483    SUnlock(&osCp.sTskTblLock);
6484
6485
6486    return (ret == ROK ? ROK : RFAILED);
6487 }
6488
6489 \f
6490 /*
6491  *
6492  *       Fun:   SSetEntInst
6493  *
6494  *       Desc:  This function sets the current entity and instance.
6495  *
6496  *       Ret:   ROK      - ok
6497  *
6498  *       Notes:
6499  *
6500  *       File:  mt_ss.c
6501  *
6502  */
6503    S16 SSetEntInst
6504 (
6505  Ent ent,                    /* entity */
6506  Inst inst                   /* instance */
6507  )
6508 {
6509    S16 i;
6510    S16 ret;
6511    pthread_t tId;
6512    SsSTskEntry *sTsk;
6513
6514
6515
6516
6517 #if (ERRCLASS & ERRCLS_INT_PAR)
6518    /* check entity and instance IDs */
6519    if (ent >= ENTNC  ||  inst >= INSTNC)
6520    {
6521       MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6522       return RFAILED;
6523    }
6524 #endif
6525
6526
6527    /* get the thread id */
6528    tId = pthread_self();
6529
6530
6531    /* find the system task in whose context we're running */
6532    sTsk = NULLP;
6533    ret = SLock(&osCp.sTskTblLock);
6534    if (ret != ROK)
6535    {
6536       return RFAILED;
6537    }
6538    for (i = 0;  i < SS_MAX_STSKS;  i++)
6539    {
6540       if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6541       {
6542          sTsk = &osCp.sTskTbl[i];
6543          break;
6544       }
6545    }
6546    if (sTsk != NULLP)
6547    {
6548       sTsk->dep.ent = ent;
6549       sTsk->dep.inst = inst;
6550    }
6551    SUnlock(&osCp.sTskTblLock);
6552
6553
6554    return (ret == ROK ? ROK : RFAILED);
6555 }
6556
6557 #endif /* SS_MULTIPLE_PROCS */
6558
6559 #ifdef SS_DRVR_SUPPORT
6560 \f
6561 /*
6562  *
6563  *       Fun:   SSetIntPend
6564  *
6565  *       Desc:  Set interrupt pending flag
6566  *
6567  *       Ret:   ROK on success
6568  *              RFAILED on error
6569  *
6570  *       Notes:
6571  *
6572  *       File:  mt_ss.c
6573  *
6574  */
6575    inline S16 SSetIntPend
6576 (
6577  uint16_t id,                         /* driver task identifier */
6578  Bool flag                       /* flag */
6579  )
6580 {
6581    MtIsFlag isFlag;
6582
6583
6584
6585
6586 #if (ERRCLASS & ERRCLS_INT_PAR)
6587    if (id >= SS_MAX_DRVRTSKS  ||  osCp.drvrTskTbl[id].used == FALSE)
6588    {
6589       MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6590       return RFAILED;
6591    }
6592 #endif
6593
6594
6595    isFlag.id = id;
6596    isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6597
6598    if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6599    {
6600       return RFAILED;
6601    }
6602
6603
6604    return ROK;
6605 }
6606 #endif  /* SS_DRVR_SUPPORT */
6607
6608
6609 #ifdef SS_LOCKLESS_MEMORY
6610 /*
6611  *
6612  *       Fun:   SGlobMemInfoShow
6613  *
6614  *       Desc:  This function displays the memory usage information
6615  *              for the destined region. It will show the usage of
6616  *              each configured bucket and the heap for the specified region.
6617  *
6618  *       Ret:   ROK             OK
6619  *              RFAILED         Region not registered
6620  *
6621  *       File:  mt_ss.c
6622  *
6623  */
6624 S16 SGlobMemInfoShow(Void)
6625 {
6626    uint16_t   idx;
6627    Txt   prntBuf[100];
6628    CmMmGlobRegCb   *globReg;
6629
6630
6631    globReg = osCp.globRegCb;
6632
6633    sprintf(prntBuf, "--------------------------------------------------------------\n");
6634    SDisplay(0, prntBuf);
6635    sprintf(prntBuf, "Global Region Bucket Information\n");
6636    SDisplay(0, prntBuf);
6637    sprintf(prntBuf, "====================================================\n");
6638    SDisplay(0, prntBuf);
6639    sprintf(prntBuf, "Bucket Id  Set Size  Free Sets  Allocated\n");
6640    SDisplay(0, prntBuf);
6641    sprintf(prntBuf, "====================================================\n");
6642    SDisplay(0, prntBuf);
6643
6644
6645    for (idx = 0; idx < globReg->numBkts; idx++)
6646    {
6647 #ifdef XEON_SPECIFIC_CHANGES
6648       sprintf(prntBuf, "%2u  %12lu  %12lu  %8lu %9lu\n",
6649             idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6650 #else      
6651 #ifndef ALIGN_64BIT
6652       sprintf(prntBuf, "%2u  %12lu  %8lu %9lu\n", 
6653             idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6654 #else
6655       sprintf(prntBuf, "%2u  %12u  %8u %9u\n", 
6656             idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6657 #endif
6658 #endif      
6659       SDisplay(0, prntBuf);
6660    }
6661    sprintf(prntBuf, "--------------------------------------------------------------\n");
6662    SDisplay(0, prntBuf);
6663
6664    return ROK;
6665 }   
6666
6667 #endif /* SS_LOCKLESS_MEMORY */
6668
6669 /*
6670    Bool IsMemoryThresholdHit(Region reg, Pool pool)
6671    {
6672    if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6673    {
6674    MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6675    reg,
6676    pool,
6677    mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6678    mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6679    return (TRUE);
6680    }
6681    return (FALSE);
6682    }
6683  */
6684
6685 /* mt022.201 - Addition of SRegInfoShow function */
6686 /*
6687  *
6688  *       Fun:   SRegInfoShow
6689  *
6690  *       Desc:  This function displays the memory usage information
6691  *              for the destined region. It will show the usage of
6692  *              each configured bucket and the heap for the specified region.
6693  *
6694  *       Ret:   ROK             OK
6695  *              RFAILED         Region not registered
6696  *
6697  *       Notes: A Sample Output from the function
6698  *       Bucket Memory: region 1
6699  *       ====================================================
6700  *       Bucket  Number of Blks configured  Size  Allocated
6701  *       ====================================================
6702  *       0                     1             16         1
6703  *       1                     1             32         0
6704  *       2                     1             80         0
6705  *       3                     1            256         0
6706  *       4                     1            320         0
6707  *
6708  *       ---------------
6709  *       Heap Memory: region 1
6710  *       Heap Size: 0
6711  *       Heap Allocated: 0
6712  *       Heap Segmented blocks: 0
6713  *
6714  *
6715  *       File:  mt_ss.c
6716  *
6717  */
6718    S16 SRegInfoShow
6719 (
6720  Region region,
6721  uint32_t *availmem
6722  )
6723 {
6724    uint16_t   idx;
6725    Txt   prntBuf[100];
6726
6727
6728 #if (ERRCLASS & ERRCLS_INT_PAR)
6729    if (region > (SS_MAX_REGS-1) )
6730    {
6731       MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
6732       return RFAILED;
6733    }
6734 #endif
6735
6736    *availmem = 0;
6737
6738 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
6739    sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
6740    SDisplay(0, prntBuf);
6741    sprintf(prntBuf, "====================================================\n");
6742    SDisplay(0, prntBuf);
6743    sprintf(prntBuf, "Bucket  Number of Blks configured  Size  Allocated\n");
6744    SDisplay(0, prntBuf);
6745    sprintf(prntBuf, "====================================================\n");
6746    SDisplay(0, prntBuf);
6747 #endif
6748
6749
6750    for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6751    {
6752 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6753 #ifdef ALIGN_64BIT
6754       sprintf((char *)prntBuf, "%2u              %8u          %5u  %8u  %8u\n",
6755             idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6756             mtCMMRegCb[region]->bktTbl[idx].size,
6757             mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6758             mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6759 #else
6760       sprintf((char *)prntBuf, "%2u              %8lu          %5lu  %8lu  %8lu\n",
6761             idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6762             mtCMMRegCb[region]->bktTbl[idx].size,
6763             mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6764             mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6765 #endif
6766 #else
6767       /*mt009.301 Fixed 64BIT compilation warnings*/
6768 #ifdef ALIGN_64BIT
6769       sprintf(prntBuf, "%2u              %8u          %5u  %8u\n",
6770             idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6771             mtCMMRegCb[region]->bktTbl[idx].size,
6772             mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6773 #else
6774       sprintf(prntBuf, "%2u              %8lu          %5lu  %8lu\n",
6775             idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6776             mtCMMRegCb[region]->bktTbl[idx].size,
6777             mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6778 #endif
6779 #endif /* not TENB_RTLIN_CHANGES */
6780       SDisplay(0, prntBuf);
6781       *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
6782             (mtCMMRegCb[region]->bktTbl[idx].numBlks -  \
6783              mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6784    }
6785    sprintf(prntBuf, "\n---------------\n");
6786    SDisplay(0, prntBuf);
6787    sprintf(prntBuf, "Heap Memory: region %d\n", region);
6788    SDisplay(0, prntBuf);
6789    /*mt009.301 Fixed 64BIT compilation warnings*/
6790 #ifdef ALIGN_64BIT
6791    sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
6792 #else
6793    sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
6794 #endif
6795    SDisplay(0, prntBuf);
6796    /*mt009.301 Fixed 64BIT compilation warnings*/
6797 #ifdef ALIGN_64BIT
6798    sprintf(prntBuf, "Heap Allocated: %u\n",
6799          (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6800 #else
6801    sprintf(prntBuf, "Heap Allocated: %lu\n",
6802          (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6803 #endif
6804    SDisplay(0, prntBuf);
6805    *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
6806 #if (ERRCLASS & ERRCLS_DEBUG)
6807    sprintf(prntBuf, "Heap Segmented blocks: %d\n",
6808          mtCMMRegCb[region]->heapCb.numFragBlk);
6809    SDisplay(0, prntBuf);
6810 #endif
6811
6812    return ROK;
6813 }
6814 #ifdef XEON_SPECIFIC_CHANGES
6815 #define  SSI_MAX_BKT_THRESHOLD 6
6816 #define  SSI_MAX_REG_THRESHOLD 2
6817 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6818 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6819 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6820
6821    static Void SInitMemThreshold
6822 (
6823  Region region,
6824  uint8_t     maxBkt
6825  )
6826 {
6827    uint8_t   idx = 0;
6828    for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6829    {
6830       SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
6831       SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
6832       SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
6833       printf("\nREGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
6834    }
6835 }
6836
6837    S16 SRegReachedMemThreshold
6838 (
6839  Region region,
6840  uint8_t     maxBkt
6841  )
6842 {
6843    uint8_t           idx       = 0;
6844    uint8_t           memStatus = 3;
6845    static uint8_t   initFlag  = 1;
6846    if(initFlag)
6847    {
6848       initFlag = 0;
6849       SInitMemThreshold(region, maxBkt);
6850    }
6851
6852    for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6853    {
6854       if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
6855       {
6856          memStatus = 0;
6857          break;
6858       }
6859       else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
6860       {
6861          memStatus = 1;
6862       }
6863       else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
6864       {
6865          memStatus = 2;
6866       }
6867    }
6868    return (memStatus);
6869 }
6870 #endif
6871 /* mt033.201 - addition of API to return the memory statistical data */
6872 /*
6873  *
6874  *       Fun:   SGetRegInfo
6875  *
6876  *       Desc:  This function returns the memory usage information
6877  *              for the destined region. It will return the usage of
6878  *              each configured bucket and the heap for the specified region.
6879  *
6880  *       Ret:   ROK   OK
6881  *              RFAILED   Region not registered
6882  *
6883  *       Notes:
6884  *
6885  *       File:  mt_ss.c
6886  *
6887  */
6888    S16 SGetRegInfo
6889 (
6890  Region region,
6891  SsMemDbgInfo *dbgInfo
6892  )
6893 {
6894    uint32_t idx;
6895
6896
6897 #if (ERRCLASS & ERRCLS_INT_PAR)
6898    if (region >= mtMemoCfg.numRegions )
6899    {
6900       MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
6901       return RFAILED;
6902    }
6903 #endif
6904
6905    dbgInfo->availmem = 0;
6906
6907    if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
6908       dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
6909    else
6910       dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
6911
6912    for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
6913    {
6914       dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
6915       dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
6916       dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
6917
6918       dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
6919             (mtCMMRegCb[region]->bktTbl[idx].numBlks -  \
6920              mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6921    }
6922
6923    dbgInfo->region = region;
6924
6925    dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
6926
6927    dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
6928          mtCMMRegCb[region]->heapCb.avlSize);
6929
6930    dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
6931
6932 #if (ERRCLASS & ERRCLS_DEBUG)
6933    dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
6934 #endif
6935
6936    return ROK;
6937 }
6938
6939    S16 SGetRegPoolInfo
6940 (
6941  uint8_t *numRegion,
6942  uint8_t *numPool
6943  )
6944 {
6945    /* Send number of Region available */
6946    *numRegion = mtMemoCfg.numRegions;
6947    /* Send number of Pools available */
6948    *numPool = cfgRegInfo[0].numPools;
6949
6950    return ROK;
6951 }
6952
6953 /* mt033.201 - addition of APIs to print the memory statistical data
6954  * as defined by SSI enhancements
6955  */
6956 #ifdef SSI_DEBUG_LEVEL1
6957 /*
6958  *
6959  *       Fun:   SPrintRegMemStatusInfo
6960  *
6961  *       Desc:  This function displays the memory usage information
6962  *              for the destined region. It will show the total memory
6963  *              used for static and dynamic memory if typeFlag is
6964  *              SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
6965  *              memory block allocated for a particular size if typeFlag
6966  *              is SS_MEM_BLK_SIZE_PROFILE from the hash list by
6967  *              calling SRegPrintMemStats.
6968  *
6969  *       Ret:   ROK
6970  *
6971  *       Notes:
6972  *
6973  *       File:  mt_ss.c
6974  *
6975  */
6976    S16 SPrintRegMemStatusInfo
6977 (
6978  Region region,
6979  uint8_t typeFlag
6980  )
6981 {
6982    Txt prntBuf[150];
6983    uint32_t idx;
6984    uint32_t statMemSize;
6985    uint32_t dynMemSize;
6986
6987
6988 #if (ERRCLASS & ERRCLS_INT_PAR)
6989    if (region >= mtMemoCfg.numRegions )
6990    {
6991       MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
6992       return RFAILED;
6993    }
6994 #endif
6995
6996    /* initialize the counters*/
6997    statMemSize = 0;
6998    dynMemSize = 0;
6999
7000    if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7001    {
7002       /* total static and dynamic memory allocated from all the buckets in region requested */
7003       sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7004       SDisplay(0, prntBuf);
7005       sprintf(prntBuf, "===========================================\n");
7006       SDisplay(0, prntBuf);
7007       sprintf(prntBuf, "Bucket        Static Memory      Dynamic Memory\n");
7008       SDisplay(0, prntBuf);
7009       sprintf(prntBuf, "===========================================\n");
7010       SDisplay(0, prntBuf);
7011       for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7012       {
7013          /*mt009.301 Fixed 64BIT compilation warnings*/
7014 #ifdef ALIGN_64BIT
7015          sprintf(prntBuf, "%2u           %8u           %8u\n", idx,
7016                mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7017                mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7018 #else
7019          sprintf(prntBuf, "%2lu           %8lu           %8lu\n", idx,
7020                mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7021                mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7022 #endif
7023          SDisplay(0, prntBuf);
7024          /* update the total count */
7025          statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7026          dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7027       }
7028       /* from buckets */
7029       /*mt009.301 Fixed 64BIT compilation warnings*/
7030 #ifdef ALIGN_64BIT
7031       sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7032       SDisplay(0, prntBuf);
7033       sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7034 #else
7035       sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7036       SDisplay(0, prntBuf);
7037       /*mt010.301 fix for compilation error*/
7038       sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7039 #endif
7040       SDisplay(0, prntBuf);
7041       /* from heap */
7042       sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7043       SDisplay(0, prntBuf);
7044       /*mt009.301 Fixed 64BIT compilation warnings*/
7045 #ifdef ALIGN_64BIT
7046       sprintf(prntBuf, "STATIC MEMORY: %u       DYNAMIC MEMORY:%u \n",
7047             mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7048 #else
7049       sprintf(prntBuf, "STATIC MEMORY: %lu      DYNAMIC MEMORY:%lu \n",
7050             mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7051 #endif
7052       SDisplay(0, prntBuf);
7053    }
7054    else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7055    {
7056       /* Bucket Memory allocation Statistics */
7057       return (SPrintRegMemStats(region));
7058    }
7059    else
7060    {
7061       /* error case */
7062       sprintf(prntBuf, "\n Invalid choice \n");
7063       SDisplay(0, prntBuf);
7064    }
7065
7066    return ROK;
7067 }
7068
7069 /*
7070  *
7071  *       Fun:   SPrintRegMemStats
7072  *
7073  *       Desc:  This function displays the memory usage information for
7074  *              the destined region. It will show the number of memory
7075  *              block allocated for a particular size from the hash list.
7076  *
7077  *       Ret:   ROK
7078  *
7079  *       Notes:
7080  *
7081  *       File:  mt_ss.c
7082  *
7083  */
7084 static S16 SPrintRegMemStats(Region region)
7085 {
7086    CmMmHashListCp *hashListCp;
7087    Txt prntBuf[150];
7088    uint32_t idx;
7089    uint32_t cntEnt;
7090
7091
7092    hashListCp = &mtCMMRegCb[region]->hashListCp;
7093
7094    sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7095    SDisplay(0, prntBuf);
7096    sprintf(prntBuf, "Maximum Entries: %u    Current Entries: %u\n",
7097          hashListCp->numOfbins, hashListCp->numOfEntries);
7098    SDisplay(0, prntBuf);
7099    sprintf(prntBuf, "===================================\n");
7100    SDisplay(0, prntBuf);
7101    sprintf(prntBuf, "Block Size      Total number of requests\n");
7102    SDisplay(0, prntBuf);
7103    sprintf(prntBuf, "===================================\n");
7104    SDisplay(0, prntBuf);
7105
7106    for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7107          (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7108    {
7109       if (hashListCp->hashList[idx].numAttempts)
7110       {
7111          cntEnt++;
7112          /*mt009.301 Fixed 64BIT compilation warnings*/
7113 #ifdef ALIGN_64BIT
7114          sprintf(prntBuf, "%8u           %8u\n", hashListCp->hashList[idx].size,
7115                hashListCp->hashList[idx].numAttempts);
7116 #else
7117          sprintf(prntBuf, "%8lu           %8lu\n", hashListCp->hashList[idx].size,
7118                hashListCp->hashList[idx].numAttempts);
7119 #endif
7120          SDisplay(0, prntBuf);
7121       }
7122    }
7123
7124    sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7125    SDisplay(0, prntBuf);
7126    sprintf(prntBuf, "=================================================\n");
7127    SDisplay(0, prntBuf);
7128    sprintf(prntBuf, "Bucket    Num of Alloc Attempts    Num of De-alloc Attempts\n");
7129    SDisplay(0, prntBuf);
7130    sprintf(prntBuf, "=================================================\n");
7131    SDisplay(0, prntBuf);
7132
7133    /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7134    for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7135    {
7136       /*mt009.301 Fixed 64BIT compilation warnings*/
7137 #ifdef ALIGN_64BIT
7138       sprintf(prntBuf, "%4u        %8u             %8u\n", idx,
7139             mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7140             mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7141 #else
7142       sprintf(prntBuf, "%4lu        %8lu             %8lu\n", idx,
7143             mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7144             mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7145 #endif
7146       SDisplay(0, prntBuf);
7147    }
7148    sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7149    SDisplay(0, prntBuf);
7150    /*mt009.301 Fixed 64BIT compilation warnings*/
7151 #ifdef ALIGN_64BIT
7152    sprintf(prntBuf, "Num of Alloc Attempts: %u      Num of De-alloc Attempts: %u\n",
7153          mtCMMRegCb[region]->heapCb.numAllocAttempts,
7154          mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7155 #else
7156    sprintf(prntBuf, "Num of Alloc Attempts: %lu      Num of De-alloc Attempts: %lu\n",
7157          mtCMMRegCb[region]->heapCb.numAllocAttempts,
7158          mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7159 #endif
7160    SDisplay(0, prntBuf);
7161    sprintf(prntBuf, "\n");
7162    SDisplay(0, prntBuf);
7163
7164    return ROK;
7165 }
7166
7167 /*
7168  *
7169  *       Fun:   SRegMemErrHdlr
7170  *
7171  *       Desc:  This function handles the errors returned from the memory
7172  *              related functions. Customers are suggested to modify this
7173  *              API according to their specific requirement.
7174  *
7175  *       Ret:   ROK   OK
7176  *
7177  *       Notes:
7178  *
7179  *       File:  mt_ss.c
7180  *
7181  */
7182    Void SRegMemErrHdlr
7183 (
7184  Region region,
7185  Data *ptr,
7186  S16 errCode
7187  )
7188 {
7189    Txt prntBuf[150];
7190
7191
7192    if (errCode == RDBLFREE)
7193    {
7194       sprintf(prntBuf, "\nDouble free attempted at location:%8p  in region:%d\n", ptr, region);
7195       SDisplay(0, prntBuf);
7196    }
7197    else if (errCode == RTRAMPLINGNOK)
7198    {
7199       sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7200       SDisplay(0, prntBuf);
7201    }
7202
7203    return;
7204 }
7205
7206 /*
7207  *
7208  *       Fun:   SPrintRegMemProfile
7209  *
7210  *       Desc:  This function displays the memory profile information
7211  *              for the destined region. This function prints for:
7212  *              1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7213  *              2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7214  *
7215  *       Ret:   ROK   OK
7216  *
7217  *       Notes:
7218  *
7219  *       File:  mt_ss.c
7220  *
7221  */
7222    S16 SPrintRegMemProfile
7223 (
7224  Region region
7225  )
7226 {
7227    CmMmHeapCb *heapCb;
7228    CmMmRegCb *regCb;
7229    CmMmBlkHdr *curBktBlk;
7230    CmHEntry *curHBlk;
7231    Size offsetToNxtBlk;
7232    Size hdrSize;
7233    Txt prntBuf[250];
7234    uint32_t idx;
7235    uint32_t blkCnt;
7236
7237
7238
7239 #if (ERRCLASS & ERRCLS_INT_PAR)
7240    if (region >= mtMemoCfg.numRegions )
7241    {
7242       MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7243       return RFAILED;
7244    }
7245 #endif
7246
7247    regCb = mtCMMRegCb[region];
7248
7249    /* memory profile */
7250    sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7251    SDisplay(0, prntBuf);
7252
7253    /* bucket profile */
7254    sprintf(prntBuf, "\nBucket Profile\n");
7255    SDisplay(0, prntBuf);
7256
7257    for (idx = 0; idx < regCb->numBkts; idx++)
7258    {
7259
7260       /*mt009.301 Fixed 64BIT compilation warnings*/
7261 #ifdef ALIGN_64BIT
7262       sprintf(prntBuf, "\nBucket number:%4u  of Size:%u  Num of Blocks: %u\n",
7263             idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7264 #else
7265       sprintf(prntBuf, "\nBucket number:%4lu  of Size:%lu  Num of Blocks: %lu\n",
7266             idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7267 #endif
7268       SDisplay(0, prntBuf);
7269
7270       sprintf(prntBuf, "==========================================================================\n");
7271       SDisplay(0, prntBuf);
7272       sprintf(prntBuf, " Block    Location    Free/Allocated  Static/dynamic  Size requested\n");
7273       SDisplay(0, prntBuf);
7274       sprintf(prntBuf, "==========================================================================\n");
7275       SDisplay(0, prntBuf);
7276
7277       offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7278
7279       for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7280             ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7281             curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7282       {
7283          /*mt009.301 Fixed 64BIT compilation warnings*/
7284 #ifdef ALIGN_64BIT
7285          sprintf(prntBuf, "%6u   %8p", blkCnt, (void *)curBktBlk);
7286 #else
7287          sprintf(prntBuf, "%6lu   %8p", blkCnt, (void *)curBktBlk);
7288 #endif
7289          SDisplay(0, prntBuf);
7290          /* check if it is a sane block, elxe jump to next block */
7291          if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7292          {
7293             sprintf(prntBuf, "     Trampled                         \n");
7294             SDisplay(0, prntBuf);
7295
7296             continue;
7297          }
7298
7299          if (CMM_IS_STATIC(curBktBlk->memFlags))
7300          {
7301             /*mt009.301 Fixed 64BIT compilation warnings*/
7302 #ifdef ALIGN_64BIT
7303             sprintf(prntBuf, "     Allocated     Static      %8u\n", curBktBlk->requestedSize);
7304 #else
7305             sprintf(prntBuf, "     Allocated     Static      %8lu\n", curBktBlk->requestedSize);
7306 #endif
7307             SDisplay(0, prntBuf);
7308          }
7309          else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7310          {
7311             /*mt009.301 Fixed 64BIT compilation warnings*/
7312 #ifdef ALIGN_64BIT
7313             sprintf(prntBuf, "     Allocated       Dynamic      %8u\n", curBktBlk->requestedSize);
7314 #else
7315             sprintf(prntBuf, "     Allocated       Dynamic      %8lu\n", curBktBlk->requestedSize);
7316 #endif
7317             SDisplay(0, prntBuf);
7318          }
7319          else if (CMM_IS_FREE(curBktBlk->memFlags))
7320          {
7321             /*mt009.301 Fixed 64BIT compilation warnings*/
7322 #ifdef ALIGN_64BIT
7323             sprintf(prntBuf, "     Free                        %8u\n", curBktBlk->requestedSize);
7324 #else
7325             sprintf(prntBuf, "     Free                        %8lu\n", curBktBlk->requestedSize);
7326 #endif
7327             SDisplay(0, prntBuf);
7328          }
7329          else
7330          {
7331             sprintf(prntBuf, "     Trampled                         \n");
7332             SDisplay(0, prntBuf);
7333          }
7334       }
7335    }
7336
7337    /* heap profile */
7338    sprintf(prntBuf, "\nHeap Profile\n");
7339    SDisplay(0, prntBuf);
7340
7341    /* point to heapCb */
7342    heapCb = &(regCb->heapCb);
7343
7344    sprintf(prntBuf, "\nHeap Start: %8p          Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7345    SDisplay(0, prntBuf);
7346    sprintf(prntBuf, "==========================================================================\n");
7347    SDisplay(0, prntBuf);
7348    sprintf(prntBuf, " Block     Location      Size    Free/Allocated   Static/dynamic  Size requested\n");
7349    SDisplay(0, prntBuf);
7350    sprintf(prntBuf, "==========================================================================\n");
7351    SDisplay(0, prntBuf);
7352
7353    /* traverse the entire heap to output the heap profile */
7354    hdrSize = sizeof(CmHEntry);
7355    for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7356          ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7357    {
7358       /*mt009.301 Fixed 64BIT compilation warnings*/
7359 #ifdef ALIGN_64BIT
7360       sprintf(prntBuf, "%6u   %8p", blkCnt, (void *)curHBlk);
7361 #else
7362       sprintf(prntBuf, "%6lu   %8p", blkCnt, (void *)curHBlk);
7363 #endif
7364       SDisplay(0, prntBuf);
7365
7366       /* check if it is a sane block, elxe jump to next block */
7367       if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7368       {
7369          sprintf(prntBuf, "                Trampled                         \n");
7370          SDisplay(0, prntBuf);
7371
7372          sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7373          SDisplay(0, prntBuf);
7374
7375          /*
7376           * To go to next block in the heap we do not have any offset value
7377           * other than curHBlk->size. As the block is already trampled
7378           * we cannot rely on this size. So it is better to stop here unless there
7379           * exists any other mechanism(?) to know the offset to next block.
7380           */
7381          return ROK;
7382       }
7383
7384       /*mt009.301 Fixed 64BIT compilation warnings*/
7385 #ifdef ALIGN_64BIT
7386       sprintf(prntBuf, "   %8u", curHBlk->size);
7387 #else
7388       sprintf(prntBuf, "   %8lu", curHBlk->size);
7389 #endif
7390       SDisplay(0, prntBuf);
7391
7392       if (CMM_IS_STATIC(curHBlk->memFlags))
7393       {
7394          /*mt009.301 Fixed 64BIT compilation warnings*/
7395 #ifdef ALIGN_64BIT
7396          sprintf(prntBuf, "     Allocated       Static       %8u\n", curHBlk->requestedSize);
7397 #else
7398          sprintf(prntBuf, "     Allocated       Static       %8lu\n", curHBlk->requestedSize);
7399 #endif
7400          SDisplay(0, prntBuf);
7401       }
7402       else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7403       {
7404          /*mt009.301 Fixed 64BIT compilation warnings*/
7405 #ifdef ALIGN_64BIT
7406          sprintf(prntBuf, "     Allocated       Dynamic      %8u\n", curHBlk->requestedSize);
7407 #else
7408          sprintf(prntBuf, "     Allocated       Dynamic      %8lu\n", curHBlk->requestedSize);
7409 #endif
7410          SDisplay(0, prntBuf);
7411       }
7412       else if (CMM_IS_FREE(curHBlk->memFlags))
7413       {
7414          /*mt009.301 Fixed 64BIT compilation warnings*/
7415 #ifdef ALIGN_64BIT
7416          sprintf(prntBuf, "     Free                      %8u\n", curHBlk->requestedSize);
7417 #else
7418          sprintf(prntBuf, "     Free                      %8lu\n", curHBlk->requestedSize);
7419 #endif
7420          SDisplay(0, prntBuf);
7421       }
7422       else
7423       {
7424          sprintf(prntBuf, "     Trampled                         \n");
7425          SDisplay(0, prntBuf);
7426       }
7427       /* goto next block in the heap */
7428       curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7429
7430    }
7431
7432    return ROK;
7433 }
7434 #endif /* SSI_DEBUG_LEVEL1 */
7435
7436 /*-- mt035.201 : Added new API for timestamp --*/
7437 /*--
7438  *
7439  *       Fun:   Get TimeStamp
7440  *
7441  *       Desc:  This function is used to Get TimeStamp in micro seconds
7442  *
7443  *       Ret:   ROK      - ok
7444  *              RFAILED  - error
7445  *
7446  *       Notes:
7447  *
7448  *       File:  mt_ss.c
7449  *
7450  --*/
7451    S16 SGetTimeStamp
7452 (
7453  S8    *ts
7454  )
7455 {
7456
7457 #ifndef SS_LINUX
7458    struct timespec ptime;
7459 #else
7460    struct timeval ptime;
7461 #endif
7462
7463    struct tm* ptm;
7464    S8 time_string[40];
7465    S32 microseconds;
7466
7467
7468 #ifndef SS_LINUX
7469    clock_gettime(CLOCK_REALTIME, &ptime);
7470 #else
7471    gettimeofday(&ptime, NULL);
7472 #endif
7473
7474    /* Obtain the time of day, and convert it to a tm struct. --*/
7475    ptm = localtime (&ptime.tv_sec);
7476    /* Klock work fix ccpu00148484 */
7477    if(ptm != NULLP)
7478    {
7479       /* Format the date and time, down to a single second. --*/
7480       strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7481    }
7482
7483    /* Compute microseconds. --*/
7484 #ifndef SS_LINUX
7485    microseconds = ptime.tv_nsec / 1000;
7486 #else
7487    microseconds = ptime.tv_usec;
7488 #endif
7489
7490    /* Print the formatted time, in seconds, followed by a decimal point
7491       and the microseconds. --*/
7492    /*mt009.301 Fixed 64BIT compilation warnings*/
7493 #ifdef ALIGN_64BIT
7494    sprintf(ts, "%s.%03d", time_string, microseconds);
7495 #else
7496    sprintf(ts, "%s.%03ld", time_string, microseconds);
7497 #endif
7498
7499    return ROK;
7500
7501 }
7502 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7503 /*
7504  *
7505  *       Fun:   Get SGetSystemTsk
7506  *
7507  *       Desc:  This function is used to Get sytem task id
7508  *
7509  *       Ret:   task id
7510  *
7511  *       Notes:
7512  *
7513  *       File:  mt_ss.c
7514  *
7515  --*/
7516 uint32_t SGetSystemTsk(Void)
7517 {
7518
7519    return (pthread_self());
7520
7521 } /* end of SGetSystemTsk */
7522
7523 #ifdef SS_MULTICORE_SUPPORT
7524 /*
7525  *
7526  *       Fun:   Add Timer thread into system task table
7527  *
7528  *       Desc:  This function is used to add the system task
7529  *              associated with Timer thread.
7530  *
7531  *       Ret:   None
7532  *
7533  *       Notes:
7534  *
7535  *       File:  mt_ss.c
7536  *
7537  --*/
7538 static SsSTskEntry* ssdAddTmrSTsk(Void)
7539 {
7540    SsSTskEntry *sTsk;
7541    S16 ret;
7542
7543    sTsk = NULLP;
7544    /* lock the system task table */
7545    ret = SLock(&osCp.sTskTblLock);
7546    if (ret != ROK)
7547    {
7548
7549 #if (ERRCLASS & ERRCLS_DEBUG)
7550       MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7551             "Could not lock system task table");
7552 #endif
7553
7554       return (sTsk);
7555    }
7556
7557    /* check count of system tasks */
7558    if (osCp.numSTsks == SS_MAX_STSKS)
7559    {
7560
7561       if ( SUnlock(&osCp.sTskTblLock) != ROK)
7562       {
7563 #if (ERRCLASS & ERRCLS_DEBUG)
7564          MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7565                "Could not give the Semaphore");
7566          return (sTsk);
7567 #endif
7568       }
7569
7570 #if (ERRCLASS & ERRCLS_ADD_RES)
7571       MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7572 #endif
7573
7574       return (sTsk);
7575    }
7576
7577
7578    /* initialize the system task entry with the information we have */
7579    sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7580
7581    /* store the system task priority */
7582    sTsk->tskPrior = SS_NORM_TSK_PRI;
7583
7584    /* initialize the demand queue */
7585    if (ssInitDmndQ(&sTsk->dQ) != ROK)
7586    {
7587
7588       if ( SUnlock(&osCp.sTskTblLock) != ROK)
7589       {
7590 #if (ERRCLASS & ERRCLS_DEBUG)
7591          MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7592                "Could not give the Semaphore");
7593          return (NULLP);
7594 #endif
7595       }
7596
7597 #if (ERRCLASS & ERRCLS_DEBUG)
7598       MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7599             "Could not initialize demand queue");
7600 #endif
7601
7602       return (NULLP);
7603    }
7604
7605    /* initialize the system task entry lock */
7606    if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7607    {
7608       ssDestroyDmndQ(&sTsk->dQ);
7609
7610       if ( SUnlock(&osCp.sTskTblLock) != ROK)
7611       {
7612 #if (ERRCLASS & ERRCLS_DEBUG)
7613          MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7614                "Could not give the Semaphore");
7615          return (NULLP);
7616 #endif
7617       }
7618
7619 #if (ERRCLASS & ERRCLS_DEBUG)
7620       MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
7621             "Could not initialize system task entry lock");
7622 #endif
7623
7624       return (NULLP);
7625    }
7626
7627
7628    /* success, update the table */
7629    sTsk->tskId       = osCp.nxtSTskEntry;
7630    sTsk->used        = TRUE;
7631    sTsk->termPend    = FALSE;
7632    osCp.nxtSTskEntry = sTsk->nxt;
7633    osCp.numSTsks++;
7634
7635    /* unlock the system task table */
7636
7637    if ( SUnlock(&osCp.sTskTblLock) != ROK)
7638    {
7639 #if (ERRCLASS & ERRCLS_DEBUG)
7640       MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
7641             "Could not give the Semaphore");
7642       return (NULLP);
7643 #endif
7644    }
7645
7646    return (sTsk);
7647 }
7648 #endif /* SS_MULTICORE_SUPPORT */
7649 /* mt003.301 Readwrite lock and recursive mutex additions */
7650 #ifdef SS_LOCK_SUPPORT
7651 /*
7652  *
7653  *       Fun:   ssdInitLockNew
7654  *
7655  *       Desc:  This function is used to initialise lock/mutex
7656  *
7657  *       Ret:   ROK   OK
7658  *
7659  *       Notes:
7660  *
7661  *       File:  mt_ss.c
7662  *
7663  */
7664 S16 ssdInitLockNew(SLockInfo *lockId,uint8_t lockType)
7665 {
7666
7667 #ifdef SS_REC_LOCK_SUPPORT
7668    pthread_mutexattr_t attr;
7669 #endif /* SS_REC_LOCK_SUPPORT */
7670    Txt prntBuf[PRNTSZE];
7671    S16    retVal = ROK;
7672
7673
7674    switch(lockType)
7675    {
7676 #ifdef SS_RDWR_LOCK_SUPPORT
7677       case SRDWRLOCK :
7678          {
7679             if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
7680             {
7681                sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
7682                SDisplay(0, prntBuf);
7683                return RFAILED;
7684             }
7685             break;
7686          }
7687 #endif /* SS_RDWR_LOCK_SUPPORT */
7688 #ifdef SS_REC_LOCK_SUPPORT
7689       case SMUTEXRECUR:
7690          {
7691             retVal = pthread_mutexattr_init(&attr);
7692
7693             if(retVal != 0)
7694             {
7695                sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
7696                SPrint(prntBuf);
7697                return RFAILED;
7698             }
7699 #ifdef SS_LINUX
7700             retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
7701 #else
7702             retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
7703 #endif
7704             if(retVal != 0)
7705             {
7706                sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
7707                pthread_mutexattr_destroy(&attr);
7708                SPrint(prntBuf);
7709                return RFAILED;
7710             }
7711             retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
7712             if(retVal != 0)
7713             {
7714                sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
7715                pthread_mutexattr_destroy(&attr);
7716                SPrint(prntBuf);
7717                return RFAILED;
7718             }
7719             break;
7720          }
7721 #endif /* SS_REC_LOCK_SUPPORT */
7722       default :
7723          {
7724             sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
7725             SDisplay(0, prntBuf);
7726             return RFAILED;
7727          }
7728    }
7729    return ROK;
7730 }
7731 /*
7732  *
7733  *       Fun:   ssdLockNew
7734  *
7735  *       Desc:  This function is used to aquire the read write lock
7736  *
7737  *       Ret:   ROK   OK
7738  *
7739  *       Notes:
7740  *
7741  *       File:  mt_ss.c
7742  *
7743  */
7744 S16 ssdLockNew(SLockInfo *lockId,uint8_t lockType)
7745 {
7746
7747    Txt prntBuf[PRNTSZE];
7748    S16    retVal = ROK;
7749
7750
7751    switch(lockType)
7752    {
7753 #ifdef SS_RDWR_LOCK_SUPPORT
7754       case SRDLOCK :
7755          {
7756             if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
7757             {
7758                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7759                SDisplay(0, prntBuf);
7760                return RFAILED;
7761             }
7762             break;
7763          }
7764       case SWRLOCK :
7765          {
7766             if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
7767             {
7768                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
7769                SDisplay(0, prntBuf);
7770                return RFAILED;
7771             }
7772             break;
7773          }
7774       case STRYRDLOCK :
7775          {
7776             if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
7777             {
7778                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7779                SDisplay(0, prntBuf);
7780                return RFAILED;
7781             }
7782             break;
7783          }
7784       case STRYWRLOCK:
7785          {
7786             if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
7787             {
7788                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7789                SDisplay(0, prntBuf);
7790                return RFAILED;
7791             }
7792             break;
7793          }
7794 #endif /* SS_RDWR_LOCK_SUPPORT */
7795 #ifdef SS_REC_LOCK_SUPPORT
7796       case SMUTEXRECUR:
7797          {
7798             if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
7799             {
7800                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7801                SDisplay(0, prntBuf);
7802                return RFAILED;
7803             }
7804             break;
7805          }
7806 #endif /* SS_REC_LOCK_SUPPORT */
7807       default :
7808          {
7809             sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
7810             SDisplay(0, prntBuf);
7811             return RFAILED;
7812          }
7813    }
7814
7815    return ROK;
7816 }
7817
7818
7819 /*
7820  *
7821  *       Fun:   ssdUnlockNew
7822  *
7823  *       Desc:  This function is used to Unlock the read write lock
7824  *
7825  *       Ret:   ROK   OK
7826  *
7827  *       Notes:
7828  *
7829  *       File:  mt_ss.c
7830  *
7831  */
7832 S16 ssdUnlockNew(SLockInfo *lockId,uint8_t lockType)
7833 {
7834
7835    Txt prntBuf[PRNTSZE];
7836    S16    retVal = ROK;
7837
7838
7839    switch(lockType)
7840    {
7841 #ifdef SS_RDWR_LOCK_SUPPORT
7842       case SRDWRLOCK :
7843          {
7844             if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
7845             {
7846                sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
7847                SDisplay(0, prntBuf);
7848                return RFAILED;
7849             }
7850             break;
7851          }
7852 #endif /* SS_RDWR_LOCK_SUPPORT */
7853 #ifdef SS_REC_LOCK_SUPPORT
7854       case SMUTEXRECUR:
7855          {
7856             if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
7857             {
7858                sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7859                SDisplay(0, prntBuf);
7860                return RFAILED;
7861             }
7862             break;
7863          }
7864 #endif /* SS_REC_LOCK_SUPPORT */
7865       default :
7866          {
7867             sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
7868             SDisplay(0, prntBuf);
7869             return RFAILED;
7870          }
7871    }
7872    return ROK;
7873 }
7874
7875 /*
7876  *
7877  *       Fun:   ssdDestroyLockNew
7878  *
7879  *       Desc:  This function is used to destroy the read write lock
7880  *
7881  *       Ret:   ROK   OK
7882  *
7883  *       Notes:
7884  *
7885  *       File:  mt_ss.c
7886  *
7887  */
7888 S16 ssdDestroyLockNew(SLockInfo *lockId,uint8_t lockType)
7889 {
7890    Txt prntBuf[PRNTSZE];
7891    S16    retVal = ROK;
7892
7893
7894    switch(lockType)
7895    {
7896 #ifdef SS_RDWR_LOCK_SUPPORT
7897       case SRDWRLOCK :
7898          {
7899             if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
7900             {
7901                sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
7902                SDisplay(0, prntBuf);
7903                return RFAILED;
7904             }
7905             break;
7906          }
7907 #endif /* SS_RDWR_LOCK_SUPPORT */
7908 #ifdef SS_REC_LOCK_SUPPORT
7909       case SMUTEXRECUR:
7910          {
7911             if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
7912             {
7913                sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
7914                SDisplay(0, prntBuf);
7915                return RFAILED;
7916             }
7917             break;
7918          }
7919 #endif /* SS_REC_LOCK_SUPPORT */
7920       default :
7921          {
7922             sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
7923             SDisplay(0, prntBuf);
7924             return RFAILED;
7925          }
7926    }
7927    return ROK;
7928 }
7929 #endif /* SS_LOCK_SUPPORT */
7930
7931 /* mt005.301 : Cavium Changes */
7932 #ifdef SS_SEUM_CAVIUM
7933
7934 /*
7935  *
7936  *        Fun:   ssInitRcvWork
7937  *
7938  *       Desc:  This is the initializtion function of receive
7939  *              work thread.
7940  *
7941  *       Ret:   ROK      - ok
7942  *              RFAILED  - failed, general (optional)
7943  *
7944  *       Notes: Function to initialize the work queue packet
7945  *              receiving thread. This creates the new thread to
7946  *              receive the work and sets the affinity.
7947  *
7948  *       File:
7949  *
7950  **/
7951 S16 ssInitRcvWork(void)
7952 {
7953    pthread_attr_t attr;
7954    pthread_t      thread;
7955
7956
7957    /* set the required attributes */
7958    pthread_attr_init(&attr);
7959    pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
7960    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
7961    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
7962
7963    /* Create a new thread to receive the work queue messages */
7964    if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
7965    {
7966       pthread_attr_destroy(&attr);
7967
7968       return RFAILED;
7969    }
7970
7971    pthread_attr_destroy(&attr);
7972
7973    return ROK;
7974
7975 }/* ssInitRcvWork */
7976
7977
7978 /*
7979  *
7980  *       Fun:   workRcvTsk
7981  *
7982  *       Desc:  This is the handler function of receive
7983  *              work thread.
7984  *
7985  *       Ret:   ROK      - ok
7986  *              RFAILED  - failed, general (optional)
7987  *
7988  *       Notes:The handler function of the work queue receiver task.
7989  *             This will be waiting for the work and after receiving
7990  *             it, work will converted and posted to that entityt
7991  *
7992  *       File:
7993  *
7994  **/
7995
7996 static void *workRcvTsk(Ptr ptr)
7997 {
7998
7999    cvmx_wqe_t *workPtr;
8000    Buffer     *mBuf, *rcvdBuf;
8001    SsMsgInfo  *minfoPtr;
8002    S16         ret;
8003    struct timespec ts;
8004    Pst         pst;
8005
8006
8007
8008    for (;;)
8009    {
8010       /* get the work if its avilable */
8011       workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8012
8013       if ( workPtr == NULLP )
8014       {
8015          /* If there is no work then sleep for 10 usec */
8016          ts.tv_sec = 0;
8017          ts.tv_nsec = 500000;
8018
8019          nanosleep(&ts, NULLP);
8020          continue;
8021       }
8022
8023       switch(workPtr->tag)
8024       {
8025          /* Switch over according to the tag value */
8026          case SS_CVMX_MBUF_TAG:
8027
8028             rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8029
8030             /* Convert the physical address to Pointers */
8031             ret = SConvPhyPtr(&rcvdBuf);
8032             if (ret != ROK)
8033             {
8034                /* mt011.301: Cavium 32 bit changes */
8035                cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8036                continue;
8037             }
8038
8039             /* Copy the buffer to this region */
8040             ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8041             if( ret != ROK )
8042             {
8043                /* mt011.301: Cavium 32 bit changes */
8044                cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8045                continue;
8046             }
8047
8048             /* mt011.301: Cavium 32 bit changes */
8049             cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8050
8051             minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8052
8053             /* Get the post strucutre and Post the message */
8054             if ( minfoPtr != NULLP)
8055             {
8056                SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8057
8058                (Void)SPstTsk(&pst, mBuf);
8059             }
8060             /* Free the buffer allocated if it cannot be sent */
8061             else
8062             {
8063                SPutMsg(mBuf);
8064             }
8065             break;
8066
8067          default:
8068             {
8069                /* Invalid tag value, drop the work */
8070                /* mt011.301: Cavium 32 bit changes */
8071                cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8072                continue;
8073             }
8074             break;
8075       }
8076
8077    }
8078 } /* workRcvTsk */
8079
8080 #endif /* SS_SEUM_CAVIUM */
8081
8082 #ifdef TENB_RTLIN_CHANGES
8083 S16 SInitLock(SLockId *l, uint8_t t)
8084 {
8085    S16 r = 0;
8086    pthread_mutexattr_t prior;
8087    pthread_mutexattr_init(&prior);
8088 #ifndef RGL_SPECIFIC_CHANGES
8089    pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8090 #endif
8091    r = pthread_mutex_init(l, &prior);
8092    pthread_mutexattr_destroy(&prior);
8093    return r;
8094 }
8095 #endif
8096 #ifdef SS_THR_REG_MAP
8097 /*
8098  *
8099  *       Fun:   ssRegMainThread
8100  *
8101  *       Desc:  This function is used to add the memory region
8102  *              mapping for the main thread.
8103  *
8104  *       Ret:   VOID (Always successful)
8105  *
8106  *       Notes:
8107  *
8108  *       File: mt_ss.c
8109  *
8110  */
8111
8112 Void ssRegMainThread(Void)
8113 {
8114
8115    if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8116    {
8117       printf("\nnot able to get different Id for main thread\n");
8118       exit(1);
8119    }
8120    /* Here the default region is added as we dont have any region associated with
8121     * Main thread. The thread should not perform any allocation except 
8122     * the initial configuratin 
8123     */
8124 #ifdef XEON_SPECIFIC_CHANGES
8125    SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8126 #else   
8127    SS_GET_THREAD_MEM_REGION() = 
8128 #endif      
8129       DFLT_REGION;
8130 }
8131
8132 /*
8133  *
8134  *       Fun:   ssCheckAndAddMemoryRegionMap
8135  *
8136  *       Desc:  This function is used to add the memory region
8137  *              mapping for the provided sTsk associated thread.
8138  *              If the threadId can be placed in the thread memory 
8139  *              region mapping table and returns success if it is able
8140  *              to place. If not, it keeps the thread ID in the static
8141  *              local array and increments the count. Once thread Id 
8142  *              is successfully placed in the thread memory region mapping 
8143  *              table, pthread_cancel is sent for all the previous threads
8144  *              which are failed to place in table.
8145  *
8146  *       Ret:   TRUE - Thread ID successfully placed in thread memory region
8147  *                     mapping table
8148  *              FALSE - If thread Id is not placed in thread memory region
8149  *                     mapping table
8150  *
8151  *       Notes:mapping tablemapping tablng tablee
8152  *
8153  *       File: mt_ss.c
8154  *
8155  */
8156    S32 ssCheckAndAddMemoryRegionMap
8157 (
8158  pthread_t    threadId,    /* Thread Id of system task */
8159  Region       region       /* Region associated with thread */
8160  )
8161 {
8162    static uint32_t       createdThreads;
8163    static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8164    uint32_t               indx;
8165
8166
8167    /* Here  0xFF is considered as invalid region and if the mapping table
8168     * contains 0xFF, that mapping entry is free
8169     */
8170    if(SS_INVALID_THREAD_REG_MAP != 
8171          osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8172    {
8173       /* Klock work fix ccpu00148484 */
8174       if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8175       {
8176          printf("\nfailed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8177          printf("\nNot able to get the different thread ID, exiting\n");
8178          exit(1);
8179       }
8180       createdThreadIds[createdThreads++] = threadId;
8181       return (FALSE);
8182    }
8183    /* If we found free mapping table entry, place the region and send pthread_cancel
8184     * for all the thread Ids which are created before this 
8185     */
8186    osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8187 #ifdef XEON_SPECIFIC_CHANGES
8188    printf("\nThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8189          ((threadId >> SS_MEM_THREAD_ID_SHIFT) % 
8190           SS_MAX_THREAD_REGION_MAP), region);
8191 #endif   
8192    for(indx = 0; indx < createdThreads; indx++)
8193    {
8194 #ifdef XEON_SPECIFIC_CHANGES
8195       printf("\nSending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8196 #endif      
8197       pthread_cancel(createdThreadIds[indx]);
8198    }
8199    createdThreads = 0;
8200
8201    return (TRUE);
8202
8203 } /* ssCheckAndAddMemoryRegionMap */
8204
8205 /*
8206  *
8207  *       Fun:   ssCheckAndDelMemoryRegionMap
8208  *
8209  *       Desc:  This function is used to add the memory region
8210  *              mapping for the provided sTsk associated thread.
8211  *              If the threadId can be placed in the thread memory 
8212  *              region mapping table and returns success if it is able
8213  *              to place. If not, it keeps the thread ID in the static
8214  *              local array and increments the count. Once thread Id 
8215  *              is successfully placed in the thread memory region mapping 
8216  *              table, pthread_cancel is sent for all the previous threads
8217  *              which are failed to place in table.
8218  *
8219  *       Ret:   TRUE - Thread ID successfully placed in thread memory region
8220  *                     mapping table
8221  *              FALSE - If thread Id is not placed in thread memory region
8222  *                     mapping table
8223  *
8224  *       Notes:mapping tablemapping tablng tablee
8225  *
8226  *       File: mt_ss.c
8227  *
8228  */
8229    S32 ssCheckAndDelMemoryRegionMap
8230 (
8231  pthread_t    threadId    /* Thread Id of system task */
8232  )
8233 {
8234
8235
8236    /* Raghu To-Do Check with team, is it necessary to acquire lock
8237     * as del and add may go parallel */
8238    /* Here  0xFF is considered as invalid region and if the mapping table
8239     * contains 0xFF, that mapping entry is free
8240     */
8241    if(SS_INVALID_THREAD_REG_MAP ==
8242          osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8243    {
8244 #ifndef ALIGN_64BIT
8245       printf("\nInvalid Thread ID (%ld)\n", (uint32_t)threadId);
8246 #else
8247       printf("\nInvalid Thread ID (%d)\n", (uint32_t)threadId);
8248 #endif
8249       return RFAILED;
8250    }
8251    /* If we found free mapping table entry, place the region and send pthread_cancel
8252     * for all the thread Ids which are created before this 
8253     */
8254    osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8255
8256    return ROK;
8257
8258 } /* ssCheckAndAddMemoryRegionMap */
8259
8260
8261 #endif
8262 #ifdef SS_TSKLOG_ENABLE
8263 /*
8264  *
8265  *       Fun:   SStartTask
8266  *
8267  *       Desc:  This function will return current time through input parameter.
8268  *
8269  *       Ret:   ROK      - ok
8270  *              RFAILED  - failed, general (optional)
8271  *
8272  *
8273  *       File:  pt_ss.c
8274  *
8275  */
8276    S16 SStartTask
8277 (
8278  volatile uint32_t      *startTime,
8279  uint32_t       taskId
8280  )
8281 {
8282 #ifdef MSPD_MLOG_NEW
8283    *startTime = GetTIMETICK();
8284 #endif
8285    return ROK;
8286 }
8287 \f
8288 /*
8289  *
8290  *       Fun:   SStopTask
8291  *
8292  *       Desc:  This function will return current time through input parameter.
8293  *              and take the difference of start time provided as input parameter
8294  *              and current time.
8295  *
8296  *       Ret:   ROK      - ok
8297  *              RFAILED  - failed, general (optional)
8298  *
8299  *
8300  *       File:  pt_ss.c
8301  *
8302  */
8303    S16 SStopTask
8304 (
8305  volatile uint32_t       startTime,
8306  uint32_t       taskId
8307  )
8308 {
8309    /*uint32_t      stopTime;*/
8310    switch(taskId)
8311    {
8312       case PID_MAC_HARQ_IND:
8313       case PID_SCH_TTI_IND:               
8314       case PID_SSI_TSK:               
8315       case PID_MAC_DAT_IND:
8316       case PID_MAC_SF_ALLOC_REQ:
8317       case PID_MAC_STA_RSP:
8318       case PID_MAC_DL_SCHD:
8319       case PID_MAC_DL_CQI_IND:
8320       case PID_MAC_UL_CQI_IND:
8321       case PID_MAC_UL_SCHD:
8322       case PID_MAC_TTI_IND:
8323       case PID_CL_RCV_PHY_MSG:
8324       case PID_CL_HARQ_STA_IND:
8325       case PID_MAC_AM_HARQ_RLS:
8326       case PID_CL_DL_BATCH_PROC:
8327       case PID_CL_DLM_PRC_TTI_IND:
8328       case PID_CRC_IND_REAL:
8329       case PID_CRC_IND_DUMMY:
8330       case PID_TTI_LATENCY:
8331       case PID_RECPREQ_PROC:
8332 #ifdef CA_PHY
8333 #ifndef LTE_TDD               
8334          MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8335 #else
8336          MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8337 #endif
8338 #else
8339          MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8340 #endif
8341          break;
8342    }
8343    return ROK;
8344 }
8345 #else
8346    S16 SStartTask
8347 (
8348  volatile uint32_t * startTime,
8349  uint32_t taskId
8350  )
8351 {
8352    *startTime = 0;
8353    return ROK;
8354 }
8355
8356    S16 SStopTask
8357 (
8358  volatile uint32_t startTime,
8359  uint32_t taskId
8360  )
8361 {
8362    return ROK;
8363 }
8364
8365 #endif /*#ifdef SS_TSKLOG_ENABLE */
8366 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8367 /** @details
8368  * This primitive is used to calculate the CPU Utilization per Core
8369  * for Intel T2200
8370  *
8371  * @param [in]   Void
8372  *
8373  * @return  Void - function is always success
8374  */
8375    Void UpdateSocCpuInfo
8376 (
8377  CmCpuStatsInfo *cpuInfo, 
8378  uint8_t    idx
8379  )
8380 {
8381    FILE       *mipsFd;
8382    S8         mipsStr[MIPS_STRING_LEN];
8383    S8         *strPart;
8384    uint32_t   l2FreeCpu;
8385    uint32_t   l2CpuUsed;
8386    uint32_t   l3FreeCpu;
8387    uint32_t   l3CpuUsed;
8388
8389    /* Open the file which holds the MIPS available value */
8390    mipsFd = fopen(MIPS_FILE, "r");
8391
8392    if(mipsFd == NULLP)
8393    {
8394       return;
8395    }
8396
8397    /* Get the free mips available value from the file */
8398    if(NULLP  == fgets(mipsStr, 24, mipsFd))
8399    {
8400       printf("\nfgets to get the free mips available failed\n");
8401       fclose(mipsFd);
8402       return;
8403    }
8404
8405    strtok(mipsStr, " ");
8406
8407    strPart = strtok(NULLP, " ");
8408
8409    if(idx == CM_L2_CPU_UTIL)
8410    {  
8411       if(strPart != NULLP)
8412       {
8413          l2FreeCpu = atoi(strPart);   
8414          l2CpuUsed = 100 - l2FreeCpu;
8415          cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8416          cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
8417          cpuInfo->cpuUtil[0].numSamples++;
8418       }
8419    }
8420    if(idx == CM_L3_CPU_UTIL)
8421    {  
8422       strPart = strtok(NULLP, " ");
8423       if(strPart != NULLP)
8424       {
8425          l3FreeCpu = atoi(strPart);   
8426          l3CpuUsed = 100 - l3FreeCpu;
8427          cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8428          cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
8429          cpuInfo->cpuUtil[0].numSamples++;
8430       }
8431    }
8432    if(idx == CM_L2_CPU_UTIL)
8433    {   
8434       cpuInfo->numCores = CM_NUM_L2_CORES ; 
8435    }
8436    else if(idx == CM_L3_CPU_UTIL)
8437    {   
8438       cpuInfo->numCores = CM_NUM_L3_CORES ; 
8439    }
8440    fclose(mipsFd);
8441
8442    return;
8443 }
8444 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8445 #ifdef SS_MULTICORE_SUPPORT
8446 /*
8447  *
8448  *       Fun:   Add Timer thread into system task table
8449  *
8450  *       Desc:  This function is used to add the system task
8451  *              associated with Timer thread.
8452  *
8453  *       Ret:   None
8454  *
8455  *       Notes:
8456  *
8457  *       File:  mt_ss.c
8458  *
8459  --*/
8460 static SsSTskEntry* ssdReAddTmrSTsk(
8461       uint8_t idx
8462       )
8463 {
8464    SsSTskEntry *sTsk;
8465    S16 ret;
8466
8467    sTsk = NULLP;
8468    /* lock the system task table */
8469    ret = SLock(&osCp.sTskTblLock);
8470    if (ret != ROK)
8471    {
8472
8473 #if (ERRCLASS & ERRCLS_DEBUG)
8474       MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8475             "Could not lock system task table");
8476 #endif
8477
8478       return (sTsk);
8479    }
8480
8481    /* initialize the system task entry with the information we have */
8482    sTsk = &osCp.sTskTbl[idx];
8483
8484    sTsk->used = FALSE;
8485    sTsk->tskPrior = 0;
8486    sTsk->numTTsks = 0;
8487    SDestroyLock(&sTsk->lock);
8488    ssDestroyDmndQ(&sTsk->dQ);
8489
8490
8491    /* store the system task priority */
8492    sTsk->tskPrior = SS_NORM_TSK_PRI;
8493
8494    /* initialize the demand queue */
8495    if (ssInitDmndQ(&sTsk->dQ) != ROK)
8496    {
8497
8498       if ( SUnlock(&osCp.sTskTblLock) != ROK)
8499       {
8500 #if (ERRCLASS & ERRCLS_DEBUG)
8501          MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8502                "Could not give the Semaphore");
8503          return (NULLP);
8504 #endif
8505       }
8506
8507 #if (ERRCLASS & ERRCLS_DEBUG)
8508       MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8509             "Could not initialize demand queue");
8510 #endif
8511
8512       return (NULLP);
8513    }
8514
8515    /* initialize the system task entry lock */
8516    if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8517    {
8518       ssDestroyDmndQ(&sTsk->dQ);
8519
8520       if ( SUnlock(&osCp.sTskTblLock) != ROK)
8521       {
8522 #if (ERRCLASS & ERRCLS_DEBUG)
8523          MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8524                "Could not give the Semaphore");
8525          return (NULLP);
8526 #endif
8527       }
8528
8529 #if (ERRCLASS & ERRCLS_DEBUG)
8530       MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8531             "Could not initialize system task entry lock");
8532 #endif
8533
8534       return (NULLP);
8535    }
8536
8537
8538    /* success, update the table */
8539    sTsk->tskId       = idx + 1;
8540    sTsk->used        = TRUE;
8541    sTsk->termPend    = FALSE;
8542
8543    /* unlock the system task table */
8544
8545    if ( SUnlock(&osCp.sTskTblLock) != ROK)
8546    {
8547 #if (ERRCLASS & ERRCLS_DEBUG)
8548       MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8549             "Could not give the Semaphore");
8550       return (NULLP);
8551 #endif
8552    }
8553
8554    return (sTsk);
8555 }
8556 #endif /* SS_MULTICORE_SUPPORT */
8557
8558 \f
8559 /*
8560  *
8561  *       Fun:   Initialize timer table
8562  *
8563  *       Desc:  This function initializes MTSS-specific information
8564  *              in the timer table.
8565  *
8566  *       Ret:   ROK      - ok
8567  *
8568  *       Notes:
8569  *
8570  *       File:  mt_ss.c
8571  *
8572  */
8573 S16 ssdReInitTmr(void)
8574 {
8575    pthread_attr_t attr;
8576    struct sched_param param_sched;
8577 #ifndef XEON_SPECIFIC_CHANGES
8578    uint8_t ret = ROK;
8579 #endif
8580 #ifdef SS_MULTICORE_SUPPORT
8581    SsSTskEntry     *sTsk;
8582 #endif /* SS_MULTICORE_SUPPORT */
8583 #ifdef SS_THR_REG_MAP
8584    uint32_t threadCreated = FALSE;
8585 #endif /* SS_THR_REG_MAP */
8586
8587
8588 #ifndef XEON_SPECIFIC_CHANGES
8589    ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
8590    if(ret != ROK)
8591    {
8592 #if (ERRCLASS & ERRCLS_DEBUG)
8593       MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8594             "Could not give the Semaphore");
8595 #endif
8596       return RFAILED;
8597    }
8598 #endif   
8599
8600    osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
8601    /* mt010.21: addition */
8602
8603 #ifdef SS_MULTICORE_SUPPORT
8604    sTsk = ssdReAddTmrSTsk(0);
8605    if(!sTsk)
8606    {
8607       return RFAILED;
8608    }
8609 #endif /* SS_MULTICORE_SUPPORT */
8610    /* create the timer handler thread */
8611
8612    pthread_attr_init(&attr);
8613    /* mt021.201 - Addition to set stack size */
8614    pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
8615    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8616    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8617    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
8618    param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
8619    pthread_attr_setschedparam(&attr, &param_sched);
8620
8621
8622 #ifdef SS_THR_REG_MAP
8623    /* When the thread is created, we check for the memory mapping table if
8624     * threadId can be placed in thread memory map table. If it is not able to place
8625     * threadId is stored in tmporary array. Once thread is created successful,
8626     * thread_cancel is sent for each thread which are created before. All the 
8627     * threads are made to wait on sema which is cancel point for thread.
8628     */
8629    while(threadCreated == FALSE)
8630    {
8631 #endif
8632       if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
8633       {
8634          /* mt020.201 - Addition for destroying thread attribute object attr */
8635          pthread_attr_destroy(&attr);
8636
8637          return RFAILED;
8638       }
8639
8640 #ifdef SS_THR_REG_MAP
8641       threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID, 
8642             sTsk->region);
8643    }
8644 #endif /* SS_THR_REG_MAP */
8645 #ifdef SS_MEM_WL_DEBUG
8646    tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
8647 #endif
8648
8649    /* mt020.201 - Addition for destroying thread attribute object attr */
8650    pthread_attr_destroy(&attr);
8651    sem_post(&osCp.dep.ssStarted);
8652    return ROK;
8653 }
8654
8655 /**********************************************************************
8656   End of file
8657  **********************************************************************/