?? zl5011xgm.c
字號(hào):
/*******************************************************************************
*
* File name: zl5011xGm.c
*
* Version: 21
*
* Author: MRC
*
* Date created: 04/04/2002
*
* Copyright 2002, 2003, 2004, 2005, Zarlink Semiconductor Limited.
* All rights reserved.
*
* Module Description:
*
* This file contains all the functions that will initialise and control
* the Granule Manager block. A granule is a block of memory that the device
* uses to transfer data between the functional blocks. Each granule has a
* corresponding descriptor, which is used to link granules into chains.
*
* Revision History:
*
* Rev: Date: Author: Comments:
* 1 04/04/2002 MRC Creation
* 2 04/04/2002 MRC Last entry in the chain is initialised
* differently.
* 3 04/04/2002 MRC Added comments
* 4 04/04/2002 MRC Update
* 5 24/04/2002 MRC Changed the granule chain to start at 1 not 0
* 6 24/04/2002 MRC The granule chain cannot include granule 0,
* renumbering did not work.
* 7 26/04/2002 MRC Changed some data names in response to comments
* from Thomas, regarding the MIB interface.
* 8 07/06/2002 MRC Added granule check functions
* 9 10/06/2002 LCW Added extra functions
* 10 13/06/2002 LCW Fixed the interrupt functions
* 11 04/07/2002 PJE modified headers to interrupt funcs as per reveiew
* 12 18/07/2002 MRC Updated GM configure fn
* 13 22/07/2002 MRC Updated following review
* 14 27/08/2002 MRC Turned granule 0 into a loop!
* 15 28/08/2002 PJE First clear the interrupts before enabling.
* 16 01/10/2002 DJA File header modified
* 17 31/10/2002 MRC Added variants + minor fixes
* 18 20/11/2002 MRC Made the last granule in the chain unusable
* 19 21/05/2003 MRC Changed granule chain initialisation to avoid
* RTP statistics memory
* 20 23/07/2004 MRC Fixed some compiler warnings
* 21 08/06/2005 MRC Amended memory area checks in GmConfigure
*
*******************************************************************************/
/***************** INCLUDE FILES *****************************/
#include "zl5011x.h"
#include "zl5011xGm.h"
#include "zl5011xGmMap.h"
#include "zl5011xAdm.h"
#include "zl5011xAdmMap.h"
#include "zl5011xRtpMap.h"
#include "zl5011xUtilLib.h"
/*******************************************************************************
Function:
zl5011xGmInit
Description:
This function initialises the GM block and data structure.
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xGmInit(zl5011xParamsS *zl5011xParams)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmInit:", 0, 0, 0, 0, 0, 0);
zl5011xParams->packetMemory.granuleHeadIndex = (Uint32T)ZL5011X_NOT_INITIALISED;
zl5011xParams->packetMemory.granuleTailIndex = (Uint32T)ZL5011X_NOT_INITIALISED;
return(status);
}
/*******************************************************************************
Function:
zl5011xGmConfigure
Description:
This function configures the granule manager. The memory manager must
already be initialised, since the base addresses for the granules and
descriptors is used in this function.
The number of granules is configured, and the granules initialised.
The head granule is number 1.
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
None
Returns:
zlStatusE
Remarks:
The number of granules actually available will be numGranules - 2, to
provide an empty granule at each end of the chain.
*******************************************************************************/
zlStatusE zl5011xGmConfigure(zl5011xParamsS *zl5011xParams, Uint32T numGranules)
{
zlStatusE status = ZL5011X_OK;
Uint32T loop, statsAddress, headGranule, prevGranule[2], granuleCount;
Uint32T endInternal, endExternal;
zl5011xBooleanE descInternal, dataInternal;
ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmConfigure: num granules %d",
numGranules, 0, 0, 0, 0, 0);
/* work out where the RTP stats are going to be in the memory map */
statsAddress = ZL5011X_RTP_STATS_BASE;
statsAddress &= (zl5011xParams->packetMemory.extMemSizeBytes - 1);
/* use variables to hold the end address of the internal and external memory areas */
endInternal = ZL5011X_INT_MEM_BASE + ZL5011X_INT_MEMORY_SIZE_IN_BYTES;
endExternal = ZL5011X_EXT_MEM_BASE + zl5011xParams->packetMemory.extMemSizeBytes;
/* determine whether the descriptors are in internal or external memory */
if (zl5011xParams->packetMemory.granDescBaseAddr >= ZL5011X_INT_MEM_BASE)
{
descInternal = ZL5011X_TRUE;
}
else
{
descInternal = ZL5011X_FALSE;
}
/* determine whether the granules are in internal or external memory */
if (zl5011xParams->packetMemory.granBaseAddr >= ZL5011X_INT_MEM_BASE)
{
dataInternal = ZL5011X_TRUE;
}
else
{
dataInternal = ZL5011X_FALSE;
}
/* determine whether the heap is in internal or external memory and then
update the relevant end address */
if (zl5011xParams->packetMemory.heapStartAddress >= ZL5011X_INT_MEM_BASE)
{
endInternal = zl5011xParams->packetMemory.heapStartAddress;
}
else
{
endExternal = zl5011xParams->packetMemory.heapStartAddress;
}
/* Option 1 : Granules INTERNAL, Descriptors INTERNAL */
if ((dataInternal == ZL5011X_TRUE) && (descInternal == ZL5011X_TRUE))
{
/* Do the memory check, assuming that the granules will be at a
lower address than the granule descriptors */
if ((zl5011xParams->packetMemory.granDescBaseAddr +
(numGranules * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) > endInternal)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
if ((zl5011xParams->packetMemory.granBaseAddr +
(numGranules * ZL5011X_GRANULE_DATA_SIZE)) > zl5011xParams->packetMemory.granDescBaseAddr)
{
status = ZL5011X_PARAMETER_INVALID;
}
}
}
/* Option 2 : Granules EXTERNAL, Descriptors INTERNAL */
if ((dataInternal == ZL5011X_FALSE) && (descInternal == ZL5011X_TRUE))
{
/* check that the memory sizes do not exceed the memory available */
if ((zl5011xParams->packetMemory.granDescBaseAddr +
(numGranules * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) > endInternal)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
if ((zl5011xParams->packetMemory.granBaseAddr +
(numGranules * ZL5011X_GRANULE_DATA_SIZE)) > endExternal)
{
status = ZL5011X_PARAMETER_INVALID;
}
}
}
/* Option 3 : Granules EXTERNAL, Descriptors EXTERNAL */
if ((dataInternal == ZL5011X_FALSE) && (descInternal == ZL5011X_FALSE))
{
/* Do the memory check, assuming that the granules will be at a
lower address than the granule descriptors */
if ((zl5011xParams->packetMemory.granDescBaseAddr +
(numGranules * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) > endExternal)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
if ((zl5011xParams->packetMemory.granBaseAddr +
(numGranules * ZL5011X_GRANULE_DATA_SIZE)) > zl5011xParams->packetMemory.granDescBaseAddr)
{
status = ZL5011X_PARAMETER_INVALID;
}
}
}
/* Option 4 : Granules INTERNAL, Descriptors EXTERNAL
bad choice, but included for completeness */
if ((dataInternal == ZL5011X_TRUE) && (descInternal == ZL5011X_FALSE))
{
/* check that the memory sizes do not exceed the memory available */
if ((zl5011xParams->packetMemory.granDescBaseAddr +
(numGranules * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) > endExternal)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
if ((zl5011xParams->packetMemory.granBaseAddr +
(numGranules * ZL5011X_GRANULE_DATA_SIZE)) > endInternal)
{
status = ZL5011X_PARAMETER_INVALID;
}
}
}
/* initialise the granule chain */
granuleCount = 0;
headGranule = (Uint32T)-1;
prevGranule[0] = 1;
/* granule 0 is not included in the granule chain, and is a special case,
since the next granule is set to 0 i.e. a loop. */
if (status == ZL5011X_OK)
{
status = zl5011xWrite(zl5011xParams,
zl5011xParams->packetMemory.granDescBaseAddr,
0);
}
for (loop = 1; loop < numGranules - 1; loop++)
{
/* if a failure has occured, or occurs during the initialisation
then bomb out */
if (status != ZL5011X_OK)
{
break;
}
if ((((zl5011xParams->packetMemory.granDescBaseAddr + (loop * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) < statsAddress) ||
((zl5011xParams->packetMemory.granDescBaseAddr + (loop * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) >= (statsAddress + ZL5011X_RTP_STATS_MEM_SIZE))) &&
(((zl5011xParams->packetMemory.granBaseAddr + (loop * ZL5011X_GRANULE_DATA_SIZE)) < statsAddress) ||
((zl5011xParams->packetMemory.granBaseAddr + (loop * ZL5011X_GRANULE_DATA_SIZE)) >= (statsAddress + ZL5011X_RTP_STATS_MEM_SIZE))))
{
/* not in the region used for RTP statistics, so okay to define a
granule and descriptor */
if (headGranule == (Uint32T)-1)
{
/* if not already seen a valid granule then mark this as the
head of the chain */
headGranule = loop;
}
/* setup the granule descriptor for the previous granule, now that we
know the next one on in the chain */
status = zl5011xWrite(zl5011xParams,
zl5011xParams->packetMemory.granDescBaseAddr + (prevGranule[0] * ZL5011X_GRANULE_DESCRIPTOR_SIZE),
(loop & ZL5011X_GRANULE_NEXT_GRN_MASK) << ZL5011X_GRANULE_NEXT_GRN_BITS);
prevGranule[1] = prevGranule[0];
prevGranule[0] = loop;
granuleCount++;
}
}
if (status == ZL5011X_OK)
{
/* for the last granule descriptor in the chain, set the NEXT_GRN to 0 */
status = zl5011xWrite(zl5011xParams,
zl5011xParams->packetMemory.granDescBaseAddr + (prevGranule[0] * ZL5011X_GRANULE_DESCRIPTOR_SIZE),
0);
}
/* set the head granule */
if (status == ZL5011X_OK)
{
status = zl5011xGmSetHeadGranule(zl5011xParams, headGranule);
}
/* set the tail granule to be the 2nd granule from the end of the chain */
if (status == ZL5011X_OK)
{
status = zl5011xGmSetTailGranule(zl5011xParams, prevGranule[1]);
}
/* set the number of free granules */
if (status == ZL5011X_OK)
{
status = zl5011xGmSetNumFreeGranules(zl5011xParams, granuleCount - 1);
}
/* by default, set the threshold to the maximum number of granules */
if (status == ZL5011X_OK)
{
status = zl5011xGmSetGranuleThreshold(zl5011xParams, granuleCount - 1);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xGmSetHeadGranule
Description:
Sets the index number of the head granule.
Inputs:
zl5011xParams Pointer to the structure for this device instance
index sets the index number of the head granule
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xGmSetHeadGranule(zl5011xParamsS *zl5011xParams, Uint32T index)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmSetHeadGranule: index %d",
index, 0, 0, 0, 0, 0);
if ((index & ~ZL5011X_GM_GRANULE_INDEX_MASK) != 0)
{
status = ZL5011X_PARAMETER_INVALID;
}
if (status == ZL5011X_OK)
{
status = zl5011xWrite(zl5011xParams, ZL5011X_GM_GRANULE_HEAD,
index << ZL5011X_GM_GRANULE_HEAD_BITS);
zl5011xParams->packetMemory.granuleHeadIndex = index;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xGmGetHeadGranule
Description:
Gets the index number of the head granule.
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
index gets the index number of the head granule
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xGmGetHeadGranule(zl5011xParamsS *zl5011xParams, Uint32T *index)
{
zlStatusE status = ZL5011X_OK;
Uint32T readValue;
ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmGetHeadGranule:", 0, 0, 0, 0, 0, 0);
status = zl5011xRead(zl5011xParams, ZL5011X_GM_GRANULE_HEAD,
&readValue);
if (status == ZL5011X_OK)
{
*index = (readValue >> ZL5011X_GM_GRANULE_HEAD_BITS) & ZL5011X_GM_GRANULE_INDEX_MASK;
ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmGetHeadGranule: index %d", *index, 0, 0, 0, 0, 0);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xGmSetTailGranule
Description:
Sets the index number of the tail granule. This function will be called during
initialisation of the granule chain, so the granules will have been sequentially
assigned. The tail granule is therefore the last granule.
Inputs:
zl5011xParams Pointer to the structure for this device instance
index sets the index number of the tail granule
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xGmSetTailGranule(zl5011xParamsS *zl5011xParams, Uint32T index)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmSetTailGranule: index %d", index, 0, 0, 0, 0, 0);
if ((index & ~ZL5011X_GM_GRANULE_INDEX_MASK) != 0)
{
status = ZL5011X_PARAMETER_INVALID;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -