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 }
int gettick(void) { int counter; u_int savedints; savedints = disable_interrupts(I32_bit); counter = GET_TIMER_VALUE(ixpclk_sc); restore_interrupts(savedints); return counter; }
UINT32 ptimer_stop_and_uart_print_scale0(void) { UINT32 rtime; //char buf[21]; rtime = 0xFFFFFFFF - GET_TIMER_VALUE(TIMER_CH1); // Tick to us rtime = (UINT32)((UINT64)rtime * 2 * 1000000 * PRESCALE_TO_DIV(TIMER_PRESCALE_2) / CLOCK_SPEED); //sprintf(buf, "%u", rtime); //uart_print(buf); return rtime; }
static u_int ixpclk_get_timecount(struct timecounter *tc) { u_int savedints, base, counter; savedints = disable_interrupts(I32_bit); do { base = ixpclk_base; counter = GET_TIMER_VALUE(ixpclk_sc); } while (base != ixpclk_base); restore_interrupts(savedints); return base - counter; }
/* * microtime: * * Fill in the specified timeval struct with the current time * accurate to the microsecond. */ void microtime(register struct timeval *tvp) { u_int oldirqstate; u_int32_t counts; static struct timeval lasttv; if (ixpclk_sc == NULL) { #ifdef DEBUG printf("microtime: called befor initialize ixpclk\n"); #endif tvp->tv_sec = 0; tvp->tv_usec = 0; return; } oldirqstate = disable_interrupts(I32_bit); counts = ixpclk_sc->sc_clock_count - GET_TIMER_VALUE(ixpclk_sc); /* Fill in the timeval struct. */ *tvp = time; tvp->tv_usec += counts / ixpclk_sc->sc_count_per_usec; /* Make sure microseconds doesn't overflow. */ while (tvp->tv_usec >= 1000000) { tvp->tv_usec -= 1000000; tvp->tv_sec++; } /* Make sure the time has advanced. */ if (tvp->tv_sec == lasttv.tv_sec && tvp->tv_usec <= lasttv.tv_usec) { tvp->tv_usec = lasttv.tv_usec + 1; if (tvp->tv_usec >= 1000000) { tvp->tv_usec -= 1000000; tvp->tv_sec++; } } lasttv = *tvp; restore_interrupts(oldirqstate); }
/* * microtime: * * Fill in the specified timeval struct with the current time * accurate to the microsecond. */ void microtime(struct timeval *tvp) { struct ixpclk_softc* sc = ixpclk_sc; static struct timeval lasttv; u_int oldirqstate; uint32_t counts; oldirqstate = disable_interrupts(I32_bit); counts = counts_per_hz - GET_TIMER_VALUE(sc); /* Fill in the timeval struct. */ *tvp = time; tvp->tv_usec += (counts / COUNTS_PER_USEC); /* Make sure microseconds doesn't overflow. */ while (tvp->tv_usec >= 1000000) { tvp->tv_usec -= 1000000; tvp->tv_sec++; } /* Make sure the time has advanced. */ if (tvp->tv_sec == lasttv.tv_sec && tvp->tv_usec <= lasttv.tv_usec) { tvp->tv_usec = lasttv.tv_usec + 1; if (tvp->tv_usec >= 1000000) { tvp->tv_usec -= 1000000; tvp->tv_sec++; } } lasttv = *tvp; restore_interrupts(oldirqstate); }
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 }