⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 davpagerecl.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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 + -