OpenSSD Cosmos+ Platform Firmware
0.0.2
The firmware of Cosmos+ OpenSSD Platform for TOSHIBA nand flash module.
|
Go to the source code of this file.
Functions | |
void | InitAddressMap () |
Initialize the translation related maps. More... | |
void | InitSliceMap () |
Initialize Logical and Virtual Slick Map. More... | |
void | RemapBadBlock () |
Try to remap the bad blocks in the main block space. More... | |
void | InitDieMap () |
Reset the free block list of each die. More... | |
void | InitBlockMap () |
Create V2P table and free block list. More... | |
void | InitCurrentBlockOfDieMap () |
Get a default free block for each die. More... | |
void | ReadBadBlockTable (unsigned int tempBbtBufAddr[], unsigned int tempBbtBufEntrySize) |
Read the pages that should contain the bad block table. More... | |
void | FindBadBlock (unsigned char dieState[], unsigned int tempBbtBufAddr[], unsigned int tempBbtBufEntrySize, unsigned int tempReadBufAddr[], unsigned int tempReadBufEntrySize) |
Build the bbt for those dies whose bbt doesn't exist. More... | |
void | SaveBadBlockTable (unsigned char dieState[], unsigned int tempBbtBufAddr[], unsigned int tempBbtBufEntrySize) |
Persist the newly created bbt for those dies whose bbt not exists. More... | |
void | RecoverBadBlockTable (unsigned int tempBufAddr) |
Read the bbt from flash and re-create if not exists. More... | |
void | EraseTotalBlockSpace () |
Erase all the blocks on user dies and wait until done. More... | |
void | EraseUserBlockSpace () |
Erase all the non-bad main blocks on user dies and wait until done. More... | |
void | InitBlockDieMap () |
Build the bad block table and V2P block mapping of each user die. More... | |
unsigned int | AddrTransRead (unsigned int logicalSliceAddr) |
Get the virtual slice address of the given logical slice. More... | |
unsigned int | AddrTransWrite (unsigned int logicalSliceAddr) |
Assign a new virtual (physical) page to the specified logical page. More... | |
unsigned int | FindFreeVirtualSlice () |
Select a free physical page (virtual slice). More... | |
unsigned int | FindFreeVirtualSliceForGc (unsigned int copyTargetDieNo, unsigned int victimBlockNo) |
unsigned int | FindDieForFreeSliceAllocation () |
Update and get the die number to serve the next write request. More... | |
void | InvalidateOldVsa (unsigned int logicalSliceAddr) |
Invalidate the specified virtual page. More... | |
void | EraseBlock (unsigned int dieNo, unsigned int blockNo) |
Erase the specified block of the specified die and discard its LSAs. More... | |
void | PutToFbList (unsigned int dieNo, unsigned int blockNo) |
Append the given virtual block to the free block list of its die. More... | |
unsigned int | GetFromFbList (unsigned int dieNo, unsigned int getFreeBlockOption) |
Pop the first block in the free block list of the specified die. More... | |
void | UpdatePhyBlockMapForGrownBadBlock (unsigned int dieNo, unsigned int phyBlockNo) |
Mark the given physical block bad block and update the bbt later. More... | |
void | UpdateBadBlockTableForGrownBadBlock (unsigned int tempBufAddr) |
Update the bad block table and persist to the specified block. More... | |
unsigned int AddrTransRead | ( | unsigned int | logicalSliceAddr | ) |
Get the virtual slice address of the given logical slice.
logicalSliceAddr | the logical address of the target slice. |
Definition at line 871 of file address_translation.c.
unsigned int AddrTransWrite | ( | unsigned int | logicalSliceAddr | ) |
Assign a new virtual (physical) page to the specified logical page.
Before issuing the write request, we should allocate a physical page for the specified logical page and invalidate the old physical page if it exists.
ReqTransSliceToLowLevel()
.logicalSliceAddr | the logical address of the target slice. |
Definition at line 903 of file address_translation.c.
void EraseBlock | ( | unsigned int | dieNo, |
unsigned int | blockNo | ||
) |
Erase the specified block of the specified die and discard its LSAs.
This function will:
Discard all the logical slice addresses of the origin block
dieNo | the die number of the specified block. |
blockNo | the block number on the specified die. |
Definition at line 1122 of file address_translation.c.
void EraseTotalBlockSpace | ( | ) |
Erase all the blocks on user dies and wait until done.
Definition at line 744 of file address_translation.c.
void EraseUserBlockSpace | ( | ) |
Erase all the non-bad main blocks on user dies and wait until done.
Definition at line 777 of file address_translation.c.
void FindBadBlock | ( | unsigned char | dieState[], |
unsigned int | tempBbtBufAddr[], | ||
unsigned int | tempBbtBufEntrySize, | ||
unsigned int | tempReadBufAddr[], | ||
unsigned int | tempReadBufEntrySize | ||
) |
Build the bbt for those dies whose bbt doesn't exist.
To determine whether a block is bad block, we should check 4 bytes in that block:
If only of the 4 bytes are not 0xFF, we can view this block as bad block.
why check these 4 bytes, why ECC and row addr dep off?
the update in the second for is redundant, it can be merged to next part
tempBbtBufEntrySize
and tempReadBufEntrySize
not usedblockChecker
not initializeddieState | the flags that indicate whether the bbt of that die should be rebuilt. |
tempBbtBufAddr | the addresses of the bbt of each die. |
tempBbtBufEntrySize | the size of the data and metadata region of a page. |
tempReadBufAddr | the buffer addresses for storing the pages to be read. |
tempReadBufEntrySize | the size of a whole page (data + metadata + ECC). |
Check all the blocks on the SSD
Definition at line 433 of file address_translation.c.
unsigned int FindDieForFreeSliceAllocation | ( | ) |
Update and get the die number to serve the next write request.
To exploit the parallelism, the write request should first be interleaved on different channels to take advantage of the channel parallelism. If all the channels' same way are used, select the next way of each channel to use the die parallelism.
Definition at line 1051 of file address_translation.c.
unsigned int FindFreeVirtualSlice | ( | ) |
Select a free physical page (virtual slice).
In current implementation, the target page to serve the write request is determined by checking the following three variables:
sliceAllocationTargetDie
:
The die where the next request should be issued to.
To exploit the parallelism of each die, especially under write-intensive workload, the write requests will be interleaved to each die.
Check FindDieForFreeSliceAllocation()
for details.
VIRTUAL_DIE_ENTRY::currentBlock
:
The current working block of the target die.
Each die maintains a current working block and will select a page from the current working block of target die to serve the write request. Once all the pages of the current working block are used, the fw will select a new free block from the free block list as the new current working block of that die.
If there the free block list of that die is empty, the fw will try to release invalid blocks by doing GC.
Check GetFromFbList()
and GarbageCollection()
for the details.
VIRTUAL_BLOCK_ENTRY::currentPage
:
The current working page of the current working block on the die.
Current implementation just selects the free page sequentially from the current working block.
currentPage
might be full after GC? Definition at line 965 of file address_translation.c.
unsigned int FindFreeVirtualSliceForGc | ( | unsigned int | copyTargetDieNo, |
unsigned int | victimBlockNo | ||
) |
Definition at line 1008 of file address_translation.c.
unsigned int GetFromFbList | ( | unsigned int | dieNo, |
unsigned int | getFreeBlockOption | ||
) |
Pop the first block in the free block list of the specified die.
VIRTUAL_DIE_ENTRY::freeBlockCnt
), so if the number of free blocks is less then the number of preserved blocks, BLOCK_FAIL
will be returned.GET_FREE_BLOCK_NORMAL
and GET_FREE_BLOCK_GC
.dieNo | The target die number. |
getFreeBlockOption | //TODO |
Definition at line 1194 of file address_translation.c.
void InitAddressMap | ( | ) |
Initialize the translation related maps.
The following tasks will be finished in the function:
This function, only initialize the base addresses of these maps, the physical block map and some bad blocks info. The other maps will be initialized in InitBlockDieMap()
and InitSliceMap()
, check the two functions for further initialization.
Definition at line 82 of file address_translation.c.
void InitBlockDieMap | ( | ) |
Build the bad block table and V2P block mapping of each user die.
To create the V2P mapping, we have to:
Definition at line 815 of file address_translation.c.
void InitBlockMap | ( | ) |
Create V2P table and free block list.
Assign a physical blocks for each virtual block:
The translation rule is basically static mapping, but the target physical block may be bad block, and thus point to another reserved block. Therefore, we should check the remappedPhyBlock
to get the available physical block.
remappedPhyBlock
will still points to the original PBA. So we must check the bad block flag to make sure the remapped block is available.Vblock2PblockOfTbsTranslation
defines the V2P mapping rule.InitAddressMap
and RemapBadBlock()
defines bad block remapping rule.Definition at line 300 of file address_translation.c.
void InitCurrentBlockOfDieMap | ( | ) |
Get a default free block for each die.
Definition at line 333 of file address_translation.c.
void InitDieMap | ( | ) |
Reset the free block list of each die.
This function currently will be called before the BBT being recovered, in other words, when the function is called, the fw don't know which block is free, which block is bad yet. The fw therefore cannot build the V2P mapping and the free block list.
Definition at line 265 of file address_translation.c.
void InitSliceMap | ( | ) |
Initialize Logical and Virtual Slick Map.
This function simply initialize all the slice addresses in the both map to NONE.
Definition at line 116 of file address_translation.c.
void InvalidateOldVsa | ( | unsigned int | logicalSliceAddr | ) |
Invalidate the specified virtual page.
Overwriting cannot perform on physical flash cell, so the fw must handle out-of-place update.
This function is used for invalidate the corresponding physical page of the specified logical page, but in case there was no physical page allocated on the logical page before, we should check if the corresponding physical page exists before doing GC on the invalidated physical page.
logicalSliceAddr | LSA that specifies the virtual slice to be invalidated. |
Definition at line 1083 of file address_translation.c.
void PutToFbList | ( | unsigned int | dieNo, |
unsigned int | blockNo | ||
) |
Append the given virtual block to the free block list of its die.
dieNo | the die number of the given block. |
blockNo | VBN of the specified block. |
Definition at line 1161 of file address_translation.c.
void ReadBadBlockTable | ( | unsigned int | tempBbtBufAddr[], |
unsigned int | tempBbtBufEntrySize | ||
) |
Read the pages that should contain the bad block table.
The bbt of that die is stored in the LSB page (or pages) of the block specified by the BAD_BLOCK_TABLE_INFO_ENTRY::phyBlock
, which is default to 0 in InitAddressMap()
.
Each block on this die (including the extended blocks), use 1 Byte to store the bad block info, so we have to read TOTAL_BLOCKS_PER_DIE / PAGE_SIZE_IN_BYTES
pages from the flash.
tempBbtBufAddr | the addresses of the bbt of each die. |
tempBbtBufEntrySize | the size of the data and metadata region of a page. |
Definition at line 365 of file address_translation.c.
void RecoverBadBlockTable | ( | unsigned int | tempBufAddr | ) |
Read the bbt from flash and re-create if not exists.
This function is used for checking and recover the bad block table from the flash.
To do this, we have several things to do:
Check whether the specific pages contains the bbt info
a. if bbt info exists, check the bad blocks in this die. b. otherwise, mark the bbt this die should be rebuilt.
tempBufAddr | the base address for buffering the pages that contain the bbt. |
Definition at line 664 of file address_translation.c.
void RemapBadBlock | ( | ) |
Try to remap the bad blocks in the main block space.
If the number of user blocks is configured as less than the number of total blocks on each die, there may be some redundant blocks can be used for replacing the bad blocks in the user blocks.
Therefore, this function will sequentially search the redundant (reserved) blocks on each die and try to replace the bad block in the user blocks on that die with the reserved blocks.
Definition at line 139 of file address_translation.c.
void SaveBadBlockTable | ( | unsigned char | dieState[], |
unsigned int | tempBbtBufAddr[], | ||
unsigned int | tempBbtBufEntrySize | ||
) |
Persist the newly created bbt for those dies whose bbt not exists.
Similar to ReadBadBlockTable, but now we have to write the bbt to the pages.
dieState | the flags that indicate whether the bbt of that die should be rebuilt. |
tempBbtBufAddr | the addresses of the bbt of each die. |
tempBbtBufEntrySize | the size of the data and metadata region of a page. |
Definition at line 563 of file address_translation.c.
void UpdateBadBlockTableForGrownBadBlock | ( | unsigned int | tempBufAddr | ) |
Update the bad block table and persist to the specified block.
A little bit similar to FindBadBlock()
, but this function use the bad block flag to mark bad blocks, instead of reading the bad block marks.
tempBufAddr | the base address of the bad block tables. |
Definition at line 1254 of file address_translation.c.
void UpdatePhyBlockMapForGrownBadBlock | ( | unsigned int | dieNo, |
unsigned int | phyBlockNo | ||
) |
Mark the given physical block bad block and update the bbt later.
dieNo | the die number of the given block. |
phyBlockNo | the physical address of the block to be marked as bad block. |
Definition at line 1240 of file address_translation.c.
P_BAD_BLOCK_TABLE_INFO_MAP bbtInfoMapPtr |
Definition at line 59 of file address_translation.c.
P_LOGICAL_SLICE_MAP logicalSliceMapPtr |
Definition at line 54 of file address_translation.c.
unsigned int mbPerbadBlockSpace |
Definition at line 62 of file address_translation.c.
P_PHY_BLOCK_MAP phyBlockMapPtr |
Definition at line 58 of file address_translation.c.
unsigned char sliceAllocationTargetDie |
Definition at line 61 of file address_translation.c.
P_VIRTUAL_BLOCK_MAP virtualBlockMapPtr |
Definition at line 56 of file address_translation.c.
P_VIRTUAL_DIE_MAP virtualDieMapPtr |
Definition at line 57 of file address_translation.c.
P_VIRTUAL_SLICE_MAP virtualSliceMapPtr |
Definition at line 55 of file address_translation.c.