comparison gpf/frame/vsi_com.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 +------------------------------------------------------------------------------
3 | File: vsi_com.c
4 +------------------------------------------------------------------------------
5 | Copyright 2002 Texas Instruments Berlin, AG
6 | All rights reserved.
7 |
8 | This file is confidential and a trade secret of Texas
9 | Instruments Berlin, AG
10 | The receipt of or possession of this file does not convey
11 | any rights to reproduce or disclose its contents or to
12 | manufacture, use, or sell anything it may describe, in
13 | whole, or in part, without the specific written consent of
14 | Texas Instruments Berlin, AG.
15 +-----------------------------------------------------------------------------
16 | Purpose : This Module defines the virtual system interface part
17 | about communication via primitives and signals.
18 +-----------------------------------------------------------------------------
19 */
20
21 #undef TEST_PCHECK
22
23 #ifndef __VSI_COM_C__
24 #define __VSI_COM_C__
25 #endif
26
27 /*==== INCLUDES ===================================================*/
28
29 #include "gpfconf.h"
30 #include "typedefs.h"
31 #include "string.h"
32 #include "os.h"
33 #include "vsi.h"
34 #include "frame.h"
35 #include "vsi.h"
36 #include "frm_defs.h"
37 #include "frm_types.h"
38 #include "frm_glob.h"
39 #include "route.h"
40
41 #ifdef MEMORY_SUPERVISION
42 #include "tools.h"
43 #endif
44
45 #ifdef _TOOLS_
46 #include "stdlib.h"
47 #endif
48
49 /*==== CONSTANTS ==================================================*/
50
51 #ifndef RUN_INT_RAM
52 char const *waited_queue_str= "Waited for space in queue";
53 char const *freed_sent_str = "Freed partition sent";
54 char const *disc_str = "Signal discarded";
55 char const *freed_str = "Partition already freed";
56 char const *trunc_str = "Allocation request truncated";
57 char const *guard_str = "Partition guard pattern destroyed";
58 char const *unknown_str = "unknown";
59 #else
60 extern char const *waited_queue_str;
61 extern char const *freed_sent_str;
62 extern char const *disc_str;
63 extern char const *freed_str;
64 extern char const *trunc_str;
65 extern char const *guard_str;
66 extern char const *unknown_str;
67 #endif
68
69 #if !defined _TARGET_ && !defined _TOOLS_
70 char const *pcheck_str = "pcon_check() returned error";
71 #define PCHECK_INITIALIZED 0xaffedead
72 #endif
73
74
75 #define MAX_DRP_BOUND 12
76
77 /*==== TYPES ======================================================*/
78
79 #if !defined _TARGET_ && !defined _TOOLS_
80 typedef struct
81 {
82 unsigned int magic_nr;
83 ULONG ret_ok;
84 ULONG (*pcheck)(ULONG opc, void * decoded_prim);
85 } T_PCHECK;
86 #endif
87
88 /*==== EXTERNALS ==================================================*/
89
90 /* -------------- S H A R E D - BEGIN ---------------- */
91 #ifdef _TOOLS_
92 #pragma data_seg("FRAME_SHARED")
93 #endif
94
95
96 #ifdef _TOOLS_
97 extern char FRM_TST_NAME[];
98 __declspec (dllimport) T_HANDLE TST_Handle;
99 #else
100 extern T_HANDLE TST_Handle;
101 #endif
102
103 extern T_HANDLE vsi_m_sem_handle;
104 extern char TaskName [];
105 //extern OS_HANDLE ext_data_pool_handle;
106 #if defined _NUCLEUS_ && defined NU_DEBUG
107 extern char check_desclist;
108 #endif
109
110 /*==== VARIABLES ==================================================*/
111
112 #if !defined _TARGET_ && !defined _TOOLS_
113 T_PCHECK pcheck_func;
114 #endif /* _TARGET_ */
115
116 #ifndef RUN_INT_RAM
117 char QueueName [ RESOURCE_NAMELEN ];
118 //char *pf_com_matrix = NULL;
119 #else
120 extern char QueueName [];
121 #endif
122
123 #ifdef _TOOLS_
124 #pragma data_seg()
125 #endif
126 /* -------------- S H A R E D - END ---------------- */
127
128 /*==== PROTOTYPES =================================================*/
129
130 #if !defined _TARGET_ && !defined _TOOLS_
131 #ifdef TEST_PCHECK
132 ULONG test_pcheck ( ULONG opc, void * decoded_prim );
133 #endif
134 #endif /* _TARGET_ */
135
136
137 #if defined _NUCLEUS_ && defined NU_DEBUG
138 int check_descriptor_list ( T_HANDLE caller, T_PRIM_HEADER *prim FILE_LINE_TYPE );
139 #endif
140
141 int int_vsi_c_pattach (T_VOID_STRUCT *prim FILE_LINE_TYPE);
142
143
144 /*==== FUNCTIONS ==================================================*/
145
146 #if 0
147 not needed -> temporarily removed
148 #ifndef RUN_INT_RAM
149 /*
150 +--------------------------------------------------------------------+
151 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
152 | STATE : code ROUTINE : vsi_c_open |
153 +--------------------------------------------------------------------+
154
155 PURPOSE : get the handle of a queue
156
157 */
158
159 char * vsi_c_init_com_matrix ( int max_entities )
160 {
161 int size;
162
163 size = (max_entities+1)*(max_entities+1);
164 if ( os_AllocateMemory ( NO_TASK, (T_VOID_STRUCT**)&pf_com_matrix, size, OS_NO_SUSPEND, ext_data_pool_handle ) != OS_OK )
165 {
166 vsi_o_assert ( NO_TASK, OS_SYST_ERR_NO_MEMORY, __FILE__, __LINE__, "No memory available for com matrix");
167 }
168 return pf_com_matrix;
169 }
170 #endif
171
172
173 #ifndef RUN_INT_RAM
174 /*
175 +--------------------------------------------------------------------------+
176 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
177 | STATE : code ROUTINE : vsi_c_get_com_matrix_entry|
178 +--------------------------------------------------------------------------+
179
180 PURPOSE : get an entry of the com matrix
181
182 */
183
184 int vsi_c_get_com_matrix_entry ( int entry, char *dst )
185 {
186 T_HANDLE snd, rcv;
187 static int cnt;
188 int size_of_matrix = (MaxEntities+1)*(MaxEntities+1);
189 int snd_len;
190
191 if ( entry == FIRST_ENTRY )
192 {
193 cnt = 0;
194 }
195 while ( cnt <= size_of_matrix )
196 {
197 if ( pf_com_matrix[cnt] != 0 )
198 {
199 snd = cnt/(MaxEntities+1);
200 vsi_e_name (NO_TASK, snd, &dst[0]);
201 snd_len = strlen(&dst[0]);
202 dst[snd_len]=' ';
203 rcv = cnt%(MaxEntities+1);
204 vsi_e_name (NO_TASK, rcv, &dst[snd_len+1]);
205 cnt++;
206 return VSI_OK;
207 }
208 cnt++;
209 }
210 return VSI_ERROR;
211 }
212 #endif
213
214 #ifndef RUN_INT_RAM
215 /*
216 +--------------------------------------------------------------------------+
217 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
218 | STATE : code ROUTINE : vsi_c_get_entity_com_entry|
219 +--------------------------------------------------------------------------+
220
221 PURPOSE : get a entity handle the is used by an entity to send primitives
222
223 */
224
225 int vsi_c_get_entity_com_entry ( int entry, T_HANDLE rcv, T_HANDLE *snd )
226 {
227 static int cnt;
228 int size_of_matrix = (MaxEntities+1)*(MaxEntities+1);
229
230 if ( entry == FIRST_ENTRY )
231 {
232 cnt = rcv;
233 }
234 while ( cnt <= size_of_matrix )
235 {
236 if ( pf_com_matrix[cnt] != 0 )
237 {
238 *snd = cnt / (MaxEntities + 1);
239 cnt = cnt + MaxEntities + 1;
240 return VSI_OK;
241 }
242 cnt = cnt + MaxEntities + 1;
243 }
244 return VSI_ERROR;
245 }
246 #endif
247 #endif
248
249 #ifndef RUN_INT_RAM
250 /*
251 +--------------------------------------------------------------------+
252 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
253 | STATE : code ROUTINE : vsi_c_open |
254 +--------------------------------------------------------------------+
255
256 PURPOSE : get the handle of a queue
257
258 */
259
260 T_HANDLE vsi_c_open (T_HANDLE Caller, char *Name)
261 {
262 #ifdef _TOOLS_
263 OS_HANDLE ComHandle;
264
265 if ( os_OpenQueue ( Caller, Name, &ComHandle ) != OS_ERROR )
266 return ComHandle;
267 #else
268 T_HANDLE e_handle;
269
270 for ( e_handle = MaxEntities; e_handle > 0; e_handle-- )
271 {
272 if ( pf_TaskTable[e_handle].Name[0] != 0
273 && pf_TaskTable[e_handle].QueueHandle != 0
274 && !strncmp (pf_TaskTable[e_handle].Name, Name, RESOURCE_NAMELEN-1) )
275 {
276 /*
277 not needed -> temporarily removed
278 pf_com_matrix[Caller*(MaxEntities+1)+e_handle] = 1;
279 */
280 return e_handle;
281 }
282 }
283 #endif
284 return VSI_ERROR;
285 }
286 #endif
287
288 #ifndef RUN_INT_RAM
289 /*
290 +--------------------------------------------------------------------+
291 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
292 | STATE : code ROUTINE : vsi_c_close |
293 +--------------------------------------------------------------------+
294
295 PURPOSE : return the handle of a queue
296
297 */
298
299 int vsi_c_close (T_HANDLE Caller, T_HANDLE ComHandle)
300 {
301
302 if ( os_CloseQueue ( Caller, ComHandle ) != OS_ERROR )
303 return VSI_OK;
304
305 return VSI_ERROR;
306 }
307 #endif
308
309 #ifndef RUN_INT_RAM
310 /*
311 +--------------------------------------------------------------------+
312 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
313 | STATE : code ROUTINE : vsi_c_clear |
314 +--------------------------------------------------------------------+
315
316 PURPOSE : read all messages from a queue
317
318 */
319
320 int vsi_c_clear (T_HANDLE Caller, T_HANDLE ComHandle)
321 {
322 OS_QDATA Msg;
323
324 while ( os_ReceiveFromQueue ( NO_TASK, ComHandle, &Msg, OS_NO_SUSPEND ) == OS_OK )
325 {
326 ;
327 }
328
329 return VSI_OK;
330 }
331 #endif
332
333 #ifndef RUN_FLASH
334 /*
335 +--------------------------------------------------------------------+
336 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
337 | STATE : code ROUTINE : vsi_c_send |
338 +--------------------------------------------------------------------+
339
340 PURPOSE : write a message to a queue
341
342 */
343
344 int vsi_c_send (T_HANDLE Caller, T_HANDLE ComHandle, T_QMSG *Msg FILE_LINE_TYPE)
345 {
346 OS_QDATA OS_Msg = { 0 };
347 LONG Status;
348 USHORT Prio;
349 #ifdef NU_DEBUG
350 T_PRIM_HEADER *prim;
351 #ifdef _TARGET_
352 T_HANDLE t_handle;
353 #endif
354 #endif
355
356 OS_Msg.data16 = Msg->MsgType;
357 OS_Msg.e_id = ComHandle;
358 switch ( Msg->MsgType )
359 {
360 case MSG_PRIMITIVE:
361 OS_Msg.ptr = Msg->Msg.Primitive.Prim;
362 OS_Msg.data32 = P_OPC(Msg->Msg.Primitive.Prim);
363 #ifdef _TOOLS_
364 OS_Msg.len = Msg->Msg.Primitive.PrimLen;
365 #endif
366 os_GetTime ( 0, &OS_Msg.time );
367 Prio = MSG_PRIMITIVE_PRIO;
368 break;
369 case MSG_SIGNAL:
370 OS_Msg.ptr = Msg->Msg.Signal.SigBuffer;
371 OS_Msg.data32 = Msg->Msg.Signal.SigOPC;
372 #ifdef _TOOLS_
373 OS_Msg.len = Msg->Msg.Signal.SigLen;
374 #endif
375 os_GetTime ( 0, &OS_Msg.time );
376 Prio = MSG_SIGNAL_PRIO;
377 break;
378 default: return VSI_ERROR;
379 /*lint -e527 suppress Warning -- Unreachable */
380 break;
381 /*lint +e527 */
382 }
383
384 #ifdef _NUCLEUS_
385 #ifdef NU_DEBUG
386 /* PARTITION GUARD PATTERN CHECK */
387 if ( Msg->MsgType == MSG_PRIMITIVE )
388 {
389 prim = (T_PRIM_HEADER*)Msg->Msg.Primitive.Prim;
390 if ( (Status = os_PartitionCheck ( (T_VOID_STRUCT*)prim )) == OS_OK )
391 {
392 if ( check_desclist == TRUE && prim->dph_offset != 0 )
393 {
394 check_descriptor_list ( Caller, prim FILE_LINE );
395 }
396 }
397 else
398 {
399 switch ( Status )
400 {
401 case OS_PARTITION_FREE:
402 vsi_o_assert ( Caller, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
403 "%s (PSEND),entity %s, partition 0x%x, opc 0x%x",
404 freed_sent_str, pf_TaskTable[Caller].Name, prim, prim->opc );
405 break;
406 case OS_PARTITION_GUARD_PATTERN_DESTROYED:
407 vsi_o_assert ( Caller, OS_SYST_ERR_PCB_PATTERN FILE_LINE_MACRO_PASSED,
408 "%s (PSEND), entity %s, partition 0x%x, opc 0x%x",
409 guard_str, pf_TaskTable[Caller].Name, prim, prim->opc );
410 break;
411 default:
412 break;
413 }
414 }
415 #ifdef MEMORY_SUPERVISION
416 vsi_ppm_send ( Caller, ComHandle, (T_PRIM_HEADER*)Msg->Msg.Primitive.Prim, file, line );
417 #endif /* MEMORY_SUPERVISION */
418 }
419 #ifdef _TARGET_
420 if ( (t_handle = os_MyHandle()) != 0 )
421 {
422 int opc;
423 switch ( os_CheckTaskStack ( t_handle ) )
424 {
425 case OS_ERROR:
426 if ( Msg->MsgType == MSG_PRIMITIVE )
427 {
428 opc = ((T_PRIM_HEADER*)Msg->Msg.Primitive.Prim)->opc;
429 }
430 else
431 {
432 opc = Msg->Msg.Signal.SigOPC;
433 }
434 vsi_o_assert ( Caller, OS_SYST_ERR_STACK_OVERFLOW FILE_LINE_MACRO_PASSED,
435 "%s Stack overflow, 0x%x", pf_TaskTable[Caller].Name, opc );
436 break;
437 default:
438 break;
439 }
440 }
441 #endif /* _TARGET_ */
442 #endif /* NU_DEBUG */
443 #endif /* _NUCLEUS_ */
444
445 Status = rt_Route ( Caller, ComHandle, Prio, OS_SUSPEND, &OS_Msg );
446
447 switch ( Status )
448 {
449 case OS_WAITED:
450 #ifdef NU_DEBUG
451 pf_handle_warning ( OS_SYST_WRN_WAIT_QUEUE, "%s %s, entity %s, queue %s, %s(%d)",
452 syst_wrn, waited_queue_str, pf_TaskTable[Caller].Name, pf_TaskTable[ComHandle].Name FILE_LINE_MACRO_PASSED );
453 #endif
454 return VSI_OK;
455 /*lint -e527 suppress Warning -- Unreachable */
456 break;
457 /*lint +e527 */
458 case OS_TIMEOUT:
459 case OS_ERROR:
460 case OS_INVALID_QUEUE:
461 Caller = e_running[os_MyHandle()];
462 if ( Msg->MsgType == MSG_SIGNAL )
463 {
464 #ifdef NU_DEBUG
465 pf_handle_warning ( OS_SYST_WRN_WAIT_QUEUE, "%s %s from %s to %s, opc 0x%x, %s(%d)",
466 syst_wrn, disc_str, pf_TaskTable[Caller].Name, pf_TaskTable[ComHandle].Name, Msg->Msg.Signal.SigOPC FILE_LINE_MACRO_PASSED );
467 #endif
468 return VSI_OK;
469 }
470 else
471 {
472 char const *p_queue_name;
473 if ( Status == OS_INVALID_QUEUE )
474 {
475 p_queue_name = unknown_str;
476 }
477 else
478 {
479 #ifdef _TOOLS_
480 os_GetQueueName ( Caller, ComHandle, QueueName );
481 p_queue_name = QueueName;
482 #else
483 p_queue_name = pf_TaskTable[ComHandle].Name;
484 #endif
485 }
486 vsi_o_assert ( Caller, OS_SYST_ERR_QUEUE_FULL FILE_LINE_MACRO_PASSED,
487 "%s write attempt to %s queue failed",
488 pf_TaskTable[Caller].Name, p_queue_name );
489 #ifdef MEMORY_SUPERVISION
490 vsi_ppm_free ( Caller, (T_PRIM_HEADER*)(OS_Msg.ptr-PPM_OFFSET), file, line);
491 #endif
492 os_DeallocatePartition (Caller, OS_Msg.ptr-PPM_OFFSET );
493 return VSI_ERROR;
494 }
495 /*lint -e527 suppress Warning -- Unreachable */
496 break;
497 /*lint +e527 */
498 case OS_OK:
499 return VSI_OK;
500 /*lint -e527 suppress Warning -- Unreachable */
501 break;
502 /*lint +e527 */
503 default:
504 return VSI_ERROR;
505 /*lint -e527 suppress Warning -- Unreachable */
506 break;
507 /*lint +e527 */
508 }
509
510 }
511 #endif
512
513 #ifndef RUN_FLASH
514 /*
515 +--------------------------------------------------------------------+
516 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
517 | STATE : code ROUTINE : vsi_c_psend |
518 +--------------------------------------------------------------------+
519
520 PURPOSE : wrapper for vsi_c_send to avoid code wasting macro
521
522 */
523 int vsi_c_psend_caller ( T_HANDLE Caller, T_HANDLE ComHandle, T_VOID_STRUCT *ptr FILE_LINE_TYPE )
524 {
525 T_QMSG QMsg;
526 T_VOID_STRUCT *snd_ptr = (T_VOID_STRUCT*)D2P(ptr);
527
528 QMsg.Msg.Primitive.Prim = snd_ptr;
529 #ifdef _TOOLS_
530 if ( ((T_PRIM_HEADER*)snd_ptr)->sh_offset != 0 )
531 QMsg.Msg.Primitive.PrimLen = ALIGN(PSIZE(ptr)) + sizeof(T_S_HEADER);
532 else
533 #endif
534 QMsg.Msg.Primitive.PrimLen = PSIZE(ptr);
535 QMsg.MsgType = MSG_PRIMITIVE;
536 if ( Caller != TST_Handle && !(P_OPC(QMsg.Msg.Primitive.Prim) & SYS_MASK ) )
537 vsi_o_ptrace (Caller, P_OPC(QMsg.Msg.Primitive.Prim), 1);
538
539 #if !defined _TARGET_ && !defined _TOOLS_
540 if ( (pcheck_active[Caller] == 1) && (pcheck_func.pcheck != NULL) )
541 {
542 ULONG ret;
543 if ( (ret = pcheck_func.pcheck ( D_OPC(ptr), ptr )) != pcheck_func.ret_ok )
544 {
545 pf_handle_warning ( OS_SYST_WRN, "%s %s %d in %s, opc 0x%x, %s(%d)",
546 syst_wrn, pcheck_str, ret, pf_TaskTable[Caller].Name, D_OPC(ptr) FILE_LINE_MACRO_PASSED );
547 }
548 }
549 #endif
550 return ( vsi_c_send ( Caller, ComHandle, &QMsg FILE_LINE) );
551 }
552 #endif
553
554 #ifndef RUN_FLASH
555 /*
556 +--------------------------------------------------------------------+
557 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
558 | STATE : code ROUTINE : vsi_c_psend |
559 +--------------------------------------------------------------------+
560
561 PURPOSE : wrapper for vsi_c_send to avoid code wasting macro
562
563 */
564 int vsi_c_psend ( T_HANDLE ComHandle, T_VOID_STRUCT *ptr FILE_LINE_TYPE )
565 {
566 T_HANDLE Caller;
567
568 Caller = e_running[os_MyHandle()];
569
570 return ( vsi_c_psend_caller ( Caller, ComHandle, ptr FILE_LINE) );
571 }
572 #endif
573
574 #ifndef RUN_FLASH
575 /*
576 +--------------------------------------------------------------------+
577 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
578 | STATE : code ROUTINE : vsi_c_ssend |
579 +--------------------------------------------------------------------+
580
581 PURPOSE : wrapper for vsi_c_send to avoid code wasting macro
582
583 */
584 int vsi_c_ssend ( T_HANDLE ComHandle, ULONG opc, T_VOID_STRUCT *ptr,
585 ULONG MsgLen FILE_LINE_TYPE )
586 {
587 T_QMSG QMsg;
588 T_HANDLE Caller;
589
590 Caller = e_running[os_MyHandle()];
591
592 QMsg.Msg.Signal.SigBuffer = (T_VOID_STRUCT*)ptr;
593 QMsg.Msg.Signal.SigOPC = opc;
594 QMsg.Msg.Signal.SigLen = MsgLen;
595 QMsg.MsgType = MSG_SIGNAL;
596
597 return ( vsi_c_send ( Caller, ComHandle, &QMsg FILE_LINE ) );
598
599 }
600 #endif
601
602 #ifndef RUN_FLASH
603 /*
604 +--------------------------------------------------------------------+
605 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
606 | STATE : code ROUTINE : vsi_c_new |
607 +--------------------------------------------------------------------+
608
609 PURPOSE : allocate a partition to send a primitive
610
611 */
612
613 T_VOID_STRUCT * vsi_c_new (T_HANDLE Caller, ULONG Size, ULONG opc FILE_LINE_TYPE)
614 {
615 T_VOID_STRUCT *prim;
616 ULONG flags;
617
618 /* VSI_MEM_NON_BLOCKING not set, blocking allocation for backwards compatibility */
619 flags = PrimGroupHandle;
620 prim = (T_VOID_STRUCT*)D2P(vsi_c_pnew_generic (Caller, Size, opc, flags FILE_LINE));
621 return prim;
622
623 }
624 #endif
625
626 #ifndef RUN_FLASH
627 /*
628 +--------------------------------------------------------------------+
629 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
630 | STATE : code ROUTINE : vsi_c_new |
631 +--------------------------------------------------------------------+
632
633 PURPOSE : allocate a partition to send a primitive
634
635 */
636
637 T_VOID_STRUCT * vsi_c_pnew_generic (T_HANDLE Caller, ULONG Size, ULONG opc, ULONG flags FILE_LINE_TYPE)
638 {
639 T_VOID_STRUCT *prim;
640
641 if ( Size < sizeof(T_PRIM_HEADER) )
642 Size = sizeof(T_PRIM_HEADER);
643
644 if ( (prim = vsi_m_new ( Size, flags FILE_LINE )) != NULL )
645 {
646 P_OPC(prim) = opc;
647 P_LEN(prim) = Size;
648 P_SDU(prim) = NULL;
649 P_CNT(prim) = 1;
650 P_SHO(prim) = 0;
651 P_DPHO(prim) = 0;
652 #ifdef MEMORY_SUPERVISION
653 Caller = e_running[os_MyHandle()];
654 vsi_ppm_new ( Caller, Size, (T_PRIM_HEADER*)prim, file, line );
655 #endif
656
657 #ifndef _TOOLS_
658 if (opc & MEMHANDLE_OPC)
659 {
660 P_MEMHANDLE_SDU(prim)=0x00000000;
661 }
662 #endif
663
664 return (T_VOID_STRUCT*)P2D(prim);
665 }
666 return NULL;
667
668 }
669 #endif
670 #ifndef RUN_FLASH
671 /*
672 +--------------------------------------------------------------------+
673 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
674 | STATE : code ROUTINE : vsi_c_pnew |
675 +--------------------------------------------------------------------+
676
677 PURPOSE : allocate a partition to send a primitive
678
679 */
680
681 T_VOID_STRUCT * vsi_c_pnew (ULONG Size, ULONG opc FILE_LINE_TYPE)
682 {
683 T_HANDLE Caller;
684
685 Caller = 0;
686
687 Size += sizeof(T_PRIM_HEADER);
688
689 return ( (T_VOID_STRUCT*)vsi_c_pnew_generic ( Caller, Size, opc, PrimGroupHandle FILE_LINE ));
690 }
691 #endif
692
693 #ifndef RUN_FLASH
694 /*
695 +--------------------------------------------------------------------+
696 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
697 | STATE : code ROUTINE : vsi_c_pnew |
698 +--------------------------------------------------------------------+
699
700 PURPOSE : allocate a partition to send a primitive
701
702 */
703
704 T_VOID_STRUCT * vsi_c_pnew_nb (ULONG Size, ULONG opc FILE_LINE_TYPE)
705 {
706 T_HANDLE Caller;
707
708 Caller = 0;
709
710 Size += sizeof(T_PRIM_HEADER);
711
712 return ( (T_VOID_STRUCT*)vsi_c_pnew_generic ( Caller, Size, opc, VSI_MEM_NON_BLOCKING|PrimGroupHandle FILE_LINE ));
713 }
714 #endif
715
716 #ifndef RUN_FLASH
717 /*
718 +---------------------------------------------------------------------+
719 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
720 | STATE : code ROUTINE : vsi_c_new_sdu_generic|
721 +---------------------------------------------------------------------+
722
723 PURPOSE : allow pool selection and flags for blocking bahavior
724
725 */
726 T_VOID_STRUCT * vsi_c_new_sdu_generic (ULONG Size, ULONG opc, USHORT sdu_len, USHORT sdu_offset, USHORT encode_offset, ULONG flags FILE_LINE_TYPE )
727 {
728 T_PRIM_HEADER *prim;
729 ULONG alloc_size;
730 T_HANDLE Caller;
731
732 Caller = 0;
733 alloc_size = Size + sizeof(T_PRIM_HEADER) + BYTELEN((SHORT)sdu_len + (SHORT)encode_offset);
734 if ( (prim = (T_PRIM_HEADER*)vsi_c_pnew_generic (Caller, alloc_size, opc, flags FILE_LINE)) != NULL )
735 {
736 D_SDU(prim) = (T_sdu*)(((char*)prim) + sdu_offset);
737 D_SDU_LEN(prim) = sdu_len;
738 D_SDU_OFF(prim) = encode_offset;
739 return ( (T_VOID_STRUCT*)prim );
740 }
741 else
742 {
743 return NULL;
744 }
745 }
746 #endif
747
748 #ifndef RUN_FLASH
749 /*
750 +--------------------------------------------------------------------+
751 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
752 | STATE : code ROUTINE : vsi_c_new_sdu |
753 +--------------------------------------------------------------------+
754
755 PURPOSE : wrapper for vsi_c_new to avoid code wasting macro
756
757 */
758 T_VOID_STRUCT * vsi_c_new_sdu (ULONG Size, ULONG opc, USHORT sdu_len, USHORT sdu_offset, USHORT encode_offset FILE_LINE_TYPE )
759 {
760 ULONG flags;
761
762 flags = PrimGroupHandle;
763
764 return vsi_c_new_sdu_generic (Size, opc, sdu_len, sdu_offset, encode_offset, flags FILE_LINE);
765 }
766 #endif
767
768 #ifndef RUN_INT_RAM
769 /*
770 +--------------------------------------------------------------------+
771 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
772 | STATE : code ROUTINE : vsi_c_ppass |
773 +--------------------------------------------------------------------+
774
775 PURPOSE : pass a partition from one primitive to another
776
777 */
778 T_VOID_STRUCT * vsi_c_ppass (T_VOID_STRUCT *prim, ULONG opc FILE_LINE_TYPE )
779 {
780 T_VOID_STRUCT *ptr;
781 ULONG len;
782 T_HANDLE Caller;
783
784 Caller = e_running[os_MyHandle()];
785 if ( D_CNT(prim) > 1 )
786 {
787 /*
788 * This does not work for dynamic primitive containing pointers, PDUP needed !!!!
789 * The sdu pointer is currently not set correctly because it is never used !!!
790 */
791 len = D_LEN(prim);
792 ptr = vsi_c_pnew ( len, opc FILE_LINE );
793 memcpy ( ptr, prim, len - sizeof(T_PRIM_HEADER) );
794 #ifdef PRIM_AUTO_FREE
795 if ( !(pf_TaskTable[Caller].Flags & PARTITION_AUTO_FREE) )
796 #endif
797 vsi_c_pfree ( &prim FILE_LINE );
798 return ptr;
799 }
800 else
801 {
802 D_OPC(prim) = opc;
803 #ifdef PRIM_AUTO_FREE
804 if ( pf_TaskTable[Caller].Flags & PARTITION_AUTO_FREE )
805 {
806 D_CNT(prim)++;
807 }
808 #endif
809 #ifdef MEMORY_SUPERVISION
810 vsi_ppm_reuse ( Caller, D2P(prim), file, line);
811 #endif
812 return prim;
813 }
814
815 }
816 #endif
817
818 #ifndef RUN_INT_RAM
819 /*
820 +--------------------------------------------------------------------+
821 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
822 | STATE : code ROUTINE : vsi_c_pstore |
823 +--------------------------------------------------------------------+
824
825 PURPOSE : store a partition (increment the reference counter)
826 consider PARTITION_AUTO_FREE
827
828 */
829 void vsi_c_pstore ( T_VOID_STRUCT *prim FILE_LINE_TYPE )
830 {
831 #ifdef PRIM_AUTO_FREE
832 T_PRIM_HEADER *ptr;
833 T_DP_HEADER *dp_hdr;
834 T_HANDLE Caller;
835
836 Caller = e_running[os_MyHandle()];
837 if ( pf_TaskTable[Caller].Flags & PARTITION_AUTO_FREE )
838 {
839 ptr = D2P(prim);
840 /* take control -> enable entity to free the prim */
841 processed_prim[Caller] = NULL;
842 /* increment reference counter */
843 D_CNT(prim)++;
844 #ifdef MEMORY_SUPERVISION
845 vsi_ppm_store ( Caller, ptr, file, line );
846 #endif
847 if ( P_DPHO(ptr) != 0 )
848 {
849 dp_hdr = (T_DP_HEADER*)((ULONG*)ptr + ptr->dph_offset);
850 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
851 while ( (ptr = (T_PRIM_HEADER*)dp_hdr) != NULL )
852 {
853 #ifdef MEMORY_SUPERVISION
854 vsi_ppm_store ( Caller, ptr, file, line );
855 #endif
856 P_CNT(ptr)++;
857 if ( dp_hdr->magic_nr != GUARD_PATTERN )
858 {
859 vsi_o_assert ( Caller, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
860 "Magic number in dp_header destroyed (PSTORE) %s , opc: 0x%lx, partition 0x%lx",
861 pf_TaskTable[Caller].Name, ptr->opc, ptr );
862 }
863 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
864 }
865 }
866 }
867 #endif /* PRIM_AUTO_FREE */
868 }
869 #endif
870
871 #ifndef RUN_INT_RAM
872 /*
873 +--------------------------------------------------------------------+
874 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
875 | STATE : code ROUTINE : vsi_c_pattach |
876 +--------------------------------------------------------------------+
877
878 PURPOSE : call internal function to store a partition (increment the reference counter)
879
880 */
881 int vsi_c_pattach ( T_VOID_STRUCT *prim FILE_LINE_TYPE )
882 {
883 T_HANDLE Caller = 0;
884 LONG sts;
885 int ret;
886
887 sts = os_ObtainSemaphore (Caller, vsi_m_sem_handle, OS_SUSPEND);
888 if ( sts == OS_ERROR || sts == OS_TIMEOUT )
889 {
890 /* Semaphore invalid or overrun */
891 Caller = e_running[os_MyHandle()];
892 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
893 "Ref Cnt Semaphore overrun, entity %s", pf_TaskTable[Caller].Name );
894 }
895
896 ret=int_vsi_c_pattach(prim FILE_LINE_MACRO);
897
898 os_ReleaseSemaphore (Caller, vsi_m_sem_handle);
899
900 return ret;
901 }
902
903 /*
904 +--------------------------------------------------------------------+
905 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
906 | STATE : code ROUTINE : int_vsi_c_pattach |
907 +--------------------------------------------------------------------+
908
909 PURPOSE : actually store a partition (increment the reference counter)
910
911 */
912 int int_vsi_c_pattach ( T_VOID_STRUCT *prim FILE_LINE_TYPE)
913 {
914 T_PRIM_HEADER *ptr;
915 T_DP_HEADER *dp_hdr;
916 T_HANDLE Caller = 0;
917 int pos;
918
919 ptr = D2P(prim);
920
921 #ifdef NU_DEBUG
922 if ( os_is_valid_partition ((T_VOID_STRUCT*)ptr) )
923 {
924 /* attach to non-partition memory */
925 Caller = e_running[os_MyHandle()];
926 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
927 "PATTACH to non-partition memory, entity %s, ptr 0x%x", pf_TaskTable[Caller].Name, ptr );
928 }
929 #endif
930
931 if ( ptr->use_cnt <= 0 )
932 {
933 /* attach to non allocated memory */
934 Caller = e_running[os_MyHandle()];
935 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
936 "PATTACH to free memory, entity %s, ptr 0x%x", pf_TaskTable[Caller].Name, ptr );
937 }
938
939 dp_hdr=NULL;
940
941 /* check if we have a primitive pointer */
942 if ( ((T_DP_HEADER*)ptr)->magic_nr != GUARD_PATTERN )
943 {
944 /* increment reference counter */
945 P_CNT(ptr)++;
946 #ifdef MEMORY_SUPERVISION
947 vsi_ppm_store ( Caller, ptr, file, line );
948 #endif
949
950 /* look for dynamic partition header */
951 if ( P_DPHO(ptr) != 0 )
952 {
953 dp_hdr = (T_DP_HEADER*)((ULONG*)ptr + ptr->dph_offset);
954 if (dp_hdr->drp_bound_list)
955 {
956 /* call attach for bound root pointers */
957 pos=0;
958 while(pos<MAX_DRP_BOUND && dp_hdr->drp_bound_list[pos])
959 {
960 int_vsi_c_pattach(dp_hdr->drp_bound_list[pos] FILE_LINE_MACRO);
961 pos++;
962 }
963 }
964
965 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
966 }
967 }
968 else
969 {
970 dp_hdr=(T_DP_HEADER*)ptr;
971 }
972
973 if ( dp_hdr )
974 {
975 if ( dp_hdr->magic_nr != GUARD_PATTERN )
976 {
977 /* primitive with T_desc_list element, use MATTACH */
978 os_ReleaseSemaphore (Caller, vsi_m_sem_handle);
979 return VSI_OK;
980 }
981 else
982 {
983 while ( (ptr = (T_PRIM_HEADER*)dp_hdr) != NULL )
984 {
985 #ifdef MEMORY_SUPERVISION
986 vsi_ppm_store ( Caller, ptr, file, line );
987 #endif
988 P_CNT(ptr)++;
989 if ( dp_hdr->magic_nr != GUARD_PATTERN )
990 {
991 vsi_o_assert ( Caller, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
992 "Magic number in dp_header destroyed (PATTACH), %s, opc: 0x%lx, partition 0x%lx",
993 pf_TaskTable[Caller].Name, ptr->opc, ptr );
994 }
995
996 if (dp_hdr->drp_bound_list)
997 {
998 /* call attach for bound root pointers */
999 pos=0;
1000 while(pos<MAX_DRP_BOUND && dp_hdr->drp_bound_list[pos])
1001 {
1002 int_vsi_c_pattach(dp_hdr->drp_bound_list[pos] FILE_LINE_MACRO);
1003 pos++;
1004 }
1005 }
1006 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
1007 }
1008 }
1009 }
1010 return VSI_OK;
1011 }
1012 #endif
1013
1014 #ifndef RUN_INT_RAM
1015 /*
1016 +--------------------------------------------------------------------+
1017 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1018 | STATE : code ROUTINE : vsi_c_reuse |
1019 +--------------------------------------------------------------------+
1020
1021 PURPOSE : function to avoid code wasting macro
1022
1023 */
1024 T_VOID_STRUCT *vsi_c_reuse ( T_PRIM_HEADER *ptr, ULONG Size, ULONG opc,
1025 USHORT sdu_len, USHORT sdu_offset, USHORT encode_offset FILE_LINE_TYPE )
1026 {
1027 T_HANDLE Caller;
1028
1029 D_OPC(ptr) = opc;
1030 D_LEN(ptr) = Size;
1031 if ( sdu_offset != NO_SDU )
1032 {
1033 D_SDU(ptr) = (T_sdu*)((char*)(ptr) + sdu_offset);
1034 D_SDU_LEN(ptr) = sdu_len;
1035 D_SDU_OFF(ptr) = encode_offset;
1036 }
1037 else
1038 D_SDU(ptr) = NULL;
1039
1040 Caller = e_running[os_MyHandle()];
1041 #ifdef MEMORY_SUPERVISION
1042 vsi_ppm_reuse ( Caller, D2P(ptr), file, line);
1043 #endif
1044 #ifdef PRIM_AUTO_FREE
1045 if ( pf_TaskTable[Caller].Flags & PARTITION_AUTO_FREE )
1046 {
1047 D_CNT(ptr)++;
1048 }
1049 #endif
1050 return ( (T_VOID_STRUCT*)ptr );
1051 }
1052 #endif
1053
1054 #ifndef RUN_FLASH
1055 /*
1056 +--------------------------------------------------------------------+
1057 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1058 | STATE : code ROUTINE : vsi_c_free |
1059 +--------------------------------------------------------------------+
1060
1061 PURPOSE : deallocate a partition that was used to send a primitive
1062
1063 */
1064
1065 int vsi_c_free (T_HANDLE Caller, T_VOID_STRUCT **Msg FILE_LINE_TYPE)
1066 {
1067 static T_VOID_STRUCT *protected_prim_to_free = NULL;
1068 #if defined (NU_DEBUG) || defined (OSL_DEBUG)
1069 LONG count;
1070 #endif
1071
1072 //LONG sts;
1073
1074 #if 0
1075 sts = os_ObtainSemaphore (Caller, vsi_m_sem_handle, OS_SUSPEND);
1076 if ( sts == OS_ERROR || sts == OS_TIMEOUT )
1077 {
1078 /* Semaphore invalid or overrun */
1079 if ( *Msg == protected_prim_to_free )
1080 {
1081 /* fatal error only if semaphore overrun on same primitive */
1082 Caller = e_running[os_MyHandle()];
1083 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
1084 "Ref Cnt Semaphore overrun, entity %s", pf_TaskTable[Caller].Name );
1085 return VSI_ERROR;
1086 }
1087 }
1088 else
1089 #endif
1090 {
1091 protected_prim_to_free = *Msg;
1092 }
1093 #if defined (NU_DEBUG) || defined (OSL_DEBUG)
1094 count = (LONG)((T_PRIM_HEADER*)*Msg)->use_cnt;
1095 if ( count <= 0 )
1096 {
1097 pf_handle_warning ( OS_SYST_WRN_MULTIPLE_FREE, "%s %s in %s, 0x%x, %s(%d)",
1098 syst_wrn, freed_str, pf_TaskTable[Caller].Name, P_OPC(*Msg) FILE_LINE_MACRO_PASSED );
1099 protected_prim_to_free = NULL;
1100 // os_ReleaseSemaphore (Caller, vsi_m_sem_handle);
1101 return VSI_OK;
1102 }
1103 #endif
1104 if ( --((T_PRIM_HEADER*)*Msg)->use_cnt == 0 )
1105 {
1106 #ifdef PRIM_AUTO_FREE
1107 if ( pf_TaskTable[Caller].Flags & PARTITION_AUTO_FREE )
1108 freed_prim[Caller] = *Msg;
1109 #endif
1110 #ifdef _NUCLEUS_
1111 #ifdef NU_DEBUG
1112
1113 if ( os_PartitionCheck( (ULONG*)*Msg ) == OS_PARTITION_GUARD_PATTERN_DESTROYED )
1114 {
1115 // os_ReleaseSemaphore (Caller, vsi_m_sem_handle);
1116 vsi_o_assert ( Caller, OS_SYST_ERR_PCB_PATTERN FILE_LINE_MACRO_PASSED,
1117 "%s (PFREE), entity %s,Partition 0x%x",
1118 guard_str, pf_TaskTable[Caller].Name, *Msg );
1119 return VSI_ERROR;
1120 }
1121 #endif
1122 #endif
1123 protected_prim_to_free = NULL;
1124 // os_ReleaseSemaphore (Caller, vsi_m_sem_handle);
1125 return ( vsi_m_free ( Msg FILE_LINE ) );
1126 }
1127
1128 protected_prim_to_free = NULL;
1129 // os_ReleaseSemaphore (Caller, vsi_m_sem_handle);
1130 return VSI_OK;
1131 }
1132 #endif
1133
1134 #ifndef RUN_FLASH
1135 /*
1136 +--------------------------------------------------------------------+
1137 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1138 | STATE : code ROUTINE : vsi_c_pfree |
1139 +--------------------------------------------------------------------+
1140
1141 PURPOSE : deallocate a partition that was used to send a primitive
1142
1143 */
1144
1145 int vsi_c_pfree (T_VOID_STRUCT **Msg FILE_LINE_TYPE)
1146 {
1147 T_VOID_STRUCT *free_ptr;
1148 T_HANDLE Caller;
1149
1150 /*
1151 * PFREE is disabled if the primitive to be freed is the currently
1152 * processed one and the auto free is enabled for the calling entity
1153 */
1154
1155 Caller = e_running[os_MyHandle()];
1156 free_ptr = (T_VOID_STRUCT*)D2P(*Msg);
1157 #ifdef NU_DEBUG
1158 if ( os_is_valid_partition ((T_VOID_STRUCT*)free_ptr) )
1159 {
1160 /* free to non-partition memory */
1161 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
1162 "PFREE to non-partition memory, entity %s, prim 0x%x", pf_TaskTable[Caller].Name, *Msg );
1163 }
1164 #endif
1165 #ifdef PRIM_AUTO_FREE
1166 if ( free_ptr == processed_prim[Caller] && pf_TaskTable[Caller].Flags & PARTITION_AUTO_FREE )
1167 {
1168 return VSI_OK;
1169 }
1170 #endif /* PRIM_AUTO_FREE */
1171 return ( vsi_c_free ( Caller, &free_ptr FILE_LINE ) );
1172 }
1173 #endif
1174
1175 #ifndef RUN_FLASH
1176 /*
1177 +--------------------------------------------------------------------+
1178 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1179 | STATE : code ROUTINE : vsi_c_await |
1180 +--------------------------------------------------------------------+
1181
1182 PURPOSE : receive a primitive
1183
1184 */
1185
1186 int vsi_c_await (T_HANDLE Caller, T_HANDLE ComHandle, T_QMSG *Msg, ULONG Timeout)
1187 {
1188 OS_QDATA OS_Msg;
1189 LONG ret;
1190 OS_HANDLE q_handle;
1191
1192
1193 #ifdef _TOOLS_
1194 q_handle = ComHandle;
1195 #else
1196 q_handle = pf_TaskTable[ComHandle].QueueHandle;
1197 #endif
1198 e_running[os_MyHandle()] = 0;
1199
1200 if ( (ret = os_ReceiveFromQueue ( Caller, q_handle, &OS_Msg, Timeout)) == OS_OK )
1201 {
1202 Msg->MsgType = OS_Msg.data16;
1203 switch ( Msg->MsgType )
1204 {
1205 case MSG_PRIMITIVE:
1206 Msg->Msg.Primitive.Prim = OS_Msg.ptr;
1207 #ifdef _TOOLS_
1208 Msg->Msg.Primitive.PrimLen = OS_Msg.len;
1209 #endif
1210 vsi_o_ptrace (Caller, ((T_PRIM_HEADER*)Msg->Msg.Primitive.Prim)->opc, 0);
1211 break;
1212 case MSG_SIGNAL:
1213 Msg->Msg.Signal.SigBuffer = OS_Msg.ptr;
1214 Msg->Msg.Signal.SigOPC = OS_Msg.data32;
1215 #ifdef _TOOLS_
1216 Msg->Msg.Signal.SigLen = OS_Msg.len;
1217 #endif
1218 break;
1219 case MSG_TIMEOUT:
1220 if ( *(pf_TaskTable[Caller].FirstTimerEntry + OS_Msg.data32) & TIMEOUT_OCCURRED )
1221 {
1222 if ( !(*(pf_TaskTable[Caller].FirstTimerEntry + OS_Msg.data32) & PERIODIC_TIMER) )
1223 {
1224 os_DestroyTimer ( Caller, (OS_HANDLE)(*(pf_TaskTable[Caller].FirstTimerEntry + OS_Msg.data32) & TIMER_HANDLE_MASK) );
1225 *(pf_TaskTable[Caller].FirstTimerEntry + OS_Msg.data32) = 0;
1226 }
1227 else
1228 {
1229 *(pf_TaskTable[Caller].FirstTimerEntry + OS_Msg.data32) &= ~TIMEOUT_OCCURRED;
1230 }
1231 Msg->Msg.Timer.Index = OS_Msg.data32;
1232 }
1233 break;
1234 default: return VSI_ERROR;
1235 /*lint -e527 suppress Warning -- Unreachable */
1236 break;
1237 /*lint +e527 */
1238 }
1239 e_running[os_MyHandle()] = Caller;
1240 prf_log_entity_activate ((void*)Caller);
1241 return VSI_OK;
1242 }
1243 else
1244 {
1245 if ( ret == OS_TIMEOUT )
1246 {
1247 e_running[os_MyHandle()] = Caller;
1248 return VSI_TIMEOUT;
1249 }
1250 }
1251 return VSI_ERROR;
1252 }
1253 #endif
1254
1255 #ifndef RUN_INT_RAM
1256 /*
1257 +--------------------------------------------------------------------+
1258 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1259 | STATE : code ROUTINE : vsi_c_primitive |
1260 +--------------------------------------------------------------------+
1261
1262 PURPOSE : send a non GSM primitive to the frame
1263
1264 */
1265
1266 int vsi_c_primitive (T_HANDLE Caller, void *Msg)
1267 {
1268 /*
1269 * the following line of code causes a warning on tms470 compiler, that cannot be avoided
1270 * without changing all entities PEI modules. Warning will not cause a problem
1271 */
1272 pf_ProcessSystemPrim ( Caller, Msg );
1273 return VSI_OK;
1274
1275 }
1276 #endif
1277
1278 #ifndef RUN_INT_RAM
1279 /*
1280 +--------------------------------------------------------------------+
1281 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1282 | STATE : code ROUTINE : vsi_c_awake |
1283 +--------------------------------------------------------------------+
1284
1285 PURPOSE : send NULL primitive to itself
1286
1287 */
1288 GLOBAL int vsi_c_awake ( T_HANDLE caller )
1289 {
1290 OS_QDATA QMsg = { 0 };
1291
1292 QMsg.data16 = MSG_PRIMITIVE;
1293 QMsg.ptr = NULL;
1294 os_SendToQueue ( caller, caller, OS_URGENT, OS_NO_SUSPEND, &QMsg );
1295 return VSI_OK;
1296 }
1297 #endif
1298
1299 #ifndef RUN_INT_RAM
1300 /*
1301 +--------------------------------------------------------------------+
1302 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1303 | STATE : code ROUTINE : vsi_c_status |
1304 +--------------------------------------------------------------------+
1305
1306 PURPOSE : allocate root of dynamic sized primitive
1307
1308 */
1309 int vsi_c_status (T_HANDLE handle, unsigned int *used, unsigned int *free)
1310 {
1311 #ifdef _NUCLEUS_
1312 int status;
1313
1314 if ( (status = os_GetQueueState (0, pf_TaskTable[handle].QueueHandle, (ULONG*)used, (ULONG*)free)) == OS_OK )
1315 return OS_OK;
1316 else
1317 #endif
1318 return OS_ERROR;
1319
1320 }
1321 #endif
1322
1323 #ifndef RUN_INT_RAM
1324 /*
1325 +--------------------------------------------------------------------+
1326 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1327 | STATE : code ROUTINE : vsi_drpo_new |
1328 +--------------------------------------------------------------------+
1329
1330 PURPOSE : allocate root of dynamic sized primitive
1331
1332 */
1333 GLOBAL T_VOID_STRUCT *vsi_drpo_new ( ULONG size, ULONG opc, ULONG guess FILE_LINE_TYPE )
1334 {
1335 T_PRIM_HEADER *prim;
1336 T_DP_HEADER *dp_hdr;
1337 T_S_HEADER *s_hdr;
1338 ULONG alloc_size;
1339 ULONG partition_size;
1340 ULONG header_size;
1341 T_HANDLE caller;
1342
1343 caller = e_running[os_MyHandle()];
1344
1345 header_size = sizeof(T_PRIM_HEADER) + sizeof(T_DP_HEADER);
1346
1347 if ( ALIGN(header_size + size) > MaxPrimPartSize )
1348 {
1349 os_GetTaskName ( caller, caller, TaskName );
1350 vsi_o_assert ( NO_TASK, OS_SYST_ERR_BIG_PARTITION FILE_LINE_MACRO_PASSED,
1351 "No Partition available, entity %s, size %d", pf_TaskTable[caller].Name, size );
1352 return NULL;
1353 }
1354
1355 if ( guess == DP_NO_FRAME_GUESS )
1356 alloc_size = ALIGN(header_size + size);
1357 else if ( guess == DP_FRAME_GUESS )
1358 alloc_size = ALIGN(header_size + size * 3);
1359 else
1360 alloc_size = ALIGN(header_size + guess + size);
1361
1362 if ( caller != 0 && caller == TST_Handle )
1363 {
1364 /*
1365 if called by PCON in the test interface while decoding we need to reserve
1366 space for the S_HEADER
1367 */
1368 alloc_size += sizeof(T_S_HEADER);
1369 }
1370
1371 if ( alloc_size > MaxPrimPartSize )
1372 {
1373 #ifdef NU_DEBUG
1374 pf_handle_warning ( OS_SYST_WRN_REQ_TRUNCATED, "%s %s (%d->%d), entity %s, opc 0x%x, %s(%d)",
1375 syst_wrn, trunc_str, alloc_size, MaxPrimPartSize, pf_TaskTable[caller].Name, opc FILE_LINE_MACRO_PASSED );
1376 #endif
1377 alloc_size = MaxPrimPartSize;
1378 }
1379 if ( ( prim = (T_PRIM_HEADER*)vsi_m_new_size ( alloc_size, PrimGroupHandle,
1380 &partition_size FILE_LINE ) ) != NULL )
1381 {
1382 #ifdef MEMORY_SUPERVISION
1383 vsi_ppm_new ( caller, alloc_size, (T_PRIM_HEADER*)prim, file, line );
1384 #endif
1385 prim->len = partition_size; /* complete partition because header is at the end */
1386 prim->opc = opc;
1387 prim->sdu = NULL;
1388 prim->use_cnt = 1;
1389 prim->sh_offset = 0;
1390 prim->dph_offset = D_HDR_OFFSET(partition_size);
1391 dp_hdr = (T_DP_HEADER*)((ULONG*)prim + prim->dph_offset);
1392 dp_hdr->magic_nr = GUARD_PATTERN;
1393 dp_hdr->drp_bound_list = NULL;
1394 dp_hdr->next = NULL;
1395 dp_hdr->offset = sizeof(T_PRIM_HEADER) + ALIGN(size);
1396 dp_hdr->size = partition_size - sizeof(T_DP_HEADER);
1397 if ( dp_hdr->offset > dp_hdr->size )
1398 {
1399 dp_hdr->offset = dp_hdr->size;
1400 }
1401 /*
1402 * The following code does not work since the 'caller' parameter has been removed from the function
1403 * prototype. The code was needed for the case where the function was called by PCON when decoding a
1404 * received primitive in the test interface. The caller in this case is 0 because it is either the
1405 * RCV_HISR on the target or the EXTR task in the simulation which is not running in the context of
1406 * the frame. Currently the sh_offset is set in the TIF driver tif.c although the guard pattern is not
1407 * set there. This is working fine so there is no reason to modify the code here. This comment
1408 * is just the result of some brainstorming and can be used for future modifications
1409 */
1410 if ( caller != 0 && caller == TST_Handle ) /* called by PCON */
1411 {
1412 prim->sh_offset = prim->dph_offset - sizeof(T_S_HEADER);
1413 dp_hdr->size = dp_hdr->size - sizeof(T_S_HEADER);
1414 s_hdr = (T_S_HEADER*)((ULONG*)prim + prim->sh_offset);
1415 s_hdr->magic_nr = GUARD_PATTERN;
1416 }
1417 else
1418 prim->sh_offset = 0;
1419 return ((T_VOID_STRUCT*)P2D(prim));
1420 }
1421 return NULL;
1422 }
1423 #endif
1424
1425 #ifndef RUN_INT_RAM
1426 /*
1427 +--------------------------------------------------------------------+
1428 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1429 | STATE : code ROUTINE : vsi_drpo_new_sdu |
1430 +--------------------------------------------------------------------+
1431
1432 PURPOSE : allocate dynamic sized partition root
1433
1434 */
1435
1436 T_VOID_STRUCT * vsi_drpo_new_sdu (ULONG Size, ULONG opc, USHORT sdu_len,
1437 USHORT sdu_offset, USHORT encode_offset, ULONG guess FILE_LINE_TYPE )
1438 {
1439 T_VOID_STRUCT *ptr;
1440 ULONG alloc_size;
1441 T_HANDLE Caller;
1442
1443 Caller = 0;
1444 alloc_size = Size + BYTELEN((SHORT)sdu_len + (SHORT)encode_offset);
1445 ptr = vsi_drpo_new ( alloc_size, opc, guess FILE_LINE );
1446 /*
1447 * the following line of code causes a warning on tms470 compiler,
1448 * that cannot be avoided. Warning will not cause a problem because due to the
1449 * arm7 alignment it is guaranteed that the sdu will start at an address divisable
1450 * by 4.
1451 */
1452 D_SDU(ptr) = (T_sdu*)((char*)ptr + sdu_offset);
1453 D_SDU_LEN(ptr) = sdu_len;
1454 D_SDU_OFF(ptr) = encode_offset;
1455
1456 return ( (T_VOID_STRUCT*)ptr );
1457 }
1458 #endif
1459
1460 #ifndef RUN_INT_RAM
1461 /*
1462 +--------------------------------------------------------------------+
1463 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1464 | STATE : code ROUTINE : vsi_drp_bind |
1465 +--------------------------------------------------------------------+
1466
1467 PURPOSE : bind child root pointer to a given parent root pointer
1468
1469 */
1470 GLOBAL int vsi_drp_bind (T_VOID_STRUCT *child, T_VOID_STRUCT *parent FILE_LINE_TYPE)
1471 {
1472 T_PRIM_HEADER *prim;
1473 T_DP_HEADER *dp_hdr;
1474 T_VOID_STRUCT **new_drp_bound_list;
1475 ULONG alloc_size;
1476 T_HANDLE caller;
1477 int pos;
1478
1479 caller = e_running[os_MyHandle()];
1480
1481 prim = D2P(parent);
1482 if ( ((T_DP_HEADER*)prim)->magic_nr == GUARD_PATTERN )
1483 {
1484 dp_hdr = (T_DP_HEADER*)prim;
1485 }
1486 else
1487 {
1488 dp_hdr = (T_DP_HEADER*)((ULONG*)prim + prim->dph_offset);
1489 }
1490
1491 if (dp_hdr->drp_bound_list == NULL)
1492 {
1493 /* no partitions bound so far */
1494 alloc_size=MAX_DRP_BOUND*sizeof(T_DP_HEADER*);
1495 if ( ( new_drp_bound_list = (T_VOID_STRUCT**)M_ALLOC (alloc_size) ) == NULL )
1496 {
1497 /* no more memory */
1498 return VSI_ERROR;
1499 }
1500
1501 memset(new_drp_bound_list,0x00,alloc_size);
1502 dp_hdr->drp_bound_list=new_drp_bound_list;
1503 }
1504
1505 /* find free bind pointer */
1506 pos=0;
1507 while(pos<MAX_DRP_BOUND && dp_hdr->drp_bound_list[pos])
1508 {
1509 pos++;
1510 }
1511 if (pos == MAX_DRP_BOUND)
1512 {
1513 /* no more free bound pointers */
1514 return VSI_ERROR;
1515 }
1516
1517 /* actually bind */
1518 P_ATTACH(child);
1519 dp_hdr->drp_bound_list[pos]=child;
1520
1521 return VSI_OK;
1522 }
1523
1524 /*
1525 +--------------------------------------------------------------------+
1526 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1527 | STATE : code ROUTINE : vsi_dp_new |
1528 +--------------------------------------------------------------------+
1529
1530 PURPOSE : allocate dynamic sized partition root
1531
1532 */
1533 GLOBAL T_VOID_STRUCT *vsi_dp_new ( ULONG size, T_VOID_STRUCT *addr, ULONG guess FILE_LINE_TYPE )
1534 {
1535 T_PRIM_HEADER *prim;
1536 T_PRIM_HEADER *last_in_chain;
1537 T_PRIM_HEADER *dyn_ptr;
1538 T_DP_HEADER *dp_hdr;
1539 T_DP_HEADER *new_prim;
1540 T_VOID_STRUCT *ptr;
1541 ULONG partition_size;
1542 ULONG alloc_size;
1543 //ULONG estimated_size;
1544 T_HANDLE caller;
1545 char is_opc_root;
1546
1547 if ( size + sizeof(T_DP_HEADER) > MaxPrimPartSize )
1548 {
1549 caller = e_running[os_MyHandle()];
1550 vsi_o_assert ( NO_TASK, OS_SYST_ERR_BIG_PARTITION FILE_LINE_MACRO_PASSED,
1551 "No Partition available, entity %s, size %d", pf_TaskTable[caller].Name, size );
1552 return NULL;
1553 }
1554 prim = D2P(addr);
1555 dyn_ptr = prim;
1556 if ( ((T_DP_HEADER*)prim)->magic_nr == GUARD_PATTERN )
1557 {
1558 dp_hdr = (T_DP_HEADER*)prim;
1559 is_opc_root = 0;
1560 }
1561 else
1562 {
1563 dp_hdr = (T_DP_HEADER*)((ULONG*)prim + prim->dph_offset);
1564 is_opc_root = 1;
1565 }
1566
1567 if ( guess == DP_NO_FRAME_GUESS )
1568 alloc_size = size + sizeof(T_DP_HEADER);
1569 else if ( guess == DP_FRAME_GUESS )
1570 alloc_size = size * 3 + sizeof(T_DP_HEADER);
1571 else
1572 alloc_size = size + guess + sizeof(T_DP_HEADER);
1573
1574 #if 0
1575 /*
1576 * update estimated size
1577 */
1578 estimated_size = dp_hdr->est_size;
1579
1580 if ( guess != DP_NO_FRAME_GUESS && guess != DP_FRAME_GUESS )
1581 {
1582 estimated_size = size + guess;
1583 alloc_size = estimated_size + sizeof(T_DP_HEADER);
1584 estimated_size -= size;
1585 }
1586 else
1587 {
1588 if ( size > estimated_size )
1589 {
1590 if ( guess == DP_FRAME_GUESS )
1591 estimated_size = size * 3;
1592 else
1593 estimated_size = size;
1594 }
1595 estimated_size -= size;
1596 if ( size > estimated_size )
1597 estimated_size = size * 2;
1598 alloc_size = estimated_size + sizeof(T_DP_HEADER);
1599 }
1600
1601 if ( estimated_size > MaxPrimPartSize )
1602 estimated_size = MaxPrimPartSize;
1603
1604 dp_hdr->est_size = estimated_size;
1605 #endif
1606 /*
1607 * check if free space in already allocated blocks (first fit)
1608 */
1609 do
1610 {
1611 if ( dp_hdr->magic_nr != GUARD_PATTERN )
1612 {
1613 caller = e_running[os_MyHandle()];
1614 vsi_o_assert ( caller, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
1615 "Magic number in dp_header destroyed (DP_ALLOC), %s opc: 0x%lx, partition 0x%lx",
1616 pf_TaskTable[caller].Name, ((T_PRIM_HEADER*)prim)->opc, prim );
1617 }
1618 if ( dp_hdr->size - dp_hdr->offset > size )
1619 {
1620 /*
1621 * if root was allocated with drpo_alloc then dp header is at the end,
1622 * the dph offset is not 0 and a primitive header is present.
1623 */
1624 if ( is_opc_root && dyn_ptr == prim )
1625 ptr = (T_VOID_STRUCT*)(((ULONG*)prim) + (dp_hdr->offset>>2));
1626 else
1627 ptr = (T_VOID_STRUCT*)(((ULONG*)dp_hdr) + (dp_hdr->offset>>2));
1628 dp_hdr->offset += ALIGN(size);
1629 return ( ptr );
1630 }
1631 if ( is_opc_root && dyn_ptr == prim )
1632 last_in_chain = prim;
1633 else
1634 last_in_chain = (T_PRIM_HEADER*)dp_hdr;
1635 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
1636 dyn_ptr = (T_PRIM_HEADER*)dp_hdr;
1637 } while ( dp_hdr );
1638
1639 /*
1640 * not enough free space -> additional allocation needed
1641 */
1642 if ( alloc_size > MaxPrimPartSize )
1643 {
1644 #ifdef NU_DEBUG
1645 caller = e_running[os_MyHandle()];
1646 pf_handle_warning ( OS_SYST_WRN_REQ_TRUNCATED, "%s %s (%d->%d), entity %s, %s(%d)",
1647 syst_wrn, trunc_str, alloc_size, MaxPrimPartSize, pf_TaskTable[caller].Name FILE_LINE_MACRO_PASSED );
1648 #endif
1649 alloc_size = MaxPrimPartSize;
1650 }
1651
1652 if ( ( new_prim = (T_DP_HEADER*)vsi_m_new_size ( alloc_size, PrimGroupHandle,
1653 &partition_size FILE_LINE ) ) != NULL )
1654 {
1655 #ifdef MEMORY_SUPERVISION
1656 caller = e_running[os_MyHandle()];
1657 vsi_ppm_new ( caller, alloc_size, (T_PRIM_HEADER*)new_prim, file, line );
1658 #endif
1659 if ( ((T_DP_HEADER*)last_in_chain)->magic_nr == GUARD_PATTERN )
1660 dp_hdr = (T_DP_HEADER*)last_in_chain;
1661 else
1662 dp_hdr = (T_DP_HEADER*)((ULONG*)last_in_chain + last_in_chain->dph_offset);
1663 dp_hdr->next = new_prim;
1664 new_prim->magic_nr = GUARD_PATTERN;
1665 new_prim->drp_bound_list = NULL;
1666 new_prim->use_cnt = 1;
1667 new_prim->next = NULL;
1668 new_prim->size = partition_size;
1669 new_prim->offset = sizeof(T_DP_HEADER) + ALIGN(size);
1670 if ( new_prim->offset > new_prim->size )
1671 {
1672 new_prim->offset = new_prim->size;
1673 }
1674 return (T_VOID_STRUCT*)(new_prim + 1);
1675 }
1676
1677 return NULL;
1678 }
1679 #endif
1680
1681 #ifndef RUN_INT_RAM
1682 /*
1683 +--------------------------------------------------------------------+
1684 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1685 | STATE : code ROUTINE : vsi_c_drp_new |
1686 +--------------------------------------------------------------------+
1687
1688 PURPOSE : allocate dynamic sized partition except root
1689
1690 */
1691 GLOBAL T_VOID_STRUCT *vsi_drp_new ( ULONG size, ULONG guess FILE_LINE_TYPE )
1692 {
1693 T_PRIM_HEADER *prim;
1694 T_DP_HEADER *dp_hdr;
1695 ULONG alloc_size;
1696 ULONG header_size;
1697 ULONG partition_size;
1698 T_HANDLE caller;
1699
1700 header_size = sizeof(T_DP_HEADER);
1701
1702 if ( ALIGN(header_size + size) > MaxPrimPartSize )
1703 {
1704 caller = e_running[os_MyHandle()];
1705 os_GetTaskName ( caller, caller, TaskName );
1706 vsi_o_assert ( NO_TASK, OS_SYST_ERR_BIG_PARTITION FILE_LINE_MACRO_PASSED,
1707 "No Partition available, entity %s, size %d", pf_TaskTable[caller].Name, size );
1708 return NULL;
1709 }
1710
1711 if ( guess == DP_NO_FRAME_GUESS )
1712 alloc_size = header_size + size;
1713 else if ( guess == DP_FRAME_GUESS )
1714 alloc_size = header_size + size * 3;
1715 else
1716 alloc_size = header_size + guess + size;
1717
1718 if ( alloc_size > MaxPrimPartSize )
1719 {
1720 #ifdef NU_DEBUG
1721 caller = e_running[os_MyHandle()];
1722 pf_handle_warning ( OS_SYST_WRN_REQ_TRUNCATED, "%s %s (%d->%d), entity %s, %s(%d)",
1723 syst_wrn, trunc_str, alloc_size, MaxPrimPartSize, pf_TaskTable[caller].Name FILE_LINE_MACRO_PASSED );
1724 #endif
1725 alloc_size = MaxPrimPartSize;
1726 }
1727
1728 if ( ( prim = (T_PRIM_HEADER*)vsi_m_new_size ( alloc_size, PrimGroupHandle,
1729 &partition_size FILE_LINE ) ) != NULL )
1730 {
1731 #ifdef MEMORY_SUPERVISION
1732 caller = e_running[os_MyHandle()];
1733 vsi_ppm_new ( caller, alloc_size, (T_PRIM_HEADER*)prim, file, line );
1734 #endif
1735 dp_hdr = (T_DP_HEADER*)prim;
1736 dp_hdr->next = NULL;
1737 dp_hdr->magic_nr = GUARD_PATTERN;
1738 dp_hdr->drp_bound_list = NULL;
1739 dp_hdr->use_cnt = 1;
1740 dp_hdr->offset = sizeof(T_DP_HEADER) + ALIGN(size);
1741 dp_hdr->size = partition_size;
1742 if ( dp_hdr->offset > dp_hdr->size )
1743 {
1744 dp_hdr->offset = dp_hdr->size;
1745 }
1746 return (T_VOID_STRUCT*)(dp_hdr+1);
1747 }
1748
1749 return NULL;
1750 }
1751 #endif
1752
1753 #ifndef RUN_INT_RAM
1754 /*
1755 +--------------------------------------------------------------------+
1756 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1757 | STATE : code ROUTINE : vsi_free |
1758 +--------------------------------------------------------------------+
1759
1760 PURPOSE : deallocate a chain of linked partitions
1761
1762 */
1763
1764 int vsi_free ( T_VOID_STRUCT **Msg FILE_LINE_TYPE )
1765 {
1766 T_PRIM_HEADER *prim;
1767 T_DP_HEADER *dp_hdr;
1768 T_VOID_STRUCT** drp_bound_list;
1769 T_HANDLE Caller = 0;
1770 int pos;
1771
1772 /*
1773 * PFREE is disabled if the primitive to be freed is the currently
1774 * processed one and the auto free is enabled for the calling entity
1775 */
1776
1777 Caller = e_running[os_MyHandle()];
1778
1779 prim = D2P(*Msg);
1780
1781 #ifdef NU_DEBUG
1782 if ( os_is_valid_partition ((T_VOID_STRUCT*)prim) )
1783 {
1784 /* free to non-partition memory */
1785 Caller = e_running[os_MyHandle()];
1786 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
1787 "FREE to non-partition memory, entity %s, prim 0x%x", pf_TaskTable[Caller].Name, *Msg );
1788 }
1789 #endif
1790
1791 #ifdef PRIM_AUTO_FREE
1792 if ( prim == (T_PRIM_HEADER*)processed_prim[Caller] && pf_TaskTable[Caller].Flags & PARTITION_AUTO_FREE )
1793 {
1794 return VSI_OK;
1795 }
1796 #endif /* PRIM_AUTO_FREE */
1797
1798 /* check if we have dynamic partition or primitive */
1799 if ( ((T_DP_HEADER*)prim)->magic_nr == GUARD_PATTERN )
1800 {
1801 dp_hdr = (T_DP_HEADER*)prim;
1802 }
1803 else if ( prim->dph_offset != 0 )
1804 {
1805 dp_hdr = (T_DP_HEADER*)((ULONG*)prim + prim->dph_offset);
1806 }
1807 else
1808 {
1809 return ( vsi_c_free ( Caller, (T_VOID_STRUCT**)&prim FILE_LINE ) );
1810 }
1811
1812 if ( dp_hdr->magic_nr != GUARD_PATTERN )
1813 {
1814 /* primitive with T_desc_list element */
1815 vsi_c_free ( Caller, (T_VOID_STRUCT**)&prim FILE_LINE );
1816 return VSI_OK;
1817 }
1818 else
1819 {
1820 do
1821 {
1822 drp_bound_list=dp_hdr->drp_bound_list;
1823 if (drp_bound_list)
1824 {
1825 /* call free for bound root pointers */
1826 pos=0;
1827 while(pos<MAX_DRP_BOUND && drp_bound_list[pos])
1828 {
1829 FREE(drp_bound_list[pos]);
1830 pos++;
1831 }
1832 }
1833
1834 /* free linked memory */
1835 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
1836 vsi_c_free ( Caller, (T_VOID_STRUCT**)&prim FILE_LINE );
1837
1838 if (prim == NULL && drp_bound_list)
1839 {
1840 /* free drp_bound_list */
1841 M_FREE(drp_bound_list);
1842 }
1843 } while ( (prim = (T_PRIM_HEADER*)dp_hdr) != NULL );
1844 }
1845 return VSI_OK;
1846 }
1847 #endif
1848
1849 #ifndef RUN_INT_RAM
1850 /*
1851 +--------------------------------------------------------------------+
1852 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1853 | STATE : code ROUTINE : vsi_d_sum |
1854 +--------------------------------------------------------------------+
1855
1856 PURPOSE : get number of bytes in dynamic sized primitive
1857
1858 */
1859 GLOBAL int vsi_dp_sum ( T_VOID_STRUCT *addr, ULONG *bytes )
1860 {
1861 T_PRIM_HEADER *prim;
1862 T_DP_HEADER *dp_hdr;
1863 ULONG size;
1864 T_HANDLE caller;
1865
1866 prim = D2P(addr);
1867 if ( ((T_DP_HEADER*)prim)->magic_nr == GUARD_PATTERN )
1868 dp_hdr = (T_DP_HEADER*)prim;
1869 else if ( prim->dph_offset != 0 )
1870 dp_hdr = (T_DP_HEADER*)((ULONG*)prim + prim->dph_offset);
1871 else
1872 {
1873 caller = e_running[os_MyHandle()];
1874 vsi_o_ttrace ( NO_TASK, TC_SYSTEM, "SYSTEM WARNING: No root of linked memory in %s",
1875 pf_TaskTable[caller].Name );
1876 return VSI_ERROR;
1877 }
1878
1879 size = 0;
1880 do
1881 {
1882 if ( dp_hdr->magic_nr != GUARD_PATTERN )
1883 {
1884 caller = e_running[os_MyHandle()];
1885 vsi_o_assert ( caller, OS_SYST_ERR, __FILE__, __LINE__,
1886 "Magic number in dp_header destroyed, opc: 0x%lx, partition 0x%lx",
1887 prim->opc, prim );
1888 }
1889 size += (dp_hdr->offset-sizeof(T_DP_HEADER));
1890 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
1891 } while ( (prim = (T_PRIM_HEADER*)dp_hdr) != NULL );
1892
1893 *bytes = size;
1894 return VSI_OK;
1895 }
1896 #endif
1897
1898 #ifndef RUN_INT_RAM
1899 /*
1900 +--------------------------------------------------------------------+
1901 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1902 | STATE : code ROUTINE : vsi_dp_max_size |
1903 +--------------------------------------------------------------------+
1904
1905 PURPOSE : get maximum number of bytes available for user data
1906 in dynamic primitive
1907
1908 */
1909 GLOBAL int vsi_dp_max_size ( void )
1910 {
1911 return ( (int)(MaxPrimPartSize - sizeof(T_PRIM_HEADER) - sizeof(T_DP_HEADER)) );
1912 }
1913 #endif
1914
1915
1916 #ifndef RUN_INT_RAM
1917 /*
1918 +--------------------------------------------------------------------+
1919 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1920 | STATE : code ROUTINE : vsi_c_pmax_size |
1921 +--------------------------------------------------------------------+
1922
1923 PURPOSE : get maximum number of bytes available for user data
1924 in dynamic primitive
1925
1926 */
1927 GLOBAL int vsi_c_pmax_size ( void )
1928 {
1929 return ( (int)(MaxPrimPartSize - sizeof(T_DP_HEADER)) );
1930 }
1931 #endif
1932
1933 #ifdef _TOOLS_
1934 /*
1935 +--------------------------------------------------------------------+
1936 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
1937 | STATE : code ROUTINE : vsi_c_sync |
1938 +--------------------------------------------------------------------+
1939
1940 PURPOSE : check if PS already started
1941
1942 */
1943 GLOBAL int vsi_c_sync ( T_HANDLE caller, T_TIME timeout )
1944 {
1945 T_VOID_STRUCT *prim;
1946 T_QMSG Msg;
1947 T_HANDLE tst_q_handle;
1948 char sync_req_name[RESOURCE_NAMELEN];
1949 char sync_req_time[8];
1950 static int sync_active = 0;
1951
1952
1953 if ( sync_active == FALSE )
1954 {
1955 sync_active = TRUE;
1956 os_GetTaskName(caller, caller, sync_req_name);
1957 itoa(timeout, sync_req_time,10);
1958
1959 prim = vsi_c_pnew ( sizeof(T_PRIM_HEADER)+strlen(SYSPRIM_CONFIG_TOKEN)+1
1960 +strlen(SYSPRIM_TST_SYNC_REQ)+1
1961 +strlen(sync_req_name)+1
1962 +strlen(sync_req_time)+1, 0x8000 FILE_LINE );
1963 strcpy ( (char*)prim, SYSPRIM_CONFIG_TOKEN );
1964 strcat ( (char*)prim, " " );
1965 strcat ( (char*)prim, SYSPRIM_TST_SYNC_REQ );
1966 strcat ( (char*)prim, " " );
1967 strcat ( (char*)prim, sync_req_name );
1968 strcat ( (char*)prim, " " );
1969 strcat ( (char*)prim, sync_req_time );
1970
1971 tst_q_handle = vsi_c_open ( caller, FRM_TST_NAME );
1972 vsi_c_psend ( tst_q_handle, prim );
1973
1974 if ( vsi_c_await ( caller, pf_TaskTable[caller].QueueHandle, &Msg, timeout ) == VSI_TIMEOUT )
1975 {
1976 vsi_o_ttrace (caller, TC_SYSTEM, "timeout - Synchronization with Stack failed" );
1977 sync_active = FALSE;
1978 return VSI_ERROR;
1979 }
1980 else
1981 {
1982 sync_active = FALSE;
1983 if ( strcmp ((char*)P2D(Msg.Msg.Primitive.Prim), SYSPRIM_TST_SYNC_CNF ) == 0 )
1984 {
1985 vsi_o_ttrace (caller, TC_SYSTEM, "TST_SYNC_CNF - Synchronization with Stack succeeded" );
1986 vsi_c_free (caller, &Msg.Msg.Primitive.Prim);
1987 return VSI_OK;
1988 }
1989 else
1990 {
1991 vsi_o_ttrace (caller, TC_SYSTEM, "TST_SYNC_REJ - Synchronization with Stack failed" );
1992 vsi_c_free (caller, &Msg.Msg.Primitive.Prim);
1993 return VSI_ERROR;
1994 }
1995 }
1996 }
1997 return VSI_OK;
1998 }
1999 #endif
2000
2001 #ifdef _TOOLS_
2002 /*
2003 +--------------------------------------------------------------------+
2004 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
2005 | STATE : code ROUTINE : vsi_c_generic_send |
2006 +--------------------------------------------------------------------+
2007
2008 PURPOSE : check if PS already started
2009
2010 */
2011 int vsi_c_alloc_send ( T_HANDLE com_handle, char* dst, char* src, void *prim, char *string )
2012 {
2013 int alloc_size;
2014 T_PRIM_HEADER *ptr;
2015 T_S_HEADER *s_hdr;
2016 unsigned int i;
2017 unsigned int size;
2018 int opc;
2019 int s_header_added = 0;
2020 int sh_offset;
2021
2022 if ( string != NULL )
2023 {
2024 size = strlen(string);
2025 alloc_size = size + sizeof(T_PRIM_HEADER);
2026 if ( dst != NULL || src != NULL )
2027 {
2028 sh_offset = ALIGN(alloc_size) / (int)sizeof(ULONG);
2029 alloc_size = ALIGN(alloc_size) + sizeof(T_S_HEADER);
2030 if ( dst != 0 )
2031 opc = 0; /* to stack -> set to SYS_MASK in tst_pei_primitive() when sh_offset != 0 */
2032 else
2033 opc = SYS_MASK; /* to tools */
2034 s_header_added = 1;
2035 }
2036 else
2037 {
2038 opc = SYS_MASK;
2039 sh_offset = 0;
2040 }
2041 ptr = (T_PRIM_HEADER*)vsi_c_new ( 0, alloc_size, opc );
2042 memcpy ( (char*)P2D(ptr), string, size );
2043 if ( s_header_added == 1 )
2044 {
2045 ptr->sh_offset = sh_offset;
2046 s_hdr = (T_S_HEADER*)((int*)ptr+ptr->sh_offset);
2047 ptr->len = size + sizeof(T_PRIM_HEADER); /* exclude S_HEADER */
2048 }
2049 }
2050 else
2051 {
2052 ptr = D2P(prim); /* work on passed primitive */
2053 }
2054 if ( dst != NULL )
2055 {
2056 if ( s_header_added == 0 )
2057 {
2058 alloc_size = ALIGN(ptr->len) + sizeof(T_S_HEADER);
2059 ptr = (T_PRIM_HEADER*)vsi_c_new ( 0, alloc_size, 0 );
2060 memcpy((char*)ptr, (char*)D2P(prim), D_LEN(prim));
2061 ptr->sh_offset = ALIGN(D_LEN(prim)) / sizeof(ULONG);
2062 s_hdr = (T_S_HEADER*)((int*)ptr+ptr->sh_offset);
2063 FREE(prim);
2064 }
2065 else
2066 {
2067 s_hdr = (T_S_HEADER*)((int*)ptr+ptr->sh_offset);
2068 }
2069 /* set org_rcv and rcv */
2070 for (i = 0; dst[i] && i < sizeof (s_hdr->rcv) && dst[i]!= ';'; i++)
2071 s_hdr->org_rcv[i] = s_hdr->rcv[i] = dst[i];
2072 if (i < sizeof s_hdr->rcv)
2073 s_hdr->org_rcv[i] = s_hdr->rcv[i] = 0;
2074
2075 s_hdr->time = 0;
2076 s_header_added = 1;
2077 }
2078
2079 if ( src != NULL )
2080 {
2081 if ( s_header_added == 0 )
2082 {
2083 alloc_size = ALIGN(ptr->len) + sizeof(T_S_HEADER);
2084 ptr = (T_PRIM_HEADER*)vsi_c_new ( 0, alloc_size, 0 );
2085 memcpy((char*)ptr, (char*)D2P(prim), D_LEN(prim));
2086 ptr->sh_offset = ALIGN(D_LEN(prim)) / sizeof(ULONG);
2087 s_hdr = (T_S_HEADER*)((int*)ptr+ptr->sh_offset);
2088 FREE(prim);
2089 }
2090 else
2091 {
2092 s_hdr = (T_S_HEADER*)((int*)ptr+ptr->sh_offset);
2093 }
2094
2095 s_hdr->time = 0;
2096
2097 /* set snd */
2098 for (i = 0; src[i] && i < sizeof (s_hdr->snd) && src[i]!= ';'; i++)
2099 s_hdr->snd[i] = src[i];
2100 if (i < sizeof s_hdr->snd)
2101 s_hdr->snd[i] = 0;
2102 }
2103
2104 return ( vsi_c_psend (com_handle, (T_VOID_STRUCT*)P2D(ptr)) );
2105 }
2106 #endif
2107
2108 #ifdef NU_DEBUG
2109 #ifndef RUN_FLASH
2110 /*
2111 +----------------------------------------------------------------------+
2112 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM |
2113 | STATE : code ROUTINE : check_descriptor_list |
2114 +----------------------------------------------------------------------+
2115
2116 PURPOSE : check partitions in descriptor list
2117
2118 */
2119 int check_descriptor_list ( T_HANDLE caller, T_PRIM_HEADER *prim FILE_LINE_TYPE )
2120 {
2121 T_DP_HEADER *dp_hdr;
2122 T_M_HEADER *mem;
2123 T_desc *desc;
2124 LONG Status;
2125
2126 dp_hdr = (T_DP_HEADER*)((ULONG*)prim + prim->dph_offset);
2127 /* the presence of the guard pattern at dph_offset is used to distinguish between dynamic primitives
2128 and primitives with descriptor list. If the guard pattern is destroyed, the primitive looks like
2129 having a descriptor list and the frame will probably crash during checking the integrity of the
2130 partitions in the list. This bahavior is prefered to non checking the partitions */
2131
2132 if ( *((ULONG*)dp_hdr) == GUARD_PATTERN )
2133 {
2134 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
2135 while (dp_hdr != NULL)
2136 {
2137 if ( dp_hdr->magic_nr != GUARD_PATTERN )
2138 {
2139 prim = (T_PRIM_HEADER*)dp_hdr;
2140 vsi_o_assert ( caller, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
2141 "Magic number in dp_header destroyed (PSEND) %s , opc: 0x%lx, partition 0x%lx",
2142 pf_TaskTable[caller].Name, prim->opc, prim );
2143 }
2144 if ( (Status = os_PartitionCheck ( (T_VOID_STRUCT*)dp_hdr)) == OS_PARTITION_GUARD_PATTERN_DESTROYED )
2145 {
2146 vsi_o_assert ( caller, OS_SYST_ERR_PCB_PATTERN FILE_LINE_MACRO_PASSED,
2147 "%s in dynamic primitive (PSEND),entity %s, prim 0x%x, opc 0x%x, bad partition 0x%x",
2148 guard_str, pf_TaskTable[caller].Name, prim, prim->opc, dp_hdr );
2149 break;
2150 }
2151 dp_hdr = (T_DP_HEADER*)dp_hdr->next;
2152 }
2153 }
2154 else
2155 {
2156 if ( caller != TST_Handle )
2157 {
2158 /* do not check and update the states of the primitives in descriptor lists when called by TST, because
2159 descriptor lists are not routed to TST and will result in the warning generated below */
2160 desc = (T_desc*)(((T_desc_list*)dp_hdr)->first);
2161 while (desc != NULL)
2162 {
2163 mem = (T_M_HEADER*)(((char*)desc)-sizeof(T_M_HEADER));
2164 if ( os_is_valid_partition ((T_VOID_STRUCT*)mem) )
2165 {
2166 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
2167 "pointer to non-partition memory in desc list(PSEND), entity %s, prim 0x%x, opc 0x%x",
2168 pf_TaskTable[caller].Name, prim, prim->opc );
2169 return VSI_ERROR;
2170 }
2171 if ( (Status = os_PartitionCheck ( (T_VOID_STRUCT*)mem)) != OS_OK )
2172 {
2173 switch ( Status )
2174 {
2175 case OS_PARTITION_GUARD_PATTERN_DESTROYED:
2176 vsi_o_assert ( caller, OS_SYST_ERR_PCB_PATTERN FILE_LINE_MACRO_PASSED,
2177 "%s in desclist (PSEND), entity %s, prim 0x%x, opc 0x%x, bad partition 0x%x",
2178 guard_str, pf_TaskTable[caller].Name, prim, prim->opc, mem );
2179 break;
2180 case OS_PARTITION_FREE:
2181 vsi_o_assert ( caller, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
2182 "%s in desclist (PSEND), entity %s, prim 0x%x, opc 0x%x, freed partition 0x%x",
2183 freed_sent_str, pf_TaskTable[caller].Name, prim, prim->opc, mem );
2184 break;
2185 default:
2186 break;
2187 }
2188 }
2189 if ( mem->desc_type == (VSI_DESC_TYPE3 >> 16) )
2190 {
2191 mem = ((T_M_HEADER*)(((T_desc3*)desc)->buffer)) - 1;
2192 if ( os_is_valid_partition ( (T_VOID_STRUCT*)mem ) )
2193 {
2194 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
2195 "pointer to non-partition memory in desc list type 3 (PSEND), entity %s, prim 0x%x, opc 0x%x, invalid partition 0x%x",
2196 pf_TaskTable[caller].Name, prim, prim->opc, mem );
2197 return VSI_ERROR;
2198 }
2199 if ( (Status = os_PartitionCheck ( (T_VOID_STRUCT*)mem )) != OS_OK )
2200 {
2201 switch ( Status )
2202 {
2203 case OS_PARTITION_GUARD_PATTERN_DESTROYED:
2204 vsi_o_assert ( caller, OS_SYST_ERR_PCB_PATTERN FILE_LINE_MACRO_PASSED,
2205 "%s in desclist type 3 (PSEND), entity %s, prim 0x%x, opc 0x%x, bad partition 0x%x",
2206 guard_str, pf_TaskTable[caller].Name, prim, prim->opc, mem );
2207 break;
2208 case OS_PARTITION_FREE:
2209 vsi_o_assert ( caller, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
2210 "%s in desclist type 3 (PSEND), entity %s, prim 0x%x, opc 0x%x, freed partition 0x%x",
2211 freed_sent_str, pf_TaskTable[caller].Name, prim, prim->opc, mem );
2212 break;
2213 default:
2214 break;
2215 }
2216 }
2217 }
2218
2219 desc = (T_desc *)desc->next;
2220 }
2221 }
2222 }
2223 return VSI_OK;
2224 }
2225 #endif
2226 #endif
2227
2228 #if !defined _TARGET_ && !defined _TOOLS_
2229
2230 /* -------------------------------------------------------------------------
2231 check functions
2232 ----------------------------------------------------------------------------*/
2233
2234 #ifdef TEST_PCHECK
2235
2236 #ifndef RUN_INT_RAM
2237 ULONG test_pcheck ( ULONG opc, void * decoded_prim )
2238 {
2239 vsi_o_ttrace ( NO_TASK, TC_SYSTEM, "test_pcheck() called for opc %8x", D_OPC(decoded_prim) );
2240 return pcheck_func.ret_ok+1;
2241 }
2242 #endif
2243
2244 #endif /* TEST_PCHECK */
2245
2246 #ifndef RUN_INT_RAM
2247 /*
2248 +------------------------------------------------------------------------------
2249 | Function : pcheck_register
2250 +------------------------------------------------------------------------------
2251 | Description : register the pcheck function.
2252 |
2253 | Parameters : func - pointer to API function pointer table
2254 |
2255 | Return : void
2256 +------------------------------------------------------------------------------
2257 */
2258 void vsi_pcheck_register ( ULONG (*func)(ULONG, void*), ULONG ret_ok )
2259 {
2260 pcheck_func.ret_ok = ret_ok;
2261 pcheck_func.pcheck = func;
2262 pcheck_func.magic_nr = PCHECK_INITIALIZED;
2263 }
2264 #endif
2265
2266 #ifndef RUN_INT_RAM
2267 /*
2268 +------------------------------------------------------------------------------
2269 | Function : ext_trace_init
2270 +------------------------------------------------------------------------------
2271 | Description : initialize external trace function pointer table.
2272 |
2273 | Parameters : void
2274 |
2275 | Return : void
2276 +------------------------------------------------------------------------------
2277 */
2278 void vsi_pcheck_init ( void )
2279 {
2280 #ifdef TEST_PCHECK
2281 vsi_pcheck_register ( test_pcheck, 0 );
2282 #endif
2283 if ( pcheck_func.magic_nr != PCHECK_INITIALIZED )
2284 {
2285 pcheck_func.ret_ok = 0;
2286 pcheck_func.pcheck = NULL;
2287 pcheck_func.magic_nr = 0;
2288 }
2289 }
2290 #endif
2291
2292 #endif /* !_TARGET_ && !_TOOLS_*/
2293
2294
2295
2296