comparison gpf/frame/vsi_mem.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_mem.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 | for the dynamic memory pools.
18 +-----------------------------------------------------------------------------
19 */
20
21 #ifndef __VSI_MEM_C__
22 #define __VSI_MEM_C__
23 #endif
24
25 /*==== INCLUDES ===================================================*/
26
27 #include <string.h>
28
29 #include "gpfconf.h"
30 #include "typedefs.h"
31 #include "vsi.h"
32 #include "os.h"
33 #include "frm_defs.h"
34 #include "frm_types.h"
35 #include "frm_glob.h"
36
37 #ifdef NU_DEBUG
38 #include "frame.h"
39 #endif
40
41 #ifdef MEMORY_SUPERVISION
42 #include "tools.h"
43 #endif
44
45 /*==== CONSTANTS ==================================================*/
46
47 #ifndef RUN_INT_RAM
48 char const *waited_str = "Waited for partition";
49 char const *bigger_str = "Bigger partition allocated than requested";
50 char const *free_str = "Partition Deallocation failed";
51 #else
52 extern char const *waited_str;
53 extern char const *bigger_str;
54 extern char const *free_str;
55 #endif
56
57 #ifdef NU_DEBUG
58 extern char const *freed_str;
59 #endif
60
61 /*==== TYPES ======================================================*/
62
63
64 /*==== EXTERNALS ==================================================*/
65
66 /* -------------- S H A R E D - BEGIN ---------------- */
67 #ifdef _TOOLS_
68 #pragma data_seg("FRAME_SHARED")
69 #endif
70
71 #if !defined (_TOOLS_) && !defined (_LINUX_) && !defined (_SOLARIS_)
72 extern const T_FRM_PARTITION_GROUP_CONFIG partition_grp_config[];
73 #endif
74
75 /*==== VARIABLES ==================================================*/
76
77 #ifndef RUN_INT_RAM
78 char init_partition_memory = DISABLE_PARTITON_INIT;
79 char init_partition_pattern = 0;
80 T_HANDLE vsi_m_sem_handle = VSI_ERROR;
81 #else
82 extern char init_partition_memory;
83 extern char init_partition_pattern;
84 extern T_HANDLE vsi_m_sem_handle;
85 #endif
86
87 #ifdef _TOOLS_
88 #pragma data_seg()
89 #endif
90 /* -------------- S H A R E D - END ---------------- */
91
92 /*==== FUNCTIONS ==================================================*/
93
94 #ifndef RUN_FLASH
95 /*
96 +--------------------------------------------------------------------+
97 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
98 | STATE : code ROUTINE : vsi_m_new |
99 +--------------------------------------------------------------------+
100
101 PURPOSE : allocate a partition of a pool defined by the parameter type
102
103 */
104
105 T_VOID_STRUCT * vsi_m_new (ULONG Size, ULONG type FILE_LINE_TYPE)
106 {
107 LONG Status;
108 T_VOID_STRUCT *prim;
109 OS_HANDLE pool;
110 T_HANDLE Caller;
111 ULONG flags;
112 ULONG suspend;
113
114 Caller = 0;
115
116 pool = type & VSI_MEM_POOL_MASK;
117 flags = type & VSI_MEM_FLAG_MASK;
118
119 if ( flags & VSI_MEM_NON_BLOCKING )
120 suspend = OS_NO_SUSPEND;
121 else
122 suspend = OS_SUSPEND;
123
124 Status = os_AllocatePartition ( Caller, &prim, Size, suspend, pool );
125
126 switch ( Status )
127 {
128 case OS_OK:
129 break;
130 case OS_WAITED:
131 #ifdef NU_DEBUG
132 Caller = e_running[os_MyHandle()];
133 pf_handle_warning ( OS_SYST_WRN_WAIT_PARTITION, "%s %s, entity %s, Size %d, %s(%d)",
134 syst_wrn, waited_str, pf_TaskTable[Caller].Name, Size FILE_LINE_MACRO_PASSED );
135 #endif
136 break;
137 case OS_ERROR:
138 case OS_TIMEOUT:
139 if ( !(flags & VSI_MEM_NON_BLOCKING) )
140 {
141 /* fatal error for blocking allocation and 'HISR' caller */
142 Caller = e_running[os_MyHandle()];
143 vsi_o_assert ( NO_TASK, OS_SYST_ERR_NO_PARTITION FILE_LINE_MACRO_PASSED,
144 "No Partition available, entity %s, size %d",
145 pf_TaskTable[Caller].Name, Size );
146 }
147 return NULL;
148 /*lint -e527 suppress Warning -- Unreachable */
149 break;
150 /*lint +e527 */
151 case OS_ALLOCATED_BIGGER:
152 #ifdef NU_DEBUG
153 Caller = e_running[os_MyHandle()];
154 pf_handle_warning ( OS_SYST_WRN_BIG_PARTITION, "%s %s, entity %s, Size %d, %s(%d)",
155 syst_wrn, bigger_str, pf_TaskTable[Caller].Name, Size FILE_LINE_MACRO_PASSED );
156 #endif
157 break;
158 default:
159 return NULL;
160 /*lint -e527 suppress Warning -- Unreachable */
161 break;
162 /*lint +e527 */
163 }
164
165 prim = prim + PPM_OFFSET;
166
167 if ( init_partition_memory )
168 {
169 memset( (char*)prim, init_partition_pattern, (unsigned int)Size );
170 }
171 #ifdef MEMORY_SUPERVISION
172 /*
173 * Pools registered via vsi_m_register_pool() cannot be handle by the partition supervision. The
174 * id therefor is set to 0, to allow the supervision functions to ignore them.
175 */
176 if ( pool == DmemGroupHandle )
177 {
178 /* for primitive vsi_ppm_new() is called after the opc has been entered in the header */
179 Caller = e_running[os_MyHandle()];
180 vsi_ppm_new ( Caller, Size, (T_PRIM_HEADER*)prim, file, line );
181 }
182 #endif /* MEMORY_SUPERVISION */
183
184 return prim;
185 }
186 #endif
187
188 #ifndef RUN_INT_RAM
189 /*
190 +--------------------------------------------------------------------+
191 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
192 | STATE : code ROUTINE : vsi_m_new_size |
193 +--------------------------------------------------------------------+
194
195 PURPOSE : allocate partition and retern partition size
196
197 */
198 T_VOID_STRUCT *vsi_m_new_size ( ULONG size, ULONG type,
199 ULONG *partition_size FILE_LINE_TYPE)
200 {
201 T_FRM_PARTITION_POOL_CONFIG * pool_config;
202 T_VOID_STRUCT *prim;
203
204 if ( ( prim = vsi_m_new ( size, type FILE_LINE ) ) != NULL )
205 {
206 #if defined (_TOOLS_) || defined (_LINUX_) || defined (_SOLARIS_)
207 *partition_size = size;
208 #else
209 pool_config = (T_FRM_PARTITION_POOL_CONFIG*)partition_grp_config[PrimGroupHandle].grp_config;
210 while ( pool_config != NULL )
211 {
212 if ( size <= pool_config->part_size )
213 {
214 *partition_size = pool_config->part_size;
215 break;
216 }
217 else
218 {
219 pool_config++;
220 }
221 }
222 #endif
223 }
224 return (prim);
225 }
226 #endif
227
228 #ifndef RUN_FLASH
229 /*
230 +--------------------------------------------------------------------+
231 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
232 | STATE : code ROUTINE : vsi_m_free |
233 +--------------------------------------------------------------------+
234
235 PURPOSE : deallocate a partition
236
237 */
238
239 int vsi_m_free (T_VOID_STRUCT **Msg FILE_LINE_TYPE)
240 {
241 T_HANDLE Caller;
242 #ifdef MEMORY_SUPERVISION
243 Caller = e_running[os_MyHandle()];
244 vsi_ppm_free ( Caller, (T_PRIM_HEADER*)*Msg, file, line );
245 #endif
246
247 Caller = 0;
248 if ( os_DeallocatePartition ( Caller, *Msg - PPM_OFFSET ) != OS_ERROR )
249 {
250 *Msg = NULL;
251 return VSI_OK;
252 }
253 #ifdef NU_DEBUG
254 Caller = e_running[os_MyHandle()];
255 pf_handle_warning ( OS_SYST_WRN_FREE_FAILED, "%s %s in %s, %s(%d)",
256 syst_wrn, free_str, pf_TaskTable[Caller].Name FILE_LINE_MACRO_PASSED );
257 #endif
258 return VSI_ERROR;
259 }
260 #endif
261
262 #ifndef RUN_FLASH
263 /*
264 +--------------------------------------------------------------------+
265 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
266 | STATE : code ROUTINE : vsi_m_cnew |
267 +--------------------------------------------------------------------+
268
269 PURPOSE : allocate a memory with reference counter
270
271 */
272
273 T_VOID_STRUCT * vsi_m_cnew (ULONG size, ULONG type FILE_LINE_TYPE)
274 {
275 T_M_HEADER *mem;
276 #ifdef MEMORY_SUPERVISION
277 T_HANDLE caller;
278 #endif
279
280 if ( (mem = (T_M_HEADER*)vsi_m_new ( size+sizeof(T_M_HEADER), type FILE_LINE )) != NULL )
281 {
282 /* set reference counter */
283 mem->ref_cnt = 1;
284 /* set descriptor type */
285 mem->desc_type = (SHORT)((type & VSI_MEM_DESC_MASK) >> 16);
286 /* return pointer to user data */
287 #ifdef MEMORY_SUPERVISION
288 caller = e_running[os_MyHandle()];
289 vsi_ppm_new ( caller, size+sizeof(T_M_HEADER), (T_PRIM_HEADER*)mem, file, line );
290 #endif
291 return (T_VOID_STRUCT*)(mem + 1);
292 }
293 else
294 {
295 return NULL;
296 }
297
298 }
299 #endif
300
301 #ifndef RUN_FLASH
302 /*
303 +--------------------------------------------------------------------+
304 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
305 | STATE : code ROUTINE : vsi_m_cfree |
306 +--------------------------------------------------------------------+
307
308 PURPOSE : allocate a memory with reference counter
309
310 */
311
312 int vsi_m_cfree (T_VOID_STRUCT **ptr FILE_LINE_TYPE)
313 {
314 T_HANDLE caller = 0;
315 LONG sts;
316 T_M_HEADER *mem;
317
318 /* get pointer to start of partition. Here is the reference counter */
319 mem = (T_M_HEADER*)*ptr - 1;
320
321 #ifdef NU_DEBUG
322 if ( os_is_valid_partition ((T_VOID_STRUCT*)mem) )
323 {
324 /* free to non-partition memory */
325 caller = e_running[os_MyHandle()];
326 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
327 "MFREE to non-partition memory, entity %s, ptr 0x%x", pf_TaskTable[caller].Name, *ptr );
328 return VSI_ERROR;
329 }
330 #endif
331
332 sts = os_ObtainSemaphore (caller, vsi_m_sem_handle, OS_SUSPEND);
333 if ( sts == OS_ERROR || sts == OS_TIMEOUT )
334 {
335 /* Semaphore invalid or overrun */
336 caller = e_running[os_MyHandle()];
337 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
338 "Ref Cnt Semaphore overrun, entity %s", pf_TaskTable[caller].Name );
339 return VSI_ERROR;
340 }
341 if ( mem->ref_cnt <= 0 )
342 {
343 #ifdef NU_DEBUG
344 /* partition already freed */
345 caller = e_running[os_MyHandle()];
346 pf_handle_warning ( OS_SYST_WRN_MULTIPLE_FREE, "%s %s in %s, %s(%d)",
347 syst_wrn, freed_str, pf_TaskTable[caller].Name FILE_LINE_MACRO_PASSED );
348 #endif
349 os_ReleaseSemaphore (caller, vsi_m_sem_handle);
350 return VSI_OK;
351 }
352 if ( --(mem->ref_cnt) == 0 )
353 {
354 #ifdef _NUCLEUS_
355 #ifdef NU_DEBUG
356
357 if ( os_PartitionCheck( (ULONG*)mem ) == OS_PARTITION_GUARD_PATTERN_DESTROYED )
358 {
359 caller = e_running[os_MyHandle()];
360 os_ReleaseSemaphore (caller, vsi_m_sem_handle);
361 vsi_o_assert ( caller, OS_SYST_ERR_PCB_PATTERN FILE_LINE_MACRO_PASSED,
362 "Partition Guard Pattern destroyed (MFREE),Task %s,Partition 0x%x",
363 pf_TaskTable[caller].Name, mem );
364 return VSI_ERROR;
365 }
366 #endif
367 #endif
368 if (vsi_m_free ( (T_VOID_STRUCT**)&mem FILE_LINE ) != VSI_OK)
369 {
370 os_ReleaseSemaphore (caller, vsi_m_sem_handle);
371 return VSI_ERROR;
372 }
373
374 *ptr=NULL;
375 }
376 os_ReleaseSemaphore (caller, vsi_m_sem_handle);
377 return VSI_OK;
378
379 }
380 #endif
381
382 #ifndef RUN_FLASH
383 /*
384 +--------------------------------------------------------------------+
385 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
386 | STATE : code ROUTINE : vsi_m_cfree |
387 +--------------------------------------------------------------------+
388
389 PURPOSE : allocate a memory with reference counter
390
391 */
392
393 int vsi_m_attach (T_VOID_STRUCT *ptr FILE_LINE_TYPE)
394 {
395 T_HANDLE caller = 0;
396 LONG sts;
397 T_M_HEADER *mem;
398
399 /* get pointer to start of partition. Here is the reference counter */
400 mem = (T_M_HEADER*)ptr - 1;
401
402 #ifdef NU_DEBUG
403 if ( os_is_valid_partition ((T_VOID_STRUCT*)mem) )
404 {
405 /* attach to non-partition memory */
406 caller = e_running[os_MyHandle()];
407 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
408 "MATTACH to non-partition memory, entity %s, ptr 0x%x", pf_TaskTable[caller].Name, ptr );
409 }
410 #endif
411 sts = os_ObtainSemaphore (caller, vsi_m_sem_handle, OS_SUSPEND);
412 if ( sts == OS_ERROR || sts == OS_TIMEOUT )
413 {
414 /* Semaphore invalid or overrun */
415 caller = e_running[os_MyHandle()];
416 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
417 "Ref Cnt Semaphore overrun, entity %s", pf_TaskTable[caller].Name );
418 }
419 if ( mem->ref_cnt <= 0 )
420 {
421 /* attach to non allocated memory */
422 caller = e_running[os_MyHandle()];
423 vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
424 "MATTACH to free memory, entity %s, ptr 0x%x", pf_TaskTable[caller].Name, ptr );
425 }
426 else
427 {
428 /* increment reference counter */
429 mem->ref_cnt++;
430 }
431 os_ReleaseSemaphore (caller, vsi_m_sem_handle);
432 return VSI_OK;
433
434 }
435 #endif
436
437 #ifndef RUN_INT_RAM
438 /*
439 +--------------------------------------------------------------------+
440 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
441 | STATE : code ROUTINE : vsi_m_status |
442 +--------------------------------------------------------------------+
443
444 PURPOSE : retrieve number of used/available partitions
445
446 */
447
448 GLOBAL int vsi_m_status ( T_HANDLE caller, ULONG size, USHORT type, USHORT *free, USHORT *alloc )
449 {
450 #ifdef _NUCLEUS_
451 OS_HANDLE pool;
452
453 pool = type & VSI_MEM_POOL_MASK;
454
455 if ( os_GetPartitionPoolStatus ( size, pool, free, alloc ) == OS_OK )
456 return VSI_OK;
457 else
458 #endif
459 return VSI_ERROR;
460 }
461 #endif
462
463 #ifndef _TOOLS_
464 #ifndef RUN_INT_RAM
465 /*
466 +--------------------------------------------------------------------+
467 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
468 | STATE : code ROUTINE : vsi_m_register_pool |
469 +--------------------------------------------------------------------+
470
471 PURPOSE : register a new partition pool group to be accessable via VSI
472
473 */
474
475 GLOBAL int vsi_m_register_pool ( char * name, T_HANDLE * pool_gr_id )
476 {
477 OS_HANDLE pool_gr;
478
479 if ( os_GetPartitionGroupHandle (OS_NOTASK, name, &pool_gr) == OS_OK )
480 {
481 *pool_gr_id = (T_HANDLE)pool_gr;
482 return VSI_OK;
483 }
484 else
485 {
486 return VSI_ERROR;
487 }
488 }
489 #endif
490 #endif
491
492 #ifndef RUN_INT_RAM
493 /*
494 +--------------------------------------------------------------------+
495 | PROJECT : GSM-Frame (8415) MODULE : VSI_MEM |
496 | STATE : code ROUTINE : vsi_m_init |
497 +--------------------------------------------------------------------+
498
499 PURPOSE : retrieve number of used/available partitions
500
501 */
502
503 GLOBAL int vsi_m_init ( char enable_init, char pattern )
504 {
505
506 init_partition_memory = enable_init;
507 init_partition_pattern = pattern;
508 os_CreateSemaphore ( 0, (char*)"VSI_MSEM", 1, &vsi_m_sem_handle, 0 );
509
510 return VSI_OK;
511 }
512 #endif