📄 avm_allo.c
字号:
/*******************************************************************************
File name : avm_allo.c
Description : Audio and video memory module memory allocation features
Date Modification Name
---- ------------ ----
17 Jun 99 Created HG
6 Oct 99 Introduce partitions functions HG
*******************************************************************************/
/* Private Definitions (internal use only) ---------------------------------- */
/*#define COMPRESS_AREA
#define FREE_AREA
#define FREE_ALL*/
#define GET_LARGEST_FREE_BLOCK_SIZE
#define USE_SEMAPHORE
/*#define DEBUG_CODE*/
/*#define DO_NOT_ALLOW_AREAS_CROSSING*/
/* Includes ----------------------------------------------------------------- */
#include <string.h>
#include <stdlib.h>
#include "stddefs.h"
#include "stlite.h"
#include "sttbx.h"
#include "stavmem.h"
#include "avm_init.h"
#include "avm_allo.h"
/* Private Types ------------------------------------------------------------ */
/* Private Constants -------------------------------------------------------- */
#define MAX_SIZE_ALIGNING_MASK 0xff /* Limitation of the aligning mask for the size */
/* Private Variables (static)------------------------------------------------ */
/* Public Variables --------------------------------------------------------- */
stavmem_Partition_t PartitionArray[STAVMEM_MAX_MAX_PARTITION];
/* Private Macros ----------------------------------------------------------- */
/* Private Function prototypes ---------------------------------------------- */
static BOOL RoundUpAlignment(U32 *Alignment_p);
static void InsertBlockAboveBlock(MemBlockDesc_t **VeryTopBlock_p, MemBlockDesc_t *InsertBlock_p, MemBlockDesc_t *ListBlock_p);
static void InsertBlockBelowBlock(MemBlockDesc_t **VeryBottomBlock_p, MemBlockDesc_t *InsertBlock_p, MemBlockDesc_t *ListBlock_p);
static void RemoveBlock(MemBlockDesc_t **VeryTopBlock_p, MemBlockDesc_t **VeryBottomBlock_p, MemBlockDesc_t *ListBlock_p);
static MemBlockDesc_t *AllocBlockDescriptor(MemBlockDesc_t **TopOfFreeBlocksList_p);
static void FreeBlockDescriptor(MemBlockDesc_t **TopOfSpaceFreeBlocksList_p, MemBlockDesc_t *Mem_p);
static ST_ErrorCode_t MarkForbiddenRangesAndBorders(stavmem_Partition_t *Partition_p, const U32 NumberOfForbiddenRanges, STAVMEM_MemoryRange_t *NotOrderedForbiddenRangeArray_p, const U32 NumberOfForbiddenBorders, void **NotOrderedForbiddenBorderArray_p);
static void UnMarkForbiddenRangesAndBorders(stavmem_Partition_t *Partition_p);
static BOOL IsInForbiddenRangeOrBorder(const void *StartAddr_p, const void *StopAddr_p, const U32 NumberOfForbiddenRanges, STAVMEM_MemoryRange_t *NotOrderedForbiddenRangeArray_p, const U32 NumberOfForbiddenBorders, void **NotOrderedForbiddenBorderArray_p);
static ST_ErrorCode_t AllocBlockNoSemaphore(const STAVMEM_AllocBlockParams_t *AllocBlockParams_p, STAVMEM_BlockHandle_t *BlockHandle_p);
static ST_ErrorCode_t FreeNoSemaphore(stavmem_Partition_t *Partition_p, STAVMEM_BlockHandle_t BlockHandle);
/* Functions ---------------------------------------------------------------- */
/*
--------------------------------------------------------------------------------
Create a memory partition in an initialised device
--------------------------------------------------------------------------------
*/
ST_ErrorCode_t STAVMEM_CreatePartition(const ST_DeviceName_t DeviceName,
const STAVMEM_CreatePartitionParams_t *CreateParams_p,
STAVMEM_PartitionHandle_t *PartitionHandle_p)
{
U32 PartitionIndex;
stavmem_Device_t *Device_p;
ST_ErrorCode_t Err = ST_NO_ERROR;
/* Exit now if parameters are bad */
if ((CreateParams_p == NULL) || (PartitionHandle_p == NULL))
{
return(ST_ERROR_BAD_PARAMETER);
}
/* Check if device already initialised and return error if not so */
Device_p = stavmem_GetPointerOnDeviceNamed(DeviceName);
if (Device_p == NULL)
{
/* Device name not found */
return(ST_ERROR_UNKNOWN_DEVICE);
}
/* Look for a free partition and return error if none is free */
PartitionIndex = 0;
while ((PartitionArray[PartitionIndex].PartitionValidity == AVMEM_VALID_PARTITION) && (PartitionIndex < STAVMEM_MAX_MAX_PARTITION))
{
PartitionIndex++;
}
if (PartitionIndex >= STAVMEM_MAX_MAX_PARTITION)
{
/* None of the partitions is free */
return(STAVMEM_ERROR_MAX_PARTITION);
}
PartitionArray[PartitionIndex].Device_p = Device_p; /* 'inherits' device characteristics */
/* In the current simplified implementation, there's no multiple partition
so let the whole space become a unique partition */
PartitionArray[PartitionIndex].PartitionVeryTopBlock_p = PartitionArray[PartitionIndex].Device_p->SpaceVeryTopBlock_p;
PartitionArray[PartitionIndex].PartitionVeryBottomBlock_p = PartitionArray[PartitionIndex].Device_p->SpaceVeryBottomBlock_p;
/* Register partition */
PartitionArray[PartitionIndex].PartitionValidity = AVMEM_VALID_PARTITION;
/* Let handle be the address of the partition */
*PartitionHandle_p = (STAVMEM_PartitionHandle_t) &PartitionArray[PartitionIndex];
STTBX_Report((STTBX_REPORT_LEVEL_INFO, "Partition created on device '%s'", DeviceName));
return(Err);
}
/*
--------------------------------------------------------------------------------
Delete a memory partition in an initialised device
--------------------------------------------------------------------------------
*/
ST_ErrorCode_t STAVMEM_DeletePartition(const ST_DeviceName_t DeviceName,
const STAVMEM_DeletePartitionParams_t *DeleteParams_p,
STAVMEM_PartitionHandle_t *PartitionHandle_p)
{
MemBlockDesc_t *Block_p;
BOOL FoundBlocks;
stavmem_Partition_t *Partition_p;
stavmem_Device_t *Device_p;
ST_ErrorCode_t Err = ST_NO_ERROR;
/* Exit now if parameters are bad */
if ((DeleteParams_p == NULL) || (PartitionHandle_p == NULL))
{
return(ST_ERROR_BAD_PARAMETER);
}
/* Check if device already initialised and return error if not so */
Device_p = stavmem_GetPointerOnDeviceNamed(DeviceName);
if (Device_p == NULL)
{
/* Device name not found */
return(ST_ERROR_UNKNOWN_DEVICE);
}
/* Get pointer to partition the block belongs to */
Partition_p = (stavmem_Partition_t *) *PartitionHandle_p;
/* Exit if the partition is not valid */
if (Partition_p->PartitionValidity != AVMEM_VALID_PARTITION)
{
return(STAVMEM_ERROR_INVALID_PARTITION_HANDLE);
}
/* Delete the partition only if the device corresponds */
if (Partition_p->Device_p != Device_p)
{
return(ST_ERROR_BAD_PARAMETER);
}
/* Ensure the partition has no more block allocated. If there is, free them if required */
Block_p = Partition_p->PartitionVeryTopBlock_p;
FoundBlocks = FALSE;
while ((Block_p != NULL) && (!FoundBlocks))
{
FoundBlocks = ((Block_p->IsUsed) && ((Block_p->AllocMode == STAVMEM_ALLOC_MODE_TOP_BOTTOM) || (Block_p->AllocMode == STAVMEM_ALLOC_MODE_BOTTOM_TOP)));
Block_p = Block_p->BlockBelow_p;
}
Block_p = Partition_p->PartitionVeryTopBlock_p;
if (FoundBlocks)
{
/* Some still allocated blocks were found: delete them of fail */
if (DeleteParams_p->ForceDelete)
{
/* Delete all still allocated blocks */
while (Block_p != NULL)
{
if ((Block_p->IsUsed) && ((Block_p->AllocMode == STAVMEM_ALLOC_MODE_TOP_BOTTOM) || (Block_p->AllocMode == STAVMEM_ALLOC_MODE_BOTTOM_TOP)))
{
/* Free block */
FreeNoSemaphore(Partition_p, (STAVMEM_BlockHandle_t) Block_p);
/* Always success */
}
Block_p = Block_p->BlockBelow_p;
}
}
else
{
/* Cannot delete partition: there are still allocated blocks */
return(STAVMEM_ERROR_ALLOCATED_BLOCK);
}
}
/* Actions before deleting partition: loose partition blocks */
Partition_p->PartitionVeryTopBlock_p = NULL;
Partition_p->PartitionVeryBottomBlock_p = NULL;
/* Un-register partition */
Partition_p->PartitionValidity = ~AVMEM_VALID_PARTITION;
STTBX_Report((STTBX_REPORT_LEVEL_INFO, "Partition deleted on device '%s'", Partition_p->Device_p->DeviceName));
return(Err);
}
/*******************************************************************************
Name : stavmem_BlockHandleBelongsToSpace
Description : Tells if a block belongs to the initialised device
Parameters : block handle and device
Assumptions :
Limitations :
Returns : TRUE if block belongs to space, FALSE otherwise
*******************************************************************************/
__inline BOOL stavmem_BlockHandleBelongsToSpace(STAVMEM_BlockHandle_t BlockHandle, stavmem_Device_t Device)
{
if ((((U32) BlockHandle) >= ((U32) Device.FirstBlock_p)) && /* Block handle address may be in range */
(((U32) BlockHandle) <= (((U32) Device.FirstBlock_p) + (sizeof(MemBlockDesc_t) * (Device.TotalAllocatedBlocks - 1)))) && /* Block handle address is in range */
(((((U32) BlockHandle) - ((U32) Device.FirstBlock_p)) % (sizeof(MemBlockDesc_t))) == 0) && /* Block handle address is valid (in range and aligned) */
(((MemBlockDesc_t *) BlockHandle)->AllocMode != STAVMEM_ALLOC_MODE_INVALID)) /* Structure is not in list of available blocks */
{
return(TRUE);
}
return(FALSE);
}
#ifdef DEBUG_CODE
/*******************************************************************************
Name : stavmem_BlockAndBip
Description : Bips and blocks with a loop. Change value to exit the loop
Parameters : None
Assumptions :
Limitations :
Returns : None
*******************************************************************************/
static void stavmem_BlockAndBip(void)
{
volatile U32 val = 0;
STTBX_Print(("\a\a"));
while (val == 0)
{
; /* change value in val to exit the loop ! */
}
}
static boolean stavmem_DisplayAllBlocksInfo(MemBlockDesc_t *VeryTopBlock_p, MemBlockDesc_t *VeryBottomBlock_p)
{
U32 Address, Size;
U32 CalculatedFreeSize = 0;
/* U32 AskedFreeSize;*/
char AllocModeStr[10];
MemBlockDesc_t *Cur_p;
boolean RetErr = TRUE;
STTBX_Print(("\nMEMORY BLOCKS FROM BOTTOM:\n"));
Cur_p = VeryBottomBlock_p;
while (Cur_p != NULL)
{
Size = Cur_p->Size;
Address = ((U32) Cur_p->StartAddr_p);
switch (Cur_p->AllocMode)
{
case STAVMEM_ALLOC_MODE_BOTTOM_TOP:
strcpy(AllocModeStr, "BottomTop");
break;
case STAVMEM_ALLOC_MODE_TOP_BOTTOM:
strcpy(AllocModeStr, "TopBottom");
break;
case STAVMEM_ALLOC_MODE_RESERVED:
strcpy(AllocModeStr, "RESERVED!");
break;
case STAVMEM_ALLOC_MODE_FORBIDDEN:
strcpy(AllocModeStr, "FORBIDDEN");
break;
default:
strcpy(AllocModeStr, "-Invalid-");
RetErr = FALSE;
break;
}
if ((RetErr) && (!Cur_p->IsUsed))
{
strcpy(AllocModeStr, "--FREE!--");
CalculatedFreeSize += Size;
}
STTBX_Print(("%#08x-%#08x : %s (%#x byte%c) \n", Address, Address + Size - 1, AllocModeStr, Size, (Size>1)?'s':'.'));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -