#include "OSModule_MemoryManagement.h"
#include"Common.h"
#include"WearLeveling.h"
#include"HardwareAdaptationLayer.h"
#include"BadBlockManagement.h"
#include"FALUserDirective.h"
#include"StructureManager.h"
#include"LLD.h"
/************************ DATA STRUCTURE ***********************/
//data structure used to store the translation
typedef struct M
{
UINT16 PhysicalBlockNumber1;
UINT16 PhysicalBlockNumber2;
UINT8 Info; //0x00=default,0x01=root,0x02=root+figlio
UINT8 LastWrite;
}TreeNode;
static UINT16 UsedBlocks = 0;
/* -------------------- Cache --------------------------*/
static SectorMap Cache[MAX_ENTRY_CACHE];
static UINT8 FreeCache[MAX_ENTRY_CACHE] =
{
0
}; //0 is OS_Free 1 is occuped
static INT32 IndexCache = -1;
/* -------------------- Cache --------------------------*/
/************************ END DATA STRUCTURE ***********************/
NFTL_Return GetSectorOffset(SectorMap Map, UINT8 Sector, UINT8 *OffSet);
NFTL_Return CreateSectorMap(UINT16 PhysicalBlockNumber, SectorMap *Map, UINT8 *LastWrite);
NFTL_Return SetSectorOffset(INT32 Map, UINT8 Sector, UINT8 OffSet);
NFTL_Return CopySectorMapFromCache(SectorMap *Origin, INT32 Destination);
/*********************** GetValidPagePosition **********************************
* Search the valid sector (the last update of sector)in the tree data structure *
* and return the physical position of it *
*---------------------------------------------------------------------------- *
* Node : is the pointer to the root node of tree data structure *
* Sector: is the sector number to search *
* PhysicalBlockNumber:is the physical block where the valid sector is written *
* PhysicalPage: is the physical page where the valid sector is written *
* Position: indicate the position in the of valid sector *
* flag: indicates if this function is called for Read or Write operations *
* return values: *
* PAGENOTFOUND: the sector in not found *
* SUCCESS:the sector is founded *
* FAILURE:the fail is occured *
*********************************************************************************/
NFTL_Return GetValidPagePosition(void *Node, UINT16 *PhysicalBlockNumber,
UINT16 *PhysicalPage, UINT8 Sector, UINT8 *Position, UINT8 flag)
{
UINT8 OffSet;
UINT16 j=0;
SectorMap Map, MapTemp;
NFTL_Return Result;
INT32 cacheChecked = 0;
UINT8 LastApp = 0;
if (flag == WRITE_OPERATION)
{
if (((TreeNode *) Node)->LastWrite + 1 == MAX_SECTOR_NUMBER)
{
*PhysicalPage = MAX_SECTOR_NUMBER;
}
else
{
*PhysicalPage = ((TreeNode *) Node)->LastWrite + 1;
}
if (GetNodeByPosition(Node,PhysicalBlockNumber) != SUCCESS)
{
return FAILURE;
}
*Position = ((TreeNode *) Node)->Info;
if ((*PhysicalPage >= MAX_SECTOR_NUMBER) && (((TreeNode *) Node)->Info == 0x02))
{
return DATA_STRUCTURE_FULL;
}
if ((*PhysicalPage >= MAX_SECTOR_NUMBER) && (((TreeNode *) Node)->Info == 0x01))
{
return PAGENOTFOUND;
}
return SUCCESS;
}
if (flag == READ_OPERATION)
{
if (((TreeNode *) Node)->Info == 0x2)
{
*Position = 0x02;
for (j = 0; j < MAX_ENTRY_CACHE; j++)
{
if ((GetSMCachePhysicalBlockNumber(j) ==
((TreeNode *) Node)->PhysicalBlockNumber2) &&
(GetSMFreeCache(j)))
{
CopySectorMapFromCache(&MapTemp,j);
Result = GetSectorOffset(MapTemp,Sector,&OffSet);
if (Result == SUCCESS)
{
*PhysicalPage = OffSet;
*PhysicalBlockNumber = ((TreeNode *) Node)->PhysicalBlockNumber2;
return SUCCESS;
}
if (Result == PAGENOTFOUND)
{
cacheChecked = 1;
break;
}
}
}//end for j
if (cacheChecked == 0) //physicalblock mapped to a logical block not in the cache
{
CreateSectorMap(((TreeNode *) Node)->PhysicalBlockNumber2,&Map,
&LastApp) ;
IncrementIndexCache();
SetSMFreeCache(GetSMIndexCache(),1);
CopySectorMap(Map,GetSMIndexCache());
if (GetSectorOffset(Map,Sector,&OffSet) == SUCCESS)
{
*PhysicalPage = OffSet;
*PhysicalBlockNumber = ((TreeNode *) Node)->PhysicalBlockNumber2;
return SUCCESS;
}
}
cacheChecked = 0;
}
*Position = 0x01;
for (j = 0; j < MAX_ENTRY_CACHE; j++)
{
if ((GetSMCachePhysicalBlockNumber(j) ==
((TreeNode *) Node)->PhysicalBlockNumber1) &&
(GetSMFreeCache(j)))
{
CopySectorMapFromCache(&MapTemp,j);
Result = GetSectorOffset(MapTemp,Sector,&OffSet);
if (Result == SUCCESS)
{
*PhysicalPage = OffSet;
*PhysicalBlockNumber = ((TreeNode *) Node)->PhysicalBlockNumber1;
return SUCCESS;
}
if (Result == PAGENOTFOUND)
{
cacheChecked = 1;
break;
}
}
}
if (cacheChecked == 0)
{
CreateSectorMap(((TreeNode *) Node)->PhysicalBlockNumber1,&Map,&LastApp) ;
IncrementIndexCache();
SetSMFreeCache(GetSMIndexCache(),1);
CopySectorMap(Map,GetSMIndexCache());
if (GetSectorOffset(Map,Sector,&OffSet) == SUCCESS)
{
*PhysicalPage = OffSet;
*PhysicalBlockNumber = ((TreeNode *) Node)->PhysicalBlockNumber1;
return SUCCESS;
}
}
}
return PAGENOTFOUND;
}
/*********************** AddBlock **********************************************
* Add in tree data structure saved in RAM the new node *
* *
*---------------------------------------------------------------------------- *
* Node : is the pointer to the root node of tree data structure *
* PhysicalBlockNumber:is the physical block in flash of new node of tree *
* SpareBuffer: indicate the position of new node and *
* *
* return values: *
* SUCCESS:the node is added in tree data structure with success *
* FAILURE:the fail is occured *
*********************************************************************************/
//angelo bug added parameter newblock
NFTL_Return AddBlock(UINT16 PhysicalBlockNumber, UINT8 *SpareBuffer, void **Node,
UINT8 *Conflict, UINT16 *ConflictPhyBlockNum, UINT8 newblock)
{
UINT8 CurrentLevel;
UINT8 LastWrite = 0;
CurrentLevel = SpareBuffer[TREE_POSITION_BYTE];
if (CurrentLevel == ROOT_POSITION)
{
if (*Node == NULL)
{
CalculateLastWrite(PhysicalBlockNumber,&LastWrite) ;
if (AddNode(Node,0x01,LastWrite,PhysicalBlockNumber) != SUCCESS)
{
return FAILURE;
}
}
else
{
if (((TreeNode *) *Node)->PhysicalBlockNumber1 != 0) // A conflict has occured
{
*Conflict = 1;
*ConflictPhyBlockNum = PhysicalBlockNumber;
}
else //The Root in RAM already exist (it is founded after a Leaf)
{
((TreeNode *) *Node)->PhysicalBlockNumber1 = PhysicalBlockNumber;
CalculateLastWrite(PhysicalBlockNumber,&LastWrite);
if (AddNode(Node,0x01,LastWrite,PhysicalBlockNumber) != SUCCESS)
{
return FAILURE;
}
}
}
}
else
{
if (*Node == NULL)
{
LastWrite = 0;
CalculateLastWrite(PhysicalBlockNumber,&LastWrite) ;
if (AddNode(Node,0x02,LastWrite,PhysicalBlockNumber) != SUCCESS)
{
return FAILURE;
}
return SUCCESS;
}
CalculateLastWrite(PhysicalBlockNumber,&LastWrite) ;
if (AddNode(Node,0x02,LastWrite,PhysicalBlockNumber) != SUCCESS)
{
return FAILURE;
}
}
return SUCCESS;
}
/********************** AddNode ********************************
* *
* Allocare new mode in the tree *
*-------------------------------------------------------------------*
* *
* *
* PARAMETER: *
* Root: is the Root of
评论0