comparison src/gpf/frame/vsi_mem.c @ 0:4e78acac3d88

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