📄 davrecpr.c
字号:
### This function is used to determine whether an object has
### some portion of itself in a block, and if that portion is
### valid in order to copy. It also determines when reclaim
### is done (by the reclaim table object).
###
### PARAMETERS:
### search_info_ptr - Current object information.
### block_number - Current block under reclaim.
###
### RETURNS:
### TRUE - block is complete (nothing to copy in curr block)
### FALSE - continue copying valid data and reading headers.
###
*/
static BOOLEAN QualifyObjectInfo(const HDR_SearchInfo *search_info_ptr,
UINT32 block_number)
{
int in_block;
UINT32 curr_obj_size;
/* Calculate the object size as the sum of the header and */
/* its data. */
curr_obj_size = HDR_CalcHeaderSize(search_info_ptr->HeaderPtr);
/* Make sure that some portion of this object is in the block. */
if (HDR_GetAlignmentAttr(search_info_ptr->HeaderPtr->Attr16) ==
HDR_HA_AlignPara)
{
curr_obj_size += search_info_ptr->CurrObj.ObjectSize;
}
ReclaimState.ObjectBaseAddr =
HDR_CalcNextHdrAddr(search_info_ptr->CurrObj.HeaderAddress,
(UINT16)HDR_GetAlignmentAttr((search_info_ptr->HeaderPtr->Attr16)),
search_info_ptr->HeaderPtr->NameSize,
search_info_ptr->CurrObj.ObjectSize) +
HDR_FixedSizeP;
ReclaimState.ObjectEndAddr =
ReclaimState.ObjectBaseAddr + curr_obj_size - 1;
in_block = IsInBlock(ReclaimState.ObjectBaseAddr,
ReclaimState.ObjectEndAddr, block_number);
if (in_block == 1)
{
/* This object is completely before this block, thus, */
/* read the next object. */
return FALSE;
}
if (HDR_GetAbsorbedAttr(search_info_ptr->HeaderPtr->Attr16) ==
HDR_HA_Exists)
{
/* If we have a Valid object, copy it out of the block. */
if ((HDR_GetHdrState(search_info_ptr->HeaderPtr->Attr16) ==
HDR_HA_STATE_Valid) ||
(HDR_GetAlignmentAttr(search_info_ptr->HeaderPtr->Attr16) ==
HDR_HA_AlignPage))
{
ReclaimState.NextState = (UINT16)RECLAIM_ST_CalcParameters;
if (search_info_ptr->HeaderPtr->ObjectType == FDI_HT_ReclaimTable)
{
ReclaimState.NextState = (UINT16)RECLAIM_ST_ReclaimComplete;
return TRUE;
}
if (in_block == -1)
{
/* This object is completely below this block number, thus, */
/* move on to the next block, but don't read the next */
/* object when the block that this object is in gets there. */
return TRUE;
}
}
else
{
ReclaimState.NextState = (UINT16)RECLAIM_ST_ProcessInvalidObj;
}
}
else
{
ReclaimState.NextState = (UINT16)RECLAIM_ST_ProcessInvalidObj;
}
return FALSE;
}
/*### Global Functions
//#########################*/
/*########################################################################
### RECPARA_InitReclaimTable
###
### DESCRIPTION:
### This function will initialize the reclaim table with the
### first header address in header block. It will also perform
### the appropriate power loss recovery methods indicated by
### the CSPEC.
###
### PARAMETERS:
### obj_info_ptr - Reclaim table object information.
### rec_tbl_addr - Base address of reclaim table object.
### table_info_ptr - Reclaim Table Info structure.
###
### RETURNS:
### ERR_NONE - When operation is successful.
###
*/
ERR_CODE RECPARA_InitReclaimTable(HDR_SearchInfoPtr obj_info_ptr,
FDI_Handle rec_tbl_addr,
const RECTBL_TableInfo *table_info_ptr,
BOOLEAN restart)
{
UINT16 prev_status16;
UINT32 current_block, header_block;
ERR_CODE status = ERR_NONE;
RECTBL_TableEntry rec_tbl_entry;
/* Start searching at the beginning of the header table. */
obj_info_ptr->CurrObj.HeaderAddress = 0;
obj_info_ptr->CurrObj.ConfigEntry.Offset = 0;
obj_info_ptr->CurrObj.ConfigEntry.Status = 0;
current_block = table_info_ptr->FirstBlock;
header_block = FDI_InvalidBlockNumber;
status = ERR_NONE;
/* Set to Invalid so the previous status is marked invalid */
/* on the first round through the loop. */
obj_info_ptr->HeaderPtr->Attr16 =
HDR_SetStatusAttr((obj_info_ptr->HeaderPtr->Attr16), HDR_HA_Invalid);
while (!status)
{
prev_status16 = obj_info_ptr->HeaderPtr->Attr16;
status = GetNextHeader(obj_info_ptr, HDR_ByNextObject, 0, restart);
if (status)
{
if (status == ERR_NO_MORE_ENTRIES)
{
break;
}
return status;
}
/* Calculate the block number of the next header. */
header_block = Handle2Block(obj_info_ptr->CurrObj.HeaderAddress);
/* Init reclaim table block entries with no valid FHL entry. */
RECTBL_InitStatusEntry(rec_tbl_entry);
if (header_block < current_block)
{
while (current_block != header_block)
{
/* Write entry with FirstHeaderLocation as Empty */
RECTBL_InitStatus(rec_tbl_entry);
RECTBL_SetFirstHeaderLocation(rec_tbl_entry,
RECTBL_NoFirstHeaderMarker);
status = RECTBL_WriteTable(rec_tbl_addr,
current_block, &rec_tbl_entry, TRUE, restart);
if (status)
{
return status;
}
current_block--;
}
}
/* Init the current block with the valid header entry. */
if (header_block <= current_block)
{
/* Write the current block entry with a valid FHL */
RECTBL_MarkValidFHL(rec_tbl_entry);
RECTBL_SetFirstHeaderLocation(rec_tbl_entry,
obj_info_ptr->CurrObj.HeaderAddress);
/* If the previous object was valid, set the PVO bit. */
if (HDR_GetHdrState(prev_status16) == HDR_HA_STATE_Invalid)
{
RECTBL_MarkPreviousValidObject(rec_tbl_entry,
RECTBL_PVO_NoPrevValid);
}
else
{
RECTBL_MarkPreviousValidObject(rec_tbl_entry,
RECTBL_PVO_PrevValid);
}
if ((HDR_GetAlignmentAttr(prev_status16) == HDR_HA_AlignPage) &&
(HDR_GetAbsorbedAttr(prev_status16) == HDR_HA_Exists))
{
RECTBL_MarkPreviousValidObject(rec_tbl_entry,
RECTBL_PVO_PrevValid);
}
status = RECTBL_WriteTable(rec_tbl_addr,
current_block, &rec_tbl_entry, TRUE, restart);
if (status)
{
return status;
}
if (current_block == 0)
{
break;
}
current_block--;
}
}
if (status == ERR_NO_MORE_ENTRIES)
{
status = ERR_NONE;
}
if (status)
{
return status;
}
/* Tell recovery that the reclaim table is now initialized. */
status = RECTBL_MarkTableComplete((FDI_Handle)0,
ReclaimState.RecTblBaseAddr, FALSE, restart);
return status;
}
/*########################################################################
### RECPARA_SaveValidObjsInCurrBlock
###
### DESCRIPTION:
### This is the main paragraph reclaim state machine. It is
### responsible for copying valid objects out of a block,
### erasing it, and copying any valid objects back from the
### reclaim block when it is used.
###
### PARAMETERS:
### none.
###
### RETURNS:
### ERR_NONE - When operation is successful.
###
*/
ERR_CODE RECPARA_SaveValidObjsInCurrBlock(BOOLEAN restart)
{
int in_blk;
UINT32 bytes_in_block, bytes_in_header;
UINT32 bytes_in_free_block, bytes_in_reclaim_block;
UINT32 block_number;
BOOLEAN process_next_block;
BOOLEAN exit_state_machine;
ERR_CODE status = ERR_NONE;
block_number = ReclaimState.CurrentBlock2Reclaim;
/* Mark the current block status to ReclaimInProgress. */
RECTBL_ReadTable(ReclaimState.RecTblBaseAddr,
block_number, &ReclaimState.RecTblEntry, TRUE, restart);
RECTBL_MarkReclaimInProgress(ReclaimState.RecTblEntry);
status = RECTBL_WriteTable(ReclaimState.RecTblBaseAddr,
block_number, &ReclaimState.RecTblEntry, TRUE, restart);
EVT_Test4Crash(EVT_RECLAIM_StateF_1);
if (status)
{
return(status);
}
/* ParaReclaimStateMachine: */
exit_state_machine = FALSE;
do
{
switch (ReclaimState.NextState)
{
case RECLAIM_ST_ReadNextObj:
if (!ReclaimState.SingleSkipRead)
{
/* Just read the next object & calculate its base address */
status = GetNextHeader((HDR_SearchInfoPtr)&SearchInfo,
HDR_ByNextObject, 0, restart);
if (status)
{
return status;
}
if (Handle2Block(SearchInfo.CurrObj.HeaderAddress) <=
ReclaimState.CurrentBlock2Reclaim)
{
ReclaimState.HeaderCopied = FALSE;
}
else
{
ReclaimState.HeaderCopied = TRUE;
}
}
else
{
ReclaimState.SingleSkipRead = FALSE;
}
process_next_block = QualifyObjectInfo(&SearchInfo, block_number);
if (!ReclaimState.HeaderCopied)
{
/* Mark source header id as ReclaimInProgress. */
HDR_ID_MarkReclaimInProgress((SearchHeader.HeaderId));
status = FLASH_WriteBuffer(SearchInfo.CurrObj.HeaderAddress,
(MemBufferPtr)&SearchHeader.HeaderId,
sizeof(SearchHeader.HeaderId));
if (status)
{
return status;
}
EVT_Test4Crash(EVT_RECLAIM_StateF_2c);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -