comparison src/gpf/frame/vsi_com.c @ 5:1ea54a97e831

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