46#ifndef ADDRESS_TRANSLATION_H_
47#define ADDRESS_TRANSLATION_H_
54#define LSA_NONE 0xffffffff
55#define LSA_FAIL 0xffffffff
57#define VSA_NONE 0xffffffff
58#define VSA_FAIL 0xffffffff
60#define PAGE_NONE 0xffff
62#define BLOCK_NONE 0xffff
63#define BLOCK_FAIL 0xffff
68#define RESERVED_FREE_BLOCK_COUNT 0x1
70#define GET_FREE_BLOCK_NORMAL 0x0
71#define GET_FREE_BLOCK_GC 0x1
73#define BLOCK_STATE_NORMAL 0
74#define BLOCK_STATE_BAD 1
76#define DIE_STATE_BAD_BLOCK_TABLE_NOT_EXIST 0
77#define DIE_STATE_BAD_BLOCK_TABLE_EXIST 1
78#define DIE_STATE_BAD_BLOCK_TABLE_HOLD 2
79#define DIE_STATE_BAD_BLOCK_TABLE_UPDATE 3
81#define BAD_BLOCK_TABLE_MAKER_IDLE 0
82#define BAD_BLOCK_TABLE_MAKER_TRIGGER 1
84#define CLEAN_DATA_IN_BYTE 0xff
87#define USED_PAGES_FOR_BAD_BLOCK_TABLE_PER_DIE (TOTAL_BLOCKS_PER_DIE / BYTES_PER_DATA_REGION_OF_PAGE + 1)
88#define DATA_SIZE_OF_BAD_BLOCK_TABLE_PER_DIE (TOTAL_BLOCKS_PER_DIE)
98#define START_PAGE_NO_OF_BAD_BLOCK_TABLE_BLOCK (1)
100#define BBT_INFO_GROWN_BAD_UPDATE_NONE 0
101#define BBT_INFO_GROWN_BAD_UPDATE_BOOKED 1
107#define Vsa2VdieTranslation(virtualSliceAddr) ((virtualSliceAddr) % (USER_DIES))
108#define Vsa2VblockTranslation(virtualSliceAddr) (((virtualSliceAddr) / (USER_DIES)) / (SLICES_PER_BLOCK))
109#define Vsa2VpageTranslation(virtualSliceAddr) (((virtualSliceAddr) / (USER_DIES)) % (SLICES_PER_BLOCK))
131#define Vorg2VsaTranslation(dieNo, blockNo, pageNo) \
132 ((dieNo) + (USER_DIES) * ((blockNo) * (SLICES_PER_BLOCK) + (pageNo)))
138#define Vdie2PchTranslation(dieNo) ((dieNo) % (USER_CHANNELS))
139#define Vdie2PwayTranslation(dieNo) ((dieNo) / (USER_CHANNELS))
150#define Vblock2PblockOfTbsTranslation(blockNo) \
151 (((blockNo) / (USER_BLOCKS_PER_LUN)) * (TOTAL_BLOCKS_PER_LUN) + ((blockNo) % (USER_BLOCKS_PER_LUN)))
159#define Vblock2PblockOfMbsTranslation(blockNo) \
160 (((blockNo) / (USER_BLOCKS_PER_LUN)) * (MAIN_BLOCKS_PER_LUN) + ((blockNo) % (USER_BLOCKS_PER_LUN)))
168#define Vpage2PlsbPageTranslation(pageNo) ((pageNo) > (0) ? (2 * (pageNo)-1) : (0))
179#define Pcw2VdieTranslation(chNo, wayNo) ((chNo) + (wayNo) * (USER_CHANNELS))
186#define PlsbPage2VpageTranslation(pageNo) ((pageNo) > (0) ? (((pageNo) + 1) / 2) : (0))
337void EraseBlock(
unsigned int dieNo,
unsigned int blockNo);
339void PutToFbList(
unsigned int dieNo,
unsigned int blockNo);
340unsigned int GetFromFbList(
unsigned int dieNo,
unsigned int getFreeBlockOption);
359#define VDIE_ENTRY(iDie) (&virtualDieMapPtr->die[(iDie)])
360#define VDIE_PREV_IDX(iDie) (VDIE_ENTRY((iDie))->prevDie)
361#define VDIE_NEXT_IDX(iDie) (VDIE_ENTRY((iDie))->nextDie)
362#define VDIE_PREV_ENTRY(iDie) (VDIE_ENTRY(VDIE_PREV_IDX((iDie))))
363#define VDIE_NEXT_ENTRY(iDie) (VDIE_ENTRY(VDIE_NEXT_IDX((iDie))))
365#define VBLK_ENTRY(iDie, iBlk) (&virtualBlockMapPtr->block[(iDie)][(iBlk)])
366#define VBLK_PREV_IDX(iDie, iBlk) (VBLK_ENTRY((iDie), (iBlk))->prevBlock)
367#define VBLK_NEXT_IDX(iDie, iBlk) (VBLK_ENTRY((iDie), (iBlk))->nextBlock)
368#define VBLK_PREV_ENTRY(iDie, iBlk) (VBLK_ENTRY((iDie), VBLK_PREV_IDX((iDie), (iBlk))))
369#define VBLK_NEXT_ENTRY(iDie, iBlk) (VBLK_ENTRY((iDie), VBLK_NEXT_IDX((iDie), (iBlk))))
370#define PBLK_ENTRY(iDie, iBlk) (&phyBlockMapPtr->phyBlock[(iDie)][(iBlk)])
372#define LSA_ENTRY(lsa) (&logicalSliceMapPtr->logicalSlice[(lsa)])
373#define VSA_ENTRY(vsa) (&virtualSliceMapPtr->virtualSlice[(vsa)])
374#define LSA2VSA(lsa) (LSA_ENTRY((lsa))->virtualSliceAddr)
375#define VSA2LSA(vsa) (VSA_ENTRY((vsa))->logicalSliceAddr)
377#define VDIE2PCH(iDie) (Vdie2PchTranslation((iDie)))
378#define VDIE2PWAY(iDie) (Vdie2PwayTranslation((iDie)))
379#define VSA2VDIE(vsa) (Vsa2VdieTranslation((vsa)))
380#define VSA2VBLK(vsa) (Vsa2VblockTranslation((vsa)))
381#define VSA2VPAGE(vsa) (Vsa2VpageTranslation((vsa)))
382#define VBA2PBA_MBS(vba) (Vblock2PblockOfMbsTranslation((vba)))
383#define VBA2PBA_TBS(vba) (Vblock2PblockOfTbsTranslation((vba)))
384#define VORG2VSA(iDie, iBlk, iPage) (Vorg2VsaTranslation((iDie), (iBlk), (iPage)))
386#define PCH2VDIE(iCh, iWay) (Pcw2VdieTranslation((iCh), (iWay)))
unsigned char sliceAllocationTargetDie
struct _PHY_BLOCK_MAP * P_PHY_BLOCK_MAP
unsigned int AddrTransRead(unsigned int logicalSliceAddr)
Get the virtual slice address of the given logical slice.
struct _BAD_BLOCK_TABLE_INFO_MAP * P_BAD_BLOCK_TABLE_INFO_MAP
unsigned int FindDieForFreeSliceAllocation()
Update and get the die number to serve the next write request.
struct _VIRTUAL_DIE_ENTRY * P_VIRTUAL_DIE_ENTRY
unsigned int GetFromFbList(unsigned int dieNo, unsigned int getFreeBlockOption)
Pop the first block in the free block list of the specified die.
void InitSliceMap()
Initialize Logical and Virtual Slick Map.
struct _BAD_BLOCK_TABLE_INFO_ENTRY * P_BAD_BLOCK_TABLE_ENTRY
struct _BAD_BLOCK_TABLE_INFO_MAP BAD_BLOCK_TABLE_INFO_MAP
The bad block tables.
struct _VIRTUAL_DIE_MAP VIRTUAL_DIE_MAP
The metadata table for all user dies.
struct _LOGICAL_SLICE_ENTRY LOGICAL_SLICE_ENTRY
Exactly the Virtual Slice Address.
void InitAddressMap()
Initialize the translation related maps.
struct _VIRTUAL_SLICE_ENTRY VIRTUAL_SLICE_ENTRY
Exactly the Logical Slice Address.
P_BAD_BLOCK_TABLE_INFO_MAP bbtInfoMapPtr
struct _FRRE_BLOCK_ALLOCATION_LIST * P_FRRE_BLOCK_ALLOCATION_LIST
void UpdatePhyBlockMapForGrownBadBlock(unsigned int dieNo, unsigned int phyBlockNo)
Mark the given physical block bad block and update the bbt later.
struct _PHY_BLOCK_ENTRY * P_PHY_BLOCK_ENTRY
struct _VIRTUAL_BLOCK_MAP VIRTUAL_BLOCK_MAP
The block metadata table for all the blocks.
P_LOGICAL_SLICE_MAP logicalSliceMapPtr
unsigned int FindFreeVirtualSlice()
Select a free physical page (virtual slice).
struct _LOGICAL_SLICE_ENTRY * P_LOGICAL_SLICE_ENTRY
struct _VIRTUAL_SLICE_MAP * P_VIRTUAL_SLICE_MAP
void EraseBlock(unsigned int dieNo, unsigned int blockNo)
Erase the specified block of the specified die and discard its LSAs.
P_VIRTUAL_DIE_MAP virtualDieMapPtr
void PutToFbList(unsigned int dieNo, unsigned int blockNo)
Append the given virtual block to the free block list of its die.
struct _BAD_BLOCK_TABLE_INFO_ENTRY BAD_BLOCK_TABLE_INFO_ENTRY
The bad block table for this die.
struct _FRRE_BLOCK_ALLOCATION_LIST FRRE_BLOCK_ALLOCATION_LIST
void UpdateBadBlockTableForGrownBadBlock(unsigned int tempBufAddr)
Update the bad block table and persist to the specified block.
struct _PHY_BLOCK_MAP PHY_BLOCK_MAP
The metadata table for all the physical blocks.
struct _PHY_BLOCK_ENTRY PHY_BLOCK_ENTRY
The metadata of the physical block.
struct _VIRTUAL_BLOCK_MAP * P_VIRTUAL_BLOCK_MAP
P_PHY_BLOCK_MAP phyBlockMapPtr
struct _VIRTUAL_SLICE_ENTRY * P_VIRTUAL_SLICE_ENTRY
struct _LOGICAL_SLICE_MAP * P_LOGICAL_SLICE_MAP
unsigned int FindFreeVirtualSliceForGc(unsigned int copyTargetDieNo, unsigned int victimBlockNo)
struct _VIRTUAL_DIE_ENTRY VIRTUAL_DIE_ENTRY
The metadata for this die.
void InvalidateOldVsa(unsigned int logicalSliceAddr)
Invalidate the specified virtual page.
struct _VIRTUAL_BLOCK_ENTRY VIRTUAL_BLOCK_ENTRY
The metadata for this block.
P_VIRTUAL_SLICE_MAP virtualSliceMapPtr
void InitBlockDieMap()
Build the bad block table and V2P block mapping of each user die.
struct _VIRTUAL_BLOCK_ENTRY * P_VIRTUAL_BLOCK_ENTRY
struct _LOGICAL_SLICE_MAP LOGICAL_SLICE_MAP
The Logical -> Virtual Slice Address mapping table.
P_VIRTUAL_BLOCK_MAP virtualBlockMapPtr
struct _VIRTUAL_DIE_MAP * P_VIRTUAL_DIE_MAP
unsigned int mbPerbadBlockSpace
struct _VIRTUAL_SLICE_MAP VIRTUAL_SLICE_MAP
The Virtual -> Logical Slice mapping table.
unsigned int AddrTransWrite(unsigned int logicalSliceAddr)
Assign a new virtual (physical) page to the specified logical page.
#define USER_BLOCKS_PER_DIE
#define TOTAL_BLOCKS_PER_DIE
The bad block table for this die.
unsigned int grownBadUpdate
BAD_BLOCK_TABLE_INFO_ENTRY bbtInfo[USER_DIES]
Exactly the Virtual Slice Address.
unsigned int virtualSliceAddr
The Logical -> Virtual Slice Address mapping table.
LOGICAL_SLICE_ENTRY logicalSlice[SLICES_PER_SSD]
The metadata of the physical block.
unsigned int remappedPhyBlock
The metadata table for all the physical blocks.
PHY_BLOCK_ENTRY phyBlock[USER_DIES][TOTAL_BLOCKS_PER_DIE]
The metadata for this block.
unsigned int invalidSliceCnt
The block metadata table for all the blocks.
VIRTUAL_BLOCK_ENTRY block[USER_DIES][USER_BLOCKS_PER_DIE]
The metadata for this die.
unsigned int headFreeBlock
unsigned int currentBlock
unsigned int freeBlockCnt
unsigned int tailFreeBlock
The metadata table for all user dies.
VIRTUAL_DIE_ENTRY die[USER_DIES]
Exactly the Logical Slice Address.
unsigned int logicalSliceAddr
The Virtual -> Logical Slice mapping table.
VIRTUAL_SLICE_ENTRY virtualSlice[SLICES_PER_SSD]