view src/gpf3/frame/vsi_mem.c @ 600:8f50b202e81f

board preprocessor conditionals: prep for more FC hw in the future This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and all preprocessor conditionals throughout the code base that tested for it, replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These new symbols are specified as follows: CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by Mother Mychaela under the FreeCalypso trademark. This family will include modem products (repackagings of the FCDEV3B, possibly with RFFE or even RF transceiver changes), and also my desired FreeCalypso handset product. CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products (which will be firmware-compatible with the FCDEV3B if they use TI Rita transceiver, or will require a different fw build if we switch to one of Silabs Aero transceivers), but not the handset product. Right now this CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize everything dealing with MCSI. At the present moment the future of FC hardware evolution is still unknown: it is not known whether we will ever have any beyond-FCDEV3B hardware at all (contingent on uncertain funding), and if we do produce further FC hardware designs, it is not known whether they will retain the same FIC modem core (triband), if we are going to have a quadband design that still retains the classic Rita transceiver, or if we are going to switch to Silabs Aero II or some other transceiver. If we produce a quadband modem that still uses Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination, and the current fcdev3b build target will be renamed to fcmodem. OTOH, if that putative quadband modem will be Aero-based, then it will require a different fw build target, the fcdev3b target will stay as it is, and the two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM, but will have different RF_FAM numbers. But no matter which way we are going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B in places like ACI, and the present change clears the way for future evolution.
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 01 Apr 2019 01:05:24 +0000
parents c41a534f33c6
children
line wrap: on
line source

/* 
+------------------------------------------------------------------------------
|  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