diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpf/frame/vsi_mem.c	Fri Oct 16 06:23:26 2020 +0000
@@ -0,0 +1,511 @@
+/* 
++------------------------------------------------------------------------------
+|  File:       vsi_mem.c
++------------------------------------------------------------------------------
+|  Copyright 2002 Texas Instruments Berlin, AG 
+|                 All rights reserved. 
+| 
+|                 This file is confidential and a trade secret of Texas 
+|                 Instruments Berlin, AG 
+|                 The receipt of or possession of this file does not convey 
+|                 any rights to reproduce or disclose its contents or to 
+|                 manufacture, use, or sell anything it may describe, in 
+|                 whole, or in part, without the specific written consent of 
+|                 Texas Instruments Berlin, AG. 
++----------------------------------------------------------------------------- 
+|  Purpose :  This Module defines the virtual system interface part
+|             for the dynamic memory pools.
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifndef __VSI_MEM_C__
+#define __VSI_MEM_C__
+#endif
+
+/*==== INCLUDES ===================================================*/
+
+#include "string.h"
+
+#include "typedefs.h"
+#include "vsi.h"
+#include "os.h"
+#include "frm_defs.h"
+#include "frm_types.h"
+#include "frm_glob.h"
+
+#ifdef NU_DEBUG
+ #include "frame.h"
+#endif
+
+#ifdef MEMORY_SUPERVISION
+ #include "tools.h"
+#endif
+
+/*==== CONSTANTS ==================================================*/
+
+#ifndef RUN_INT_RAM
+char const *waited_str = "Waited for partition";
+char const *bigger_str = "Bigger partition allocated than requested";
+char const *free_str   = "Partition Deallocation failed";
+#else
+extern char const *waited_str;
+extern char const *bigger_str;
+extern char const *free_str;
+#endif
+
+#ifdef NU_DEBUG
+extern char const *freed_str;
+#endif
+ 
+/*==== TYPES ======================================================*/
+
+
+/*==== EXTERNALS ==================================================*/
+
+/* -------------- S H A R E D - BEGIN ---------------- */
+#ifdef _TOOLS_
+#pragma data_seg("FRAME_SHARED") 
+#endif
+
+#if !defined (_TOOLS_) && !defined (_LINUX_) && !defined (_SOLARIS_)
+extern const T_FRM_PARTITION_GROUP_CONFIG partition_grp_config[];
+#endif
+
+/*==== VARIABLES ==================================================*/
+
+#ifndef RUN_INT_RAM
+ char init_partition_memory = DISABLE_PARTITON_INIT;
+ char init_partition_pattern = 0;
+ T_HANDLE vsi_m_sem_handle = VSI_ERROR;
+#else
+ extern char init_partition_memory;
+ extern char init_partition_pattern;
+ extern T_HANDLE vsi_m_sem_handle;
+#endif
+	        
+#ifdef _TOOLS_
+#pragma data_seg()
+#endif
+/* -------------- S H A R E D - END ---------------- */
+
+/*==== FUNCTIONS ==================================================*/
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_new           |
++--------------------------------------------------------------------+
+
+  PURPOSE : allocate a partition of a pool defined by the parameter type
+
+*/
+
+T_VOID_STRUCT * vsi_m_new (ULONG Size, ULONG type FILE_LINE_TYPE)
+{
+LONG Status;
+T_VOID_STRUCT *prim;
+OS_HANDLE pool;
+T_HANDLE Caller;
+ULONG flags;
+ULONG suspend;
+
+  Caller = 0;
+
+  pool  = type & VSI_MEM_POOL_MASK;
+  flags = type & VSI_MEM_FLAG_MASK;
+
+  if ( flags & VSI_MEM_NON_BLOCKING )
+    suspend = OS_NO_SUSPEND;
+  else
+    suspend = OS_SUSPEND;
+
+  Status = os_AllocatePartition ( Caller, &prim, Size, suspend, pool );
+
+  switch ( Status )
+  {
+    case OS_OK:
+    break;
+    case OS_WAITED:
+#ifdef NU_DEBUG
+      Caller = e_running[os_MyHandle()];
+      pf_handle_warning ( OS_SYST_WRN_WAIT_PARTITION, "%s %s, entity %s, Size %d, %s(%d)", 
+                          syst_wrn, waited_str, pf_TaskTable[Caller].Name, Size FILE_LINE_MACRO_PASSED );
+#endif
+    break;
+    case OS_ERROR:
+    case OS_TIMEOUT:
+      if ( !(flags & VSI_MEM_NON_BLOCKING) )
+      {
+        /* fatal error for blocking allocation and 'HISR' caller */
+        Caller = e_running[os_MyHandle()];
+        vsi_o_assert ( NO_TASK, OS_SYST_ERR_NO_PARTITION FILE_LINE_MACRO_PASSED,
+                       "No Partition available, entity %s, size %d",
+                       pf_TaskTable[Caller].Name, Size );
+      }
+      return NULL;
+    /*lint -e527 suppress Warning -- Unreachable */
+    break;
+    /*lint +e527 */
+    case OS_ALLOCATED_BIGGER:
+#ifdef NU_DEBUG
+      Caller = e_running[os_MyHandle()];
+      pf_handle_warning ( OS_SYST_WRN_BIG_PARTITION, "%s %s, entity %s, Size %d, %s(%d)", 
+                          syst_wrn, bigger_str, pf_TaskTable[Caller].Name, Size FILE_LINE_MACRO_PASSED );
+#endif
+    break;
+    default:
+      return NULL;
+    /*lint -e527 suppress Warning -- Unreachable */
+    break;
+    /*lint +e527 */
+  }
+
+  prim = prim + PPM_OFFSET;
+
+  if ( init_partition_memory )
+  {
+    memset( (char*)prim, init_partition_pattern, (unsigned int)Size );
+  }
+#ifdef MEMORY_SUPERVISION
+  /*
+   * Pools registered via vsi_m_register_pool() cannot be handle by the partition supervision. The
+   * id therefor is set to 0, to allow the supervision functions to ignore them.
+   */
+  if ( pool == DmemGroupHandle )
+  {
+    /* for primitive vsi_ppm_new() is called after the opc has been entered in the header */
+    Caller = e_running[os_MyHandle()];
+    vsi_ppm_new ( Caller, Size, (T_PRIM_HEADER*)prim, file, line );
+  }
+#endif /* MEMORY_SUPERVISION */
+
+  return prim;
+}
+#endif
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_new_size      |
++--------------------------------------------------------------------+
+
+  PURPOSE : allocate partition and retern partition size
+
+*/
+T_VOID_STRUCT *vsi_m_new_size ( ULONG size, ULONG type,
+                                ULONG *partition_size FILE_LINE_TYPE)
+{
+T_FRM_PARTITION_POOL_CONFIG * pool_config;
+T_VOID_STRUCT *prim;
+
+  if ( ( prim = vsi_m_new ( size, type FILE_LINE ) ) != NULL )
+  {
+#if defined (_TOOLS_) || defined (_LINUX_) || defined (_SOLARIS_)
+    *partition_size = size;
+#else
+    pool_config = (T_FRM_PARTITION_POOL_CONFIG*)partition_grp_config[PrimGroupHandle].grp_config;
+    while ( pool_config != NULL )
+    {
+      if ( size <= pool_config->part_size )
+      {
+        *partition_size = pool_config->part_size;
+        break;
+      }
+      else
+      {
+        pool_config++;
+      }
+    }
+#endif
+  }
+  return (prim);
+}
+#endif
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_free          |
++--------------------------------------------------------------------+
+
+  PURPOSE : deallocate a partition
+
+*/
+
+int vsi_m_free (T_VOID_STRUCT **Msg FILE_LINE_TYPE)
+{
+T_HANDLE Caller;
+#ifdef MEMORY_SUPERVISION
+  Caller = e_running[os_MyHandle()];
+  vsi_ppm_free ( Caller, (T_PRIM_HEADER*)*Msg, file, line );
+#endif
+
+  Caller = 0;
+  if ( os_DeallocatePartition ( Caller, *Msg - PPM_OFFSET ) != OS_ERROR )
+  {
+    *Msg = NULL;
+    return VSI_OK;
+  }
+#ifdef NU_DEBUG
+  Caller = e_running[os_MyHandle()];
+  pf_handle_warning ( OS_SYST_WRN_FREE_FAILED, "%s %s in %s, %s(%d)", 
+                      syst_wrn, free_str, pf_TaskTable[Caller].Name FILE_LINE_MACRO_PASSED );
+#endif
+  return VSI_ERROR;
+}
+#endif
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_cnew          |
++--------------------------------------------------------------------+
+
+  PURPOSE : allocate a memory with reference counter
+
+*/
+
+T_VOID_STRUCT * vsi_m_cnew (ULONG size, ULONG type FILE_LINE_TYPE)
+{
+T_M_HEADER *mem;
+#ifdef MEMORY_SUPERVISION
+T_HANDLE caller;
+#endif
+
+  if ( (mem = (T_M_HEADER*)vsi_m_new ( size+sizeof(T_M_HEADER), type FILE_LINE )) != NULL )
+  {
+    /* set reference counter */
+    mem->ref_cnt = 1;
+    /* set descriptor type */
+    mem->desc_type = (SHORT)((type & VSI_MEM_DESC_MASK) >> 16);
+    /* return pointer to user data */
+#ifdef MEMORY_SUPERVISION
+    caller = e_running[os_MyHandle()];
+    vsi_ppm_new ( caller, size+sizeof(T_M_HEADER), (T_PRIM_HEADER*)mem, file, line );
+#endif
+    return (T_VOID_STRUCT*)(mem + 1);
+  }
+  else
+  {
+    return NULL;
+  }
+
+}
+#endif
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_cfree         |
++--------------------------------------------------------------------+
+
+  PURPOSE : allocate a memory with reference counter
+
+*/
+
+int vsi_m_cfree (T_VOID_STRUCT **ptr FILE_LINE_TYPE)
+{
+T_HANDLE caller = 0;
+LONG sts;
+T_M_HEADER *mem;
+
+  /* get pointer to start of partition. Here is the reference counter */
+  mem = (T_M_HEADER*)*ptr - 1;
+
+#ifdef NU_DEBUG
+  if ( os_is_valid_partition ((T_VOID_STRUCT*)mem) )
+  {
+    /* free to non-partition memory */
+    caller = e_running[os_MyHandle()];
+    vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
+                   "MFREE to non-partition memory, entity %s, ptr 0x%x", pf_TaskTable[caller].Name, *ptr );
+    return VSI_ERROR;
+  }
+#endif
+
+  sts = os_ObtainSemaphore (caller, vsi_m_sem_handle, OS_SUSPEND);
+  if ( sts == OS_ERROR || sts == OS_TIMEOUT )
+  {
+    /* Semaphore invalid or overrun */
+    caller = e_running[os_MyHandle()];
+    vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
+                   "Ref Cnt Semaphore overrun, entity %s", pf_TaskTable[caller].Name );
+    return VSI_ERROR;
+  }
+  if ( mem->ref_cnt <= 0 )
+  {
+#ifdef NU_DEBUG
+    /* partition already freed */
+    caller = e_running[os_MyHandle()];
+    pf_handle_warning ( OS_SYST_WRN_MULTIPLE_FREE, "%s %s in %s, %s(%d)", 
+                        syst_wrn, freed_str, pf_TaskTable[caller].Name FILE_LINE_MACRO_PASSED );
+#endif
+    os_ReleaseSemaphore (caller, vsi_m_sem_handle);
+    return VSI_OK;
+  }
+  if ( --(mem->ref_cnt) == 0 )
+  {
+#ifdef _NUCLEUS_
+#ifdef NU_DEBUG
+
+    if ( os_PartitionCheck( (ULONG*)mem ) == OS_PARTITION_GUARD_PATTERN_DESTROYED )
+    {
+      caller = e_running[os_MyHandle()];
+      os_ReleaseSemaphore (caller, vsi_m_sem_handle);
+      vsi_o_assert ( caller, OS_SYST_ERR_PCB_PATTERN FILE_LINE_MACRO_PASSED,
+                     "Partition Guard Pattern destroyed (MFREE),Task %s,Partition 0x%x",
+                     pf_TaskTable[caller].Name, mem );
+      return VSI_ERROR;
+    }
+#endif
+#endif
+    if (vsi_m_free ( (T_VOID_STRUCT**)&mem FILE_LINE ) != VSI_OK)
+    {
+      os_ReleaseSemaphore (caller, vsi_m_sem_handle);
+      return VSI_ERROR;
+    }
+
+    *ptr=NULL;
+  }
+  os_ReleaseSemaphore (caller, vsi_m_sem_handle);
+  return VSI_OK;
+
+}
+#endif
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_cfree         |
++--------------------------------------------------------------------+
+
+  PURPOSE : allocate a memory with reference counter
+
+*/
+
+int vsi_m_attach (T_VOID_STRUCT *ptr FILE_LINE_TYPE)
+{
+T_HANDLE caller = 0;
+LONG sts;
+T_M_HEADER *mem;
+
+  /* get pointer to start of partition. Here is the reference counter */
+  mem = (T_M_HEADER*)ptr - 1;
+
+#ifdef NU_DEBUG
+  if ( os_is_valid_partition ((T_VOID_STRUCT*)mem) )
+  {
+    /* attach to non-partition memory */
+    caller = e_running[os_MyHandle()];
+    vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
+                   "MATTACH to non-partition memory, entity %s, ptr 0x%x", pf_TaskTable[caller].Name, ptr );
+  }
+#endif
+  sts = os_ObtainSemaphore (caller, vsi_m_sem_handle, OS_SUSPEND);
+  if ( sts == OS_ERROR || sts == OS_TIMEOUT )
+  {
+    /* Semaphore invalid or overrun */
+    caller = e_running[os_MyHandle()];
+    vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
+                   "Ref Cnt Semaphore overrun, entity %s", pf_TaskTable[caller].Name );
+  }
+  if ( mem->ref_cnt <= 0 )
+  {
+    /* attach to non allocated memory */
+    caller = e_running[os_MyHandle()];
+    vsi_o_assert ( NO_TASK, OS_SYST_ERR FILE_LINE_MACRO_PASSED,
+                   "MATTACH to free memory, entity %s, ptr 0x%x", pf_TaskTable[caller].Name, ptr );
+  }
+  else
+  {
+    /* increment reference counter */
+    mem->ref_cnt++;
+  }
+  os_ReleaseSemaphore (caller, vsi_m_sem_handle);
+  return VSI_OK;
+
+}
+#endif
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_status        |
++--------------------------------------------------------------------+
+
+  PURPOSE : retrieve number of used/available partitions
+
+*/
+
+GLOBAL int vsi_m_status ( T_HANDLE caller, ULONG size, USHORT type, USHORT *free, USHORT *alloc )
+{
+#ifdef _NUCLEUS_
+OS_HANDLE pool;
+
+  pool = type & VSI_MEM_POOL_MASK;
+
+  if ( os_GetPartitionPoolStatus ( size, pool, free, alloc ) == OS_OK )
+    return VSI_OK;
+  else
+#endif
+    return VSI_ERROR;
+}
+#endif
+
+#ifndef _TOOLS_
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_register_pool |
++--------------------------------------------------------------------+
+
+  PURPOSE : register a new partition pool group to be accessable via VSI
+
+*/
+
+GLOBAL int vsi_m_register_pool ( char * name, T_HANDLE * pool_gr_id )
+{
+OS_HANDLE pool_gr;
+  
+  if ( os_GetPartitionGroupHandle (OS_NOTASK, name, &pool_gr) == OS_OK )
+  {
+    *pool_gr_id = (T_HANDLE)pool_gr;
+    return VSI_OK;
+  }
+  else
+  {
+    return VSI_ERROR;
+  }
+}
+#endif
+#endif
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-Frame (8415)           MODULE  : VSI_MEM             |
+| STATE   : code                       ROUTINE : vsi_m_init          |
++--------------------------------------------------------------------+
+
+  PURPOSE : retrieve number of used/available partitions
+
+*/
+
+GLOBAL int vsi_m_init ( char enable_init, char pattern )
+{
+
+  init_partition_memory  = enable_init;
+  init_partition_pattern = pattern; 
+  os_CreateSemaphore ( 0, (char*)"VSI_MSEM", 1, &vsi_m_sem_handle, 0 );
+
+  return VSI_OK;
+}
+#endif