📄 davbkup.c
字号:
/* Copyright (c) 1995-2004 Intel Corporation */
/* Intel Confidential */
/* ###########################################################################
### BKUP
###
### Module: davbkup.c - functions for allocating and creating object backups
###
### $Workfile: davbkup.c $
### $Revision: 11 $
### $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 "davext.h"
#include "davbkup.h"
/*### Local Declarations
#########################*/
/*### Global Declarations
#########################*/
/*### Local Functions
#########################*/
#define ExitOnError(status) \
if (status != ERR_NONE) \
{ return status; }
/* E5.5.962 Begin */
#define CleanupAndExitOnError(status) \
if(status != ERR_NONE) \
{ \
mDEBUG_CHECK_ERRCODE(status) \
MEM_CalcMemoryStatistics(FALSE); \
return status; \
}
/* E5.5.962 End */
/*### Global Functions
#########################*/
/*#################################################################
### BKUP_FindBackupFreeChunk
###
### DESCRIPTION:
### This function finds a contiguous area of free space in page
### space for backup operations. It will, if needed, create
### free chunks in order to block-align the backup area if
### requested or if a pinning issue exists.
###
### PARAMETERS:
### aRequestedSizeInPages -- size of chunk needed for backup
### aHandlePtr -- OUT: a handle to the backup area
### aBlockAlign -- flag to indicate if block alignment is preferred.
### restart -- Flag used to for PLR.
###
### 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 BKUP_FindBackupFreeChunk( UINT32 aRequestedSizeInPages,
FDI_HandlePtr aHandlePtr,
BOOLEAN aBlockAlign,
BOOLEAN restart)
{
ERR_CODE status = ERR_NONE;
FDI_Handle freePoolHandle;
UINT32 freePoolOffset;
FDI_Handle blockAlignedFreePoolHandle;
UINT32 freePoolSizeInPages;
UINT32 blockAlignedFreePoolSizeInPages;
FDI_Handle freeChunkHandle;
UINT32 freeChunkOffset;
UINT32 freeChunkEndOffset;
UINT32 freeChunkFirstBlock;
UINT32 freeChunkLastBlock;
FDI_Handle blockAlignedFreeChunkHandle;
UINT32 blockAlignedFreeChunkOffset;
UINT32 freeChunkSizeInPages;
UINT32 blockAlignedFreeChunkSizeInPages;
SEARCH_SearchInfo searchInfo;
SEARCH_CompareInfo compareInfo;
/* initialize the returned handle to an invalid address */
*aHandlePtr = FDI_InvalidObjAddress;
/* FIRST and SECOND CHOICES: use the free pool */
/* get the FreePoolHandle and FreePoolSize */
status = MEM_CalcSizeAndHandleOfFreePoolInPageSpace(&freePoolSizeInPages, &freePoolHandle);
ExitOnError(status);
/* if FreePoolSize >= aRequestedSize */
if (freePoolSizeInPages >= aRequestedSizeInPages)
{
/* if the free pool isn't block aligned and (block alignment was requested or free pool is pinned) */
freePoolOffset = (freePoolHandle-FDI_FirstObjectAddress)/FDI_PageSize;
if (((freePoolOffset*FDI_PageSize) % FDI_BlockSize) != 0 &&
(aBlockAlign == TRUE || (PIN_LIST_IsObjectPinned((freePoolHandle-FDI_FirstObjectAddress)/FDI_PageSize, 1) != enNotPinned)))
{
/* if the free pool spans more than one block boundary, see */
/* if we can align on the next block boundary and use it */
if ((freePoolSizeInPages*FDI_PageSize) > FDI_BlockSize)
{
/* compute adjustedFreePoolHandle based on next block boundary */
blockAlignedFreePoolHandle = FDI_FirstObjectAddress +
((UTIL_CalcBlockNumberForOffset(freePoolOffset)+1) * FDI_BlockSize);
/* compute adjustedFreePoolSize based on new handle */
blockAlignedFreePoolSizeInPages =
(FDI_ParaSpaceAddressBottom - blockAlignedFreePoolHandle) / FDI_PageSize;
/* if adjustedFreePoolSize > aRequestedSize */
if (blockAlignedFreePoolSizeInPages > aRequestedSizeInPages)
{
/* FIRST CHOICE */
/* would prefer contiguous free chunk in free pool, */
/* the beginning of which is aligned on a block boundary */
/* create free chunk header to hold space between */
/* current free pool start and the block boundary */
*aHandlePtr = blockAlignedFreePoolHandle;
/* create a free chunk to fill in between the last object */
/* and the beginning of the block-aligned free pool */
FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;
FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
status = FHDR_CreateFreeChunkHeader(
FDI_LastHeaderEntry,
freePoolOffset,
freePoolSizeInPages - blockAlignedFreePoolSizeInPages);
ExitOnError(status);
}
else
{
/* SECOND CHOICE */
/* if first choice not available, can we use the free pool as-is? */
/* only if last object in page space isn't pinned */
if (PIN_LIST_IsObjectPinned((freePoolHandle-FDI_FirstObjectAddress)/FDI_PageSize, 1) == enNotPinned)
{
/* *aFreeChunkHandlePtr = FreePoolHandle */
*aHandlePtr = freePoolHandle;
}/* end if */
}
}
else
{
/* SECOND CHOICE */
/* free pool is less than a single block in size, but */
/* the size is big enough, if it's not pinned */
if (PIN_LIST_IsObjectPinned((freePoolHandle-FDI_FirstObjectAddress)/FDI_PageSize, 1) == enNotPinned)
{
/* *aFreeChunkHandlePtr = FreePoolHandle */
*aHandlePtr = freePoolHandle;
}/* end if */
}
}
else
{
/* FIRST CHOICE */
/* The free pool is block aligned, and it's big enough, so */
/* use it as is. Since it's block aligned, we don't have */
/* to worry about pinning. */
/* *aFreeChunkHandlePtr = FreePoolHandle */
*aHandlePtr = freePoolHandle;
}/* end if */
}/* end if */
/* if we couldn't get a good handle from the free pool, */
/* then try a free chunk within page space */
if (*aHandlePtr == FDI_InvalidObjAddress)
{
/* look for an unpinned free chunk in page space that fits the requested size */
status = MEM_FindLargestUnpinnedFreeChunkInPageSpace(&freeChunkHandle, &freeChunkSizeInPages);
ExitOnError(status);
if (freeChunkSizeInPages >= aRequestedSizeInPages)
{
/* if the free chunk spans a block boundary and isn't block aligned and block alignment was requested */
freeChunkOffset = (freeChunkHandle-FDI_FirstObjectAddress) / FDI_PageSize;
freeChunkEndOffset = freeChunkOffset+freeChunkSizeInPages;
freeChunkFirstBlock = UTIL_CalcBlockNumberForOffset(freeChunkOffset);
freeChunkLastBlock = UTIL_CalcBlockNumberForOffset(freeChunkOffset+freeChunkSizeInPages - 1);
if ((freeChunkFirstBlock < freeChunkLastBlock) &&
(((freeChunkOffset*FDI_PageSize) % FDI_BlockSize) != 0) && aBlockAlign == TRUE)
{
/* compute adjustedFreeChunkHandle based on next block boundary, */
blockAlignedFreeChunkHandle = FDI_FirstObjectAddress +
((freeChunkFirstBlock+1) * FDI_BlockSize);
/* compute adjustedFreeChunkSize based on new handle */
blockAlignedFreeChunkSizeInPages = freeChunkSizeInPages - ((blockAlignedFreeChunkHandle - freeChunkHandle) / FDI_PageSize);
if (blockAlignedFreeChunkSizeInPages >= aRequestedSizeInPages)
{
/* THIRD CHOICE */
/* use a block-aligned free chunk in the page space */
*aHandlePtr = blockAlignedFreeChunkHandle;
blockAlignedFreeChunkOffset = (blockAlignedFreeChunkHandle - FDI_FirstObjectAddress) / FDI_PageSize;
/* find the original free chunk header */
SEARCH_Header2SearchInfo((&searchInfo), (&FDI_SearchHeader));
compareInfo.CompareValue = freeChunkHandle;
compareInfo.NamePtr = 0;
compareInfo.NameSize = 0;
status = SEARCH_GetNextHeader(&searchInfo, SEARCH_ByObjectHeaderAddress, &compareInfo, FALSE);
if (status == ERR_NONE)
{
/* Found an existing object, but is it a free chunk? */
if (FHDR_GetAllocationStatus(&(searchInfo.HeaderPtr->FHdr)) != HDR_ALLOC_EMPTY)
{
status = ERR_STATE;
ExitOnError(status);
}
/* mark the original free chunk as absorbing */
status = FHDR_AbsorbingHeaderInFlash(
searchInfo.CurrObj.HeaderAddress,
&(searchInfo.HeaderPtr->FHdr));
ExitOnError(status);
}
else
{
/* couldn't find a header, so something is corrupted */
status = ERR_STATE;
ExitOnError(status);
}
/* create two new free chunk headers to replace the original */
FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;
FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
status = FHDR_CreateFreeChunkHeader(
FDI_LastHeaderEntry,
freeChunkOffset,
freeChunkSizeInPages - blockAlignedFreeChunkSizeInPages);
ExitOnError(status);
FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;
FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
status = FHDR_CreateFreeChunkHeader(
FDI_LastHeaderEntry,
blockAlignedFreeChunkOffset,
blockAlignedFreeChunkSizeInPages);
ExitOnError(status);
/* mark the original free chunk as absorbed */
status = FHDR_AbsorbedHeaderInFlash(
searchInfo.CurrObj.HeaderAddress,
&(searchInfo.HeaderPtr->FHdr));
ExitOnError(status);
}
else
{
/* FOURTH CHOICE */
/* if first choice not available, use the free chunk as is */
/* if last object in page space isn't pinned */
*aHandlePtr = freeChunkHandle;
}
}
else
{
/* FOURTH CHOICE */
/* either the free chunk doesn't span a block boundary, */
/* or it's already block aligned. Use it as-is. */
*aHandlePtr = freeChunkHandle;
}/* end if */
}/* end if */
}/* end if */
/* at this point, if we haven't got a good handle, */
/* then we've run out of options */
if (*aHandlePtr == FDI_InvalidObjAddress)
{
status = ERR_NO_MORE_ENTRIES;
}
return status;
}
/*#################################################################
### BKUP_CreateBackupObject
###
### DESCRIPTION:
### This function creates a backup copy (including header) of
### the object specified by the search info parameter.
###
### PARAMETERS:
### aSearchInfo -- search structure containing information
### about the object to be backed up. This
### must be initialized prior to calling this
### function.
### aBkupHandle -- location in page space to create the backup.
### restart -- Flag used to for PLR.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -