📄 davpagerecl.c
字号:
/* Copyright (c) 1995-2004 Intel Corporation */
/* Intel Confidential */
/* ###########################################################################
### DAV Page Reclaim
###
### Module: davpagerecl.c - Fixed Header module
###
### $Workfile: DavPageRecl.c $
### $Revision: 23 $
### $NoKeywords: $
########################################################################### */
/*
*****************************************************************
* NOTICE OF LICENSE AGREEMENT
*
* This code is provided by Intel Corp., and the use is governed
* under the terms of a license agreement. See license agreement
* for complete terms of license.
*
* YOU MAY ONLY USE THE SOFTWARE WITH INTEL FLASH PRODUCTS. YOUR
* USE OF THE SOFTWARE WITH ANY OTHER FLASH PRODUCTS IS EXPRESSLY
* PROHIBITED UNLESS AND UNTIL YOU APPLY FOR, AND ARE GRANTED IN
* INTEL'S SOLE DISCRETION, A SEPARATE WRITTEN SOFTWARE LICENSE
* FROM INTEL LICENSING ANY SUCH USE.
*****************************************************************
*/
/*### Include Files
#########################*/
#include "DavLib.h"
#if (DIRECT_ACCESS_VOLUME == TRUE)
#include "DavCfgTbl.h"
#include "DavPaRecl.h"
#include "DavSearch.h"
#include "DavRtTbl.h"
#include "DavRatTbl.h"
#include "davmodob.h"
#include "DavPageRecl.h"
/*### Local Declarations
#########################*/
/*### Global Declarations
#########################*/
PAGE_RECLAIM_Address GlbReclaimRef;
/*### Local Functions
#########################*/
ERR_CODE RECLAIM_PAGE_InitializeOttTable(PAGE_RECLAIM_Address* aRef);
/*Fix Start:SCR964 */
ERR_CODE RECLAIM_PAGE_InitializeRtTableCompleteRestOfBlocks(UINT16 aEndBlock1, UINT16 aEndBlock2, EnBlockOperation aObjState[], UINT16 aRtMoveIndex);
/*Fix End:SCR964 */
ERR_CODE RECLAIM_PAGE_InitializeRtTable(PAGE_RECLAIM_Address* aRef);
ERR_CODE RECLAIM_PAGE_InitializeRatTable(PAGE_RECLAIM_Address* aRef);
ERR_CODE RECLAIM_PAGE_ModifyUserObjects(PAGE_RECLAIM_Address* aRef);
/*### Global Functions
#########################*/
/*#################################################################
### RECLAIM_PAGE_InitializeRtTableCompleteRestOfBlocks
###
### DESCRIPTION:
### This function is used to complete the initialization of
### of the rt table when there are no more matching entries
### in the ott table. When this condition occurs, it is an
### indication the remaining blocks are deleted.
###
### PARAMETERS:
### aEndBlock1 -- IN: The last block referenced in the OTT table
### aEndBlock2 -- IN: The last working block
### aObjState -- IN: The state array for the blocks between
### the last ott block and the last working block.
### aRtMoveIndex -- IN: The index into the state array
###
### RETURNS:
### When this function passes with no errors a value of 0 is
### returned otherwise, it returns a status of type ERR_CODE.
###*/
/*Fix Start:SCR964 */
ERR_CODE RECLAIM_PAGE_InitializeRtTableCompleteRestOfBlocks(
UINT16 aEndBlock1, UINT16 aEndBlock2, EnBlockOperation aObjState[], UINT16 aRtMoveIndex)
{
UINT16 rtIndex;
/*Fix End:SCR964 */
if(aEndBlock1 == aEndBlock2)
{
/* Objects in the ott determined the state of the block */
return ERR_NONE;
}
for(rtIndex=aEndBlock1+1, aRtMoveIndex=aRtMoveIndex+1; rtIndex<= aEndBlock2; rtIndex++, aRtMoveIndex++)
{
aObjState[aRtMoveIndex] = enBlockOperationErase;
}
return ERR_NONE;
}
/*#################################################################
### RECLAIM_PAGE_InitializeRtTable
###
### DESCRIPTION:
### This function create the rt table based on the ott table.
###
### PARAMETERS:
### aRef -- IN: Parameter used throughout the page reclaim.
###
### RETURNS:
### When this function passes with no errors a value of 0 is
### returned otherwise, it returns a status of type ERR_CODE.
###*/
ERR_CODE RECLAIM_PAGE_InitializeRtTable(PAGE_RECLAIM_Address* aRef)
{
ERR_CODE status = ERR_NONE;
FDI_Handle unusedHandle;
OTTTBL_EntryPtr ottEntryPtr;
OTTTBL_Leader ottLeader;
/*Fix Start:SCR964 */
UINT16 ottIndex;
UINT16 ottObjStartBlock;
UINT16 ottObjEndBlock;
UINT16 numberBlocks;
EnBlockOperation rtOprRequired[RTTBL_MaxEntries];
UINT16 rtIndex;
RTTBL_Entry rtEntry;
RTTBL_Leader rtLeader;
UINT16 rtMoveIndex;
UINT16 rtStartBlock;
UINT16 rtEndBlock1;
UINT16 rtEndBlock2;
UINT16 rtBlockNotUsed;
/*Fix End:SCR964 */
BOOLEAN forceCopyCandidate;
/* POWER-LOSS */
if(aRef->plrRestart == TRUE)
{
/* Can we get a complete RTTBL? */
status = RTTBL_GetFirstRtEntry(&unusedHandle, &rtEntry, &rtLeader);
if(status != ERR_NONE)
{
if(status != ERR_NOTEXISTS)
{
return ERR_STATE;
}
}
else
{
/* Nothing further to do */
return status;
}
/* We are restarting, insure that the OTT is re-read */
aRef->sramOttEntries = 0;
}
/* Is the OTT list in sram? */
if(aRef->sramOttEntries == 0)
{
/* No. Read it in */
status = OTTTBL_ReadTableIntoSRAM(&ottLeader, &unusedHandle,
&aRef->sramOttEntriesList[0], sizeof(aRef->sramOttEntriesList), &aRef->sramOttEntries);
if(status != ERR_NONE)
{
return status;
}
}
else
{
/* Yes. The list is sram, however, not the OTT Leader */
status = OTTTBL_GetFirstOttEntry(&unusedHandle, &aRef->sramOttEntriesList[0], &ottLeader);
if(status != ERR_NONE)
{
return status;
}
}
/* Initialize array */
UTIL_ClearVariable((UINT8*)&rtOprRequired[0], sizeof(rtOprRequired), enBlockOperationNone);
/* REALLOCATE OPERATION */
if(aRef->reclaimType == enPageReallocate)
{
/* Compute the number of blocks the object spans */
numberBlocks = OTTTBL_GetEndWorkBlockNumber(&ottLeader) - OTTTBL_GetStartWorkBlockNumber(&ottLeader) + 1;
/* Create a RT table for each span block */
/* Each block will have no operation required, therefore, forces a skip when moving objects */
status = CFGTBL_Allocate_RTTBL(OTTTBL_GetEndWorkBlockNumber(&ottLeader), numberBlocks, &rtOprRequired[0]);
if(status != ERR_NONE)
{
return status;
}
return ERR_NONE; /* Rt Init */
}
/* FULL-DEFRAG/PARTIAL-DEFRAG/RECLAIM-IN-PLACE OPERATION */
/* Special case - Only a blocks to erase */
if(OTTTBL_GetNumRows(&ottLeader) == 0)
{
/* Set this block such that they will be erased */
for(rtIndex=OTTTBL_GetStartWorkBlockNumber(&ottLeader),rtMoveIndex=0; rtIndex<=OTTTBL_GetEndWorkBlockNumber(&ottLeader); rtIndex++, rtMoveIndex++)
{
rtOprRequired[rtMoveIndex] = enBlockOperationErase;
}
numberBlocks = OTTTBL_GetEndWorkBlockNumber(&ottLeader) - OTTTBL_GetStartWorkBlockNumber(&ottLeader) + 1;
status = CFGTBL_Allocate_RTTBL(OTTTBL_GetEndWorkBlockNumber(&ottLeader), numberBlocks, &rtOprRequired[0]);
if(status != ERR_NONE)
{
return status;
}
return ERR_NONE;
}
/* Normal case - Blocks that may have work to do */
/* [<- OTTFirstBlock, OTTMiddleBlock, OTTEndBlock->] */
rtStartBlock = OTTTBL_GetStartWorkBlockNumber(&ottLeader);
OTTTBL_CalcDestinationBlockRange(&aRef->sramOttEntriesList[OTTTBL_GetNumRows(&ottLeader)-1], &rtBlockNotUsed,
&rtEndBlock1);
rtEndBlock2 = OTTTBL_GetEndWorkBlockNumber (&ottLeader);
ottIndex = 0;
rtMoveIndex = 0;
for(rtIndex=rtStartBlock,rtMoveIndex=0; rtIndex<=rtEndBlock1; rtIndex++, rtMoveIndex++)
{
/* Walk through all OTT entries. Will jump out if block changes */
while(ottIndex <= OTTTBL_GetNumRows(&ottLeader))
{
/* If we are out of OTT entries, exit */
if(ottIndex == OTTTBL_GetNumRows(&ottLeader))
{
/* All remaining blocks are to be erased */
status = RECLAIM_PAGE_InitializeRtTableCompleteRestOfBlocks(rtEndBlock1, rtEndBlock2, &rtOprRequired[0], rtMoveIndex);
if(status != ERR_NONE)
{
return status;
}
/* Jump out */
break;
}
/* Get key information from the OTT */
ottEntryPtr = &aRef->sramOttEntriesList[ottIndex];
OTTTBL_CalcDestinationBlockRange(ottEntryPtr, &ottObjStartBlock, &ottObjEndBlock);
/* The forceCopyCandidate flag: */
/* There is a case where a dirty object sits on top of a user object. This */
/* user object is the last entry in the ott table. However, no objects are */
/* moving in the block of the last entry. */
/* The problem is that the OTT_IsMoving computes that there is */
/* no-operation-required. This is correct, however, there is part of a */
/* dirty object that is on top of the last ott block has dirty data. If we */
/* accept the no-operation-required, then this dirty data in the last ott e */
/* entry block does not get erased. This is why we do this computation to */
/* force a copy of all the objects in this block. */
forceCopyCandidate = FALSE;
if(rtIndex == rtEndBlock1)
{
if(ottIndex == OTTTBL_GetNumRows(&ottLeader)-1)
{
/* If the end of the last ott object does not touch the end of the block */
if(OTTTBL_CalcSourceHandle(ottEntryPtr)+(OTTTBL_GetOttEntrySize(ottEntryPtr)*FDI_PageSize)-1 <
UTIL_CalcHandleOfBlockTopBoundary(rtIndex))
{
/* If reclaim in place, then forget it */
if(aRef->reclaimType != enPageReallocate)
{
/* We may have a dirty object above us */
forceCopyCandidate = TRUE;
}
}
}
}
if(ottObjStartBlock == rtIndex && ottObjEndBlock == rtIndex)
{
/* FULL OBJECT */
if(OTTTBL_IsMoving(&ottLeader, ottEntryPtr, forceCopyCandidate) == TRUE)
{
rtOprRequired[rtMoveIndex] = enBlockOperationCopy;
}
/* Entire object is in the block */
ottIndex++; /* next ott */
}
else if(ottObjStartBlock == rtIndex)
{
/* FIRST PART OF OBJECT */
if(OTTTBL_IsMoving(&ottLeader, ottEntryPtr, forceCopyCandidate) == TRUE)
{
rtOprRequired[rtMoveIndex] = enBlockOperationCopy;
}
/* We see the first but not the last, therefore, it spans a block */
break; /* next block */
}
else if(ottObjEndBlock == rtIndex)
{
/* LAST PART OF OBJECT */
if(OTTTBL_IsMoving(&ottLeader, ottEntryPtr, forceCopyCandidate) == TRUE)
{
rtOprRequired[rtMoveIndex] = enBlockOperationCopy;
}
/* We see the last, however, more objects may be in this block */
ottIndex++; /* next ott */
}
else if(rtIndex > ottObjStartBlock && rtIndex < ottObjEndBlock)
{
/* MIDDLE PART OF OBJECT */
if(OTTTBL_IsMoving(&ottLeader, ottEntryPtr, forceCopyCandidate) == TRUE)
{
rtOprRequired[rtMoveIndex] = enBlockOperationCopy;
}
/* We see the middle, however, not the first or last. This spans a block */
break; /* next block */
}
else
{
/* NOT IN CURRENT BLOCK */
break; /* next block */
}
} /* while next ott part or ott */
} /* for next rt */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -