📄 davrecrv.c
字号:
HDR_ST_ReclaimInProgress)
{
RecoverState.State = RECRCVR_RelocateReclaimTable;
}
else
{
if (HDR_ID_GetReclaimState(SearchHeader.HeaderId) ==
HDR_ST_Normal)
{
RecoverState.State = RECRCVR_StartStateMachine;
}
else
{
return ERR_SYSTEM;
}
}
}
else
{
if (HDR_GetStatusAttr(SearchHeader.Attr16) ==
HDR_HA_WriteInProgress)
{
RecoverState.State = RECRCVR_InitReclaimTable;
}
else
{
if (HDR_GetStatusAttr(SearchHeader.Attr16) ==
HDR_HA_Valid)
{
RecoverState.State = RECRCVR_StartStateMachine;
}
else
{
return ERR_SYSTEM;
}
}
}
break;
case (RSLT_HeaderNoTable | RSLT_RBNoTable):
/* Could have been creating the reclaim table and */
/* not finished the header. */
if (paragraph_reclaim)
{
/* The configuration header offset would indicate this */
/* state before getting here. */
return ERR_SYSTEM;
}
else
{
if (HDR_GetStatusAttr(SearchHeader.Attr16) ==
HDR_HA_WriteInProgress)
{
RecoverState.State = RECRCVR_InitReclaimTable;
}
else
{
/* Table was not being created, the headers */
/* haven't been absorbed. */
RecoverState.State = RECRCVR_FinishUpReclaim;
}
}
break;
case (RSLT_NoTable | RSLT_RBNoTable):
/* Must have not finished marking the config offset to */
/* reclaim complete. */
if (paragraph_reclaim)
{
RecoverState.State = RECRCVR_FinishUpReclaim;
}
else
{
return ERR_SYSTEM;
}
break;
default:
{};
}
return ERR_NONE;
}
/*### Global Functions
//#########################*/
/*########################################################################
### RECRCVR_LocateTO_N_FROMBlocks
###
### DESCRIPTION:
### This function will go through the reclaim table and locate
### the TO and FROM block information. For paragraph reclaim
### it will also locate the FirstHeaderLocation.
###
### NOTE: ReclaimState.RecTblBaseAddr must contain a
### completely initialized reclaim table.
###
### PARAMETERS:
### paragraph_reclaim - Indicates special processing for
### page vs. paragraph reclaim.
###
### RETURNS:
### ERR_NONE - When operation is successful.
###
*/
ERR_CODE RECRCVR_LocateTO_N_FROMBlocks(BOOLEAN paragraph_reclaim, BOOLEAN restart)
{
UINT32 ii;
UINT32 current_block;
ERR_CODE status = ERR_NONE;
RECTBL_TableEntry prev_entry;
RecoverState.TOBlock = FDI_InvalidBlockNumber;
RecoverState.FHLBlock = FDI_InvalidBlockNumber;
RecoverState.FROMBlock = FDI_InvalidBlockNumber;
RECTBL_InitStatusEntry(prev_entry);
/* Loop through the reclaim table looking for certain properties. */
current_block = ReclaimState.TableInfo.FirstBlock;
for (ii = 0; ii < ReclaimState.TableInfo.TotalBlocks; ii++)
{
RECTBL_ReadTable(ReclaimState.RecTblBaseAddr, current_block,
&ReclaimState.RecTblEntry, paragraph_reclaim, restart);
/* Search the reclaim table for any blocks marked EraseInProgress */
/* and no EraseComplete or CopyComplete and no EraseInProgress. */
if ((RECTBL_IsEraseInProgress(ReclaimState.RecTblEntry) &&
!RECTBL_IsEraseComplete(ReclaimState.RecTblEntry)) ||
(RECTBL_IsCopyComplete(ReclaimState.RecTblEntry) &&
!RECTBL_IsEraseInProgress(ReclaimState.RecTblEntry)))
{
/* Mark the block as EraseInProgress. */
RECTBL_MarkEraseInProgress(ReclaimState.RecTblEntry);
status = RECTBL_WriteTable(ReclaimState.RecTblBaseAddr,
current_block, &ReclaimState.RecTblEntry,
paragraph_reclaim, restart);
if (status)
{
return status;
}
/* Erase the block. */
status = FLASH_EraseBlock(Block2Handle(current_block), FALSE);
if (status)
{
return status;
}
/* Mark the block as EraseComplete. */
RECTBL_MarkEraseComplete(ReclaimState.RecTblEntry);
status = RECTBL_WriteTable(ReclaimState.RecTblBaseAddr,
current_block, &ReclaimState.RecTblEntry,
paragraph_reclaim, restart);
if (status)
{
return status;
}
}
/* Check to see if the block has been erased and there is */
/* data in the reclaim block to be copied back. */
if (RECTBL_IsEraseComplete(ReclaimState.RecTblEntry) &&
!RECTBL_IsCopyComplete(ReclaimState.RecTblEntry))
{
/* Pretend the entire block contains valid data. */
MemMap.RecBlk.BytesUsed = FDI_BlockSize;
MemMap.RecBlk.BaseAddr = FDI_ReclaimBlockAddress;
MemMap.FreeBlk.BaseAddr = Block2Handle(current_block);
if (Handle2Block(ReclaimState.RecTblBaseAddr) ==
Handle2Block(FDI_ReclaimBlockAddress))
{
if (paragraph_reclaim)
{
MemMap.RecBlk.BytesUsed -= RECTBL_ParaRecTblSize;
MemMap.RecBlk.BaseAddr += RECTBL_ParaRecTblSize;
MemMap.FreeBlk.BaseAddr += RECTBL_ParaRecTblSize;
}
else
{
MemMap.RecBlk.BytesUsed -= RECTBL_PageRecTblSize;
}
}
status = FLASH_CopyFlash(MemMap.RecBlk.BaseAddr,
MemMap.FreeBlk.BaseAddr, MemMap.RecBlk.BytesUsed);
if (status)
{
return status;
}
RECTBL_MarkCopyComplete((ReclaimState.RecTblEntry));
status = RECTBL_WriteTable(ReclaimState.RecTblBaseAddr,
current_block, &ReclaimState.RecTblEntry,
paragraph_reclaim, restart);
if (status)
{
return status;
}
}
/* Check to see if there is a possibility that the reclaim */
/* block did not finish getting erased. */
if ((!RECTBL_IsReclaimInProgress(ReclaimState.RecTblEntry)) &&
RECTBL_IsCopyComplete(prev_entry))
{
if (Handle2Block(FDI_ReclaimBlockAddress) !=
Handle2Block(ReclaimState.RecTblBaseAddr))
{
status = FLASH_EraseBlock(FDI_ReclaimBlockAddress, FALSE);
if (status)
{
return status;
}
}
/* Mark the current block to RIP so we don't erase the */
/* reclaim block again. */
RECTBL_MarkReclaimInProgress((ReclaimState.RecTblEntry));
status = RECTBL_WriteTable(ReclaimState.RecTblBaseAddr,
current_block, &ReclaimState.RecTblEntry,
paragraph_reclaim, restart);
if (status)
{
return status;
}
}
if (RecoverState.TOBlock == FDI_InvalidBlockNumber)
{
/* Locate the first entry in the reclaim table with */
/* TOBlock = no [Done] bit marked. */
if (!RECTBL_IsBlockDone(ReclaimState.RecTblEntry))
{
RecoverState.TOBlock = current_block;
RecoverState.TOReclaimStatus = ReclaimState.RecTblEntry;
}
}
if (RecoverState.FROMBlock == FDI_InvalidBlockNumber)
{
/* Locate the first entry in the reclaim table with */
/* no [CC] bit marked = FROMBlock. */
if (!RECTBL_IsCopyComplete(ReclaimState.RecTblEntry) &&
!RECTBL_IsBlockDone(ReclaimState.RecTblEntry))
{
RecoverState.FROMBlock = current_block;
RecoverState.FROMReclaimStatus = ReclaimState.RecTblEntry;
}
}
/* Locate the first valid FHL including and beyond the */
/* FROMBlock. */
if ((RecoverState.FHLBlock == FDI_InvalidBlockNumber) &&
(RecoverState.FROMBlock != FDI_InvalidBlockNumber))
{
if (RECTBL_IsValidFHL(ReclaimState.RecTblEntry) &&
!RECTBL_IsEraseComplete(ReclaimState.RecTblEntry))
{
RecoverState.FHLBlock = current_block;
RecoverState.FHLReclaimStatus = ReclaimState.RecTblEntry;
}
}
if (paragraph_reclaim)
{
current_block--;
}
else
{
current_block++;
}
prev_entry = ReclaimState.RecTblEntry;
}
/* If we don't find the TO and FROM headers then */
/* there is a problem. */
if (RecoverState.FROMBlock == FDI_InvalidBlockNumber)
{
if (paragraph_reclaim)
{
RecoverState.FROMBlock = current_block + 1;
}
else
{
RecoverState.FROMBlock = current_block - 1;
}
}
return ERR_NONE;
}
/*########################################################################
### RECRCVR_CalcReclaimRestartState
###
### DESCRIPTION:
### This function will calculate the state of the reclaim table,
### where is it & what is the next reclaim state should be. It
### will also setup any globals necessary to restart reclaim.
###
### NOTE: ReclaimState.ConfigEntry must contain an authentic
### configuration header entry!
###
### PARAMETERS:
### paragraph_reclaim - Indicates special processing for
### page vs. paragraph reclaim.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -