static void overwriteChunkNew() { //uart_print_level_1("25 "); uart_print("overwriteChunkNew\r\n"); UINT32 nSectsToWrite = (((sectOffset_ % SECTORS_PER_CHUNK) + remainingSects_) < SECTORS_PER_CHUNK) ? remainingSects_ : (SECTORS_PER_CHUNK - (sectOffset_ % SECTORS_PER_CHUNK)); #if MeasureDetailedOverwrite start_interval_measurement(TIMER_CH3, TIMER_PRESCALE_0); #endif if ((sectOffset_ % SECTORS_PER_CHUNK == 0) && (((sectOffset_ + nSectsToWrite) % SECTORS_PER_CHUNK) == 0)) { overwriteCompleteChunkNew(); #if MeasureDetailedOverwrite UINT32 timerValue=GET_TIMER_VALUE(TIMER_CH3); UINT32 nTicks = 0xFFFFFFFF - timerValue; uart_print_level_2("OCN0 "); uart_print_level_2_int(nTicks); uart_print_level_2("\r\n"); #endif } else { overwritePartialChunkNew(nSectsToWrite); #if MeasureDetailedOverwrite UINT32 timerValue=GET_TIMER_VALUE(TIMER_CH3); UINT32 nTicks = 0xFFFFFFFF - timerValue; uart_print_level_2("OCN1 "); uart_print_level_2_int(nTicks); uart_print_level_2("\r\n"); #endif } updateOwDramBufMetadata(); updateOwChunkPtr(); sectOffset_ += nSectsToWrite; remainingSects_ -= nSectsToWrite; }
static void overwriteCompletePageInOwLog() { #if DetailedOwStats == 1 uart_print_level_1("-\r\n"); #endif uart_print("overwriteCompletePageInOwLog\r\n"); #if MeasureDetailedOverwrite start_interval_measurement(TIMER_CH3, TIMER_PRESCALE_0); #endif chooseNewBank_(); manageOldCompletePage(); UINT32 newLogLpn = getOWLpn(bank_); UINT32 lbn = LogPageToLogBlk(newLogLpn); UINT32 vBlk = get_log_vbn(bank_, lbn); UINT32 pageOffset = LogPageToOffset(newLogLpn); nand_page_ptprogram_from_host(bank_, vBlk, pageOffset, 0, SECTORS_PER_PAGE); increaseOwCounter(bank_, lbn, pageOffset); #if MeasureOwEfficiency write_dram_32(OwEffBuf(bank_, LogPageToLogBlk(newLogLpn)), read_dram_32(OwEffBuf(bank_, LogPageToLogBlk(newLogLpn))) + SECTORS_PER_PAGE); #endif for(UINT32 i=0; i<CHUNKS_PER_PAGE; i++) { write_dram_32(chunkInLpnsList(OWCtrl[bank_].lpnsListPtr, LogPageToOffset(newLogLpn), i), lpn_); write_dram_32(ChunksMapTable(lpn_, i), ( (bank_ * LOG_BLK_PER_BANK * CHUNKS_PER_BLK) + (newLogLpn * CHUNKS_PER_PAGE) + i ) | StartOwLogLpn); } increaseOWLpn(bank_); #if MeasureDetailedOverwrite UINT32 timerValue=GET_TIMER_VALUE(TIMER_CH3); UINT32 nTicks = 0xFFFFFFFF - timerValue; uart_print_level_2("OPN0 "); uart_print_level_2_int(nTicks); uart_print_level_2("\r\n"); #endif }
static void overwritePartialPageOldNotInOrder() { //uart_print_level_1("19 "); uart_print("overwritePartialPageOldNotInOrder\r\n"); while (remainingSects_ != 0) { UINT32 chunkIdx = sectOffset_ / SECTORS_PER_CHUNK; //UINT32 chunkAddr = getChunkAddr(node_, chunkIdx); UINT32 chunkAddr = read_dram_32(ChunksMapTable(lpn_, chunkIdx)); #if MeasureDetailedOverwrite start_interval_measurement(TIMER_CH3, TIMER_PRESCALE_0); #endif switch (findChunkLocation(chunkAddr)) { case Invalid: { uart_print(" invalid\r\n"); overwriteChunkNew(); break; } case FlashWLog: { uart_print(" in w log\r\n"); overwriteChunkOldInWLog(chunkAddr); #if MeasureDetailedOverwrite UINT32 timerValue=GET_TIMER_VALUE(TIMER_CH3); UINT32 nTicks = 0xFFFFFFFF - timerValue; uart_print_level_2("OCO3 "); uart_print_level_2_int(nTicks); uart_print_level_2("\r\n"); #endif break; } case DRAMWLog: { uart_print(" in w DRAM buf\r\n"); overwriteChunkOldInWBuf(chunkAddr); #if MeasureDetailedOverwrite UINT32 timerValue=GET_TIMER_VALUE(TIMER_CH3); UINT32 nTicks = 0xFFFFFFFF - timerValue; uart_print_level_2("OCO2 "); uart_print_level_2_int(nTicks); uart_print_level_2("\r\n"); #endif break; } case DRAMOwLog: { uart_print(" in ow DRAM buf\r\n"); chunkAddr = chunkAddr & 0x7FFFFFFF; overwriteChunkOldInOwBuf(chunkAddr); #if MeasureDetailedOverwrite UINT32 timerValue=GET_TIMER_VALUE(TIMER_CH3); UINT32 nTicks = 0xFFFFFFFF - timerValue; uart_print_level_2("OCO0 "); uart_print_level_2_int(nTicks); uart_print_level_2("\r\n"); #endif break; } case FlashOwLog: { uart_print(" in ow log\r\n"); chunkAddr = chunkAddr & 0x7FFFFFFF; overwriteChunkOldInOwLog(chunkAddr); #if MeasureDetailedOverwrite UINT32 timerValue=GET_TIMER_VALUE(TIMER_CH3); UINT32 nTicks = 0xFFFFFFFF - timerValue; uart_print_level_2("OCO1 "); uart_print_level_2_int(nTicks); uart_print_level_2("\r\n"); #endif break; } } } // SATA buffer management g_ftl_write_buf_id = (g_ftl_write_buf_id + 1) % NUM_WR_BUFFERS; SETREG (BM_STACK_WRSET, g_ftl_write_buf_id); SETREG (BM_STACK_RESET, 0x01); }
static void overwritePageOldInOrderInOwLog() { #if MeasureDetailedOverwrite start_interval_measurement(TIMER_CH3, TIMER_PRESCALE_0); #endif uart_print("overwritePageOldInOrderInOwLog\r\n"); UINT32 firstChunk = sectOffset_ / SECTORS_PER_CHUNK; UINT32 chunk = read_dram_32(ChunksMapTable(lpn_, firstChunk)); chunk = chunk & 0x7FFFFFFF; UINT32 bank = ChunkToBank(chunk); UINT32 lbn = ChunkToLbn(chunk); UINT32 vBlk = get_log_vbn(bank, lbn); UINT32 pageOffset = ChunkToPageOffset(chunk); if(readOwCounter(bank, lbn, pageOffset) < OwLimit) { #if DetailedOwStats == 1 uart_print_level_1("*\r\n"); #endif uart_print("Can overwrite in place\r\n"); nand_page_ptprogram_from_host(bank, vBlk, pageOffset, sectOffset_, nSects_); increaseOwCounter(bank, lbn, pageOffset); #if MeasureOwEfficiency write_dram_32(OwEffBuf(bank_, ChunkToLbn(chunk)), read_dram_32(OwEffBuf(bank_, ChunkToLbn(chunk))) + nSects_); #endif } else { uart_print("Exceeding limit, must find a new page\r\n"); if (remainingSects_ == SECTORS_PER_PAGE) { overwriteCompletePageInOwLog(); } else { syncWithWriteLimit(); UINT16 invalidChunksToDecrement = 0; chooseNewBank_(); while(remainingSects_) { invalidChunksToDecrement++; UINT32 nSectsToWrite = (((sectOffset_ % SECTORS_PER_CHUNK) + remainingSects_) < SECTORS_PER_CHUNK) ? remainingSects_ : (SECTORS_PER_CHUNK - (sectOffset_ % SECTORS_PER_CHUNK)); if(nSectsToWrite == SECTORS_PER_CHUNK) { uart_print("Copy chunk "); uart_print_int( (sectOffset_ % SECTORS_PER_CHUNK) / SECTORS_PER_CHUNK); uart_print(" to OW_LOG_BUF\r\n"); overwriteCompleteChunkNew(); updateOwDramBufMetadata(); updateOwChunkPtr(); } else { UINT32 chunkIdx = sectOffset_ / SECTORS_PER_CHUNK; chunk = read_dram_32(ChunksMapTable(lpn_, chunkIdx)); chunk = chunk & 0x7FFFFFFF; overwritePartialChunkWhenOldChunkIsInExhaustedOWLog(nSectsToWrite, chunk); updateOwDramBufMetadata(); updateOwChunkPtr(); } sectOffset_ += nSectsToWrite; remainingSects_ -= nSectsToWrite; } decrementValidChunksByN(&heapDataOverwrite, bank, lbn, invalidChunksToDecrement); g_ftl_write_buf_id = (g_ftl_write_buf_id + 1) % NUM_WR_BUFFERS; SETREG (BM_STACK_WRSET, g_ftl_write_buf_id); SETREG (BM_STACK_RESET, 0x01); } } #if MeasureDetailedOverwrite UINT32 timerValue=GET_TIMER_VALUE(TIMER_CH3); UINT32 nTicks = 0xFFFFFFFF - timerValue; uart_print_level_2("OPIO "); uart_print_level_2_int(nTicks); uart_print_level_2("\r\n"); #endif }
void ptimer_start_scale0(void) { start_interval_measurement(TIMER_CH2, TIMER_PRESCALE_0); }
void ptimer_start(void) { start_interval_measurement(TIMER_CH1, TIMER_PRESCALE_2); }