Binary files OpenSSD-1.1.0/build_gnu/install.exe and OpenSSD-1.1.0_rev/build_gnu/install.exe differ diff -urN OpenSSD-1.1.0/build_gnu/Makefile OpenSSD-1.1.0_rev/build_gnu/Makefile --- OpenSSD-1.1.0/build_gnu/Makefile 2011-08-03 19:38:20.000000000 +0900 +++ OpenSSD-1.1.0_rev/build_gnu/Makefile 2016-05-03 13:54:54.613616000 +0900 @@ -1,4 +1,4 @@ -FTL = tutorial +FTL = greedy PREFIX = arm-none-eabi- CC = $(PREFIX)gcc AS = $(PREFIX)as @@ -13,7 +13,7 @@ LIBS = -lgcc VPATH = ../ftl_$(FTL);../sata;..;../target_spw -SRCS = ftl.c sata_identify.c sata_cmd.c sata_isr.c sata_main.c sata_table.c initialize.c mem_util.c flash.c flash_wrapper.c misc.c uart.c +SRCS = ftl.c ftl_test.c sata_identify.c sata_cmd.c sata_isr.c sata_main.c sata_table.c initialize.c mem_util.c flash.c flash_wrapper.c misc.c uart.c INITSRC = ../target_spw/init_gnu.s OBJS = $(SRCS:.c=.o) init.o DEPS = $(SRCS:.c=.d) diff -urN OpenSSD-1.1.0/ftl_dac/ftl.c OpenSSD-1.1.0_rev/ftl_dac/ftl.c --- OpenSSD-1.1.0/ftl_dac/ftl.c 2011-12-16 18:19:16.000000000 +0900 +++ OpenSSD-1.1.0_rev/ftl_dac/ftl.c 2016-05-03 15:20:36.758686800 +0900 @@ -98,7 +98,6 @@ static misc_metadata g_misc_meta[NUM_BANKS]; static ftl_statistics g_ftl_statistics[NUM_BANKS]; static BOOL32 g_bsp_isr_flag[NUM_BANKS]; -static UINT32 g_bad_blk_count[NUM_BANKS]; // SATA read/write buffer pointer id UINT32 g_ftl_read_buf_id; @@ -198,123 +197,6 @@ while (1); } } -static void build_bad_blk_list(void) -{ - UINT32 bank, num_entries, result, vblk_offset; - scan_list_t* scan_list = (scan_list_t*) TEMP_BUF_ADDR; - - mem_set_dram(BAD_BLK_BMP_ADDR, NULL, BAD_BLK_BMP_BYTES); - - disable_irq(); - - flash_clear_irq(); - - for (bank = 0; bank < NUM_BANKS; bank++) - { - SETREG(FCP_CMD, FC_COL_ROW_READ_OUT); - SETREG(FCP_BANK, REAL_BANK(bank)); - SETREG(FCP_OPTION, FO_E); - SETREG(FCP_DMA_ADDR, (UINT32) scan_list); - SETREG(FCP_DMA_CNT, SCAN_LIST_SIZE); - SETREG(FCP_COL, 0); - SETREG(FCP_ROW_L(bank), SCAN_LIST_PAGE_OFFSET); - SETREG(FCP_ROW_H(bank), SCAN_LIST_PAGE_OFFSET); - - SETREG(FCP_ISSUE, NULL); - while ((GETREG(WR_STAT) & 0x00000001) != 0); - while (BSP_FSM(bank) != BANK_IDLE); - - num_entries = NULL; - result = OK; - - if (BSP_INTR(bank) & FIRQ_DATA_CORRUPT) - { - result = FAIL; - } - else - { - UINT32 i; - - num_entries = read_dram_16(&(scan_list->num_entries)); - - if (num_entries > SCAN_LIST_ITEMS) - { - result = FAIL; - } - else - { - for (i = 0; i < num_entries; i++) - { - UINT16 entry = read_dram_16(scan_list->list + i); - UINT16 pblk_offset = entry & 0x7FFF; - - if (pblk_offset == 0 || pblk_offset >= PBLKS_PER_BANK) - { - #if OPTION_REDUCED_CAPACITY == FALSE - result = FAIL; - #endif - } - else - { - write_dram_16(scan_list->list + i, pblk_offset); - } - } - } - } - - if (result == FAIL) - { - num_entries = 0; - } - else - { - write_dram_16(&(scan_list->num_entries), 0); - } - - g_bad_blk_count[bank] = 0; - - for (vblk_offset = 1; vblk_offset < VBLKS_PER_BANK; vblk_offset++) - { - BOOL32 bad = FALSE; - - #if OPTION_2_PLANE - { - UINT32 pblk_offset; - - pblk_offset = vblk_offset * NUM_PLANES; - - // fix bug@v.1.1.0 - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, pblk_offset) < num_entries + 1) - { - bad = TRUE; - } - - pblk_offset = vblk_offset * NUM_PLANES + 1; - - // fix bug@v.1.1.0 - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, pblk_offset) < num_entries + 1) - { - bad = TRUE; - } - } - #else - { - // fix bug@v.1.1.0 - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, vblk_offset) < num_entries + 1) - { - bad = TRUE; - } - } - #endif - - if (bad) - { - g_bad_blk_count[bank]++; - set_bit_dram(BAD_BLK_BMP_ADDR + bank*(VBLKS_PER_BANK/8 + 1), vblk_offset); - } - } - } -} void ftl_open(void) { diff -urN OpenSSD-1.1.0/ftl_faster/ftl.c OpenSSD-1.1.0_rev/ftl_faster/ftl.c --- OpenSSD-1.1.0/ftl_faster/ftl.c 2011-12-16 18:19:16.000000000 +0900 +++ OpenSSD-1.1.0_rev/ftl_faster/ftl.c 2016-05-03 15:20:27.463559200 +0900 @@ -52,7 +52,6 @@ static misc_metadata g_misc_meta[NUM_BANKS]; static ftl_statistics g_ftl_statistics[NUM_BANKS]; // volatile metadata -static UINT32 g_bad_blk_count[NUM_BANKS]; static BOOL32 g_bsp_isr_flag[NUM_BANKS]; static BOOL32 g_gc_flag[NUM_BANKS]; @@ -131,7 +130,6 @@ // FTL internal function prototype //---------------------------------- static void sanity_check(void); -static void build_bad_blk_list(void); static void set_data_vbn(UINT32 const bank, UINT32 const data_lbn, UINT32 const vblock); static void set_log_vbn(UINT32 const bank, UINT32 const log_lbn, UINT32 const vblock); static void set_isol_vbn(UINT32 const bank, UINT32 const isol_lbn, UINT32 const vblock); @@ -191,102 +189,7 @@ while (1); } } -static void build_bad_blk_list(void) -{ - UINT32 bank, num_entries, result, vblk_offset; - scan_list_t* scan_list = (scan_list_t*) TEMP_BUF_ADDR; - - mem_set_dram(BAD_BLK_BMP_ADDR, NULL, BAD_BLK_BMP_BYTES); - - disable_irq(); - flash_clear_irq(); - - for (bank = 0; bank < NUM_BANKS; bank++) { - SETREG(FCP_CMD, FC_COL_ROW_READ_OUT); - SETREG(FCP_BANK, REAL_BANK(bank)); - SETREG(FCP_OPTION, FO_E); - SETREG(FCP_DMA_ADDR, (UINT32) scan_list); - SETREG(FCP_DMA_CNT, SCAN_LIST_SIZE); - SETREG(FCP_COL, 0); - SETREG(FCP_ROW_L(bank), SCAN_LIST_PAGE_OFFSET); - SETREG(FCP_ROW_H(bank), SCAN_LIST_PAGE_OFFSET); - - SETREG(FCP_ISSUE, NULL); - while ((GETREG(WR_STAT) & 0x00000001) != 0); - while (BSP_FSM(bank) != BANK_IDLE); - - num_entries = NULL; - result = OK; - - if (BSP_INTR(bank) & FIRQ_DATA_CORRUPT) { - result = FAIL; - } - else { - UINT32 i; - - num_entries = read_dram_16(&(scan_list->num_entries)); - - if (num_entries > SCAN_LIST_ITEMS) { - result = FAIL; - } - else { - for (i = 0; i < num_entries; i++) { - UINT16 entry = read_dram_16(scan_list->list + i); - UINT16 pblk_offset = entry & 0x7FFF; - - if (pblk_offset == 0 || pblk_offset >= PBLKS_PER_BANK) { - #if OPTION_REDUCED_CAPACITY == FALSE - result = FAIL; - #endif - } - else { - write_dram_16(scan_list->list + i, pblk_offset); - } - } - } - } - if (result == FAIL) { - num_entries = 0; - } - else { - write_dram_16(&(scan_list->num_entries), 0); - } - g_bad_blk_count[bank] = 0; - - for (vblk_offset = 1; vblk_offset < VBLKS_PER_BANK; vblk_offset++) { - BOOL32 bad = FALSE; - - #if OPTION_2_PLANE - { - UINT32 pblk_offset; - - pblk_offset = vblk_offset * NUM_PLANES; - - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, pblk_offset) < num_entries + 1) { - bad = TRUE; - } - pblk_offset = vblk_offset * NUM_PLANES + 1; - - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, pblk_offset) < num_entries + 1) { - bad = TRUE; - } - } - #else - { - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, vblk_offset) < num_entries + 1) { - bad = TRUE; - } - } - #endif - - if (bad) { - g_bad_blk_count[bank]++; - set_bit_dram(BAD_BLK_BMP_ADDR + bank*(VBLKS_PER_BANK/8 + 1), vblk_offset); - } - } - } -} void ftl_open(void) { /* UINT32 volatile g_break = 0; */ diff -urN OpenSSD-1.1.0/ftl_greedy/ftl.c OpenSSD-1.1.0_rev/ftl_greedy/ftl.c --- OpenSSD-1.1.0/ftl_greedy/ftl.c 2011-12-16 18:19:16.000000000 +0900 +++ OpenSSD-1.1.0_rev/ftl_greedy/ftl.c 2016-05-03 15:22:35.290032800 +0900 @@ -63,7 +63,6 @@ //---------------------------------- static misc_metadata g_misc_meta[NUM_BANKS]; static ftl_statistics g_ftl_statistics[NUM_BANKS]; -static UINT32 g_bad_blk_count[NUM_BANKS]; // SATA read/write buffer pointer id UINT32 g_ftl_read_buf_id; @@ -89,7 +88,6 @@ // page-level striping technique (I/O parallelism) #define get_num_bank(lpn) ((lpn) % NUM_BANKS) -#define get_bad_blk_cnt(bank) (g_bad_blk_count[bank]) #define get_cur_write_vpn(bank) (g_misc_meta[bank].cur_write_vpn) #define set_new_write_vpn(bank, vpn) (g_misc_meta[bank].cur_write_vpn = vpn) #define get_gc_vblock(bank) (g_misc_meta[bank].gc_vblock) @@ -138,123 +136,6 @@ while (1); } } -static void build_bad_blk_list(void) -{ - UINT32 bank, num_entries, result, vblk_offset; - scan_list_t* scan_list = (scan_list_t*) TEMP_BUF_ADDR; - - mem_set_dram(BAD_BLK_BMP_ADDR, NULL, BAD_BLK_BMP_BYTES); - - disable_irq(); - - flash_clear_irq(); - - for (bank = 0; bank < NUM_BANKS; bank++) - { - SETREG(FCP_CMD, FC_COL_ROW_READ_OUT); - SETREG(FCP_BANK, REAL_BANK(bank)); - SETREG(FCP_OPTION, FO_E); - SETREG(FCP_DMA_ADDR, (UINT32) scan_list); - SETREG(FCP_DMA_CNT, SCAN_LIST_SIZE); - SETREG(FCP_COL, 0); - SETREG(FCP_ROW_L(bank), SCAN_LIST_PAGE_OFFSET); - SETREG(FCP_ROW_H(bank), SCAN_LIST_PAGE_OFFSET); - - SETREG(FCP_ISSUE, NULL); - while ((GETREG(WR_STAT) & 0x00000001) != 0); - while (BSP_FSM(bank) != BANK_IDLE); - - num_entries = NULL; - result = OK; - - if (BSP_INTR(bank) & FIRQ_DATA_CORRUPT) - { - result = FAIL; - } - else - { - UINT32 i; - - num_entries = read_dram_16(&(scan_list->num_entries)); - - if (num_entries > SCAN_LIST_ITEMS) - { - result = FAIL; - } - else - { - for (i = 0; i < num_entries; i++) - { - UINT16 entry = read_dram_16(scan_list->list + i); - UINT16 pblk_offset = entry & 0x7FFF; - - if (pblk_offset == 0 || pblk_offset >= PBLKS_PER_BANK) - { - #if OPTION_REDUCED_CAPACITY == FALSE - result = FAIL; - #endif - } - else - { - write_dram_16(scan_list->list + i, pblk_offset); - } - } - } - } - - if (result == FAIL) - { - num_entries = 0; // We cannot trust this scan list. Perhaps a software bug. - } - else - { - write_dram_16(&(scan_list->num_entries), 0); - } - - g_bad_blk_count[bank] = 0; - - for (vblk_offset = 1; vblk_offset < VBLKS_PER_BANK; vblk_offset++) - { - BOOL32 bad = FALSE; - - #if OPTION_2_PLANE - { - UINT32 pblk_offset; - - pblk_offset = vblk_offset * NUM_PLANES; - - // fix bug@jasmine v.1.1.0 - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, pblk_offset) < num_entries + 1) - { - bad = TRUE; - } - - pblk_offset = vblk_offset * NUM_PLANES + 1; - - // fix bug@jasmine v.1.1.0 - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, pblk_offset) < num_entries + 1) - { - bad = TRUE; - } - } - #else - { - // fix bug@jasmine v.1.1.0 - if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, vblk_offset) < num_entries + 1) - { - bad = TRUE; - } - } - #endif - - if (bad) - { - g_bad_blk_count[bank]++; - set_bit_dram(BAD_BLK_BMP_ADDR + bank*(VBLKS_PER_BANK/8 + 1), vblk_offset); - } - } - } -} void ftl_open(void) { diff -urN OpenSSD-1.1.0/ftl_greedy/ftl.h OpenSSD-1.1.0_rev/ftl_greedy/ftl.h --- OpenSSD-1.1.0/ftl_greedy/ftl.h 2011-12-16 18:19:16.000000000 +0900 +++ OpenSSD-1.1.0_rev/ftl_greedy/ftl.h 2016-05-03 14:20:06.597843900 +0900 @@ -38,7 +38,7 @@ #define NUM_TEMP_BUFFERS 1 #define DRAM_BYTES_OTHER ((NUM_COPY_BUFFERS + NUM_FTL_BUFFERS + NUM_HIL_BUFFERS + NUM_TEMP_BUFFERS) * BYTES_PER_PAGE \ -+ BAD_BLK_BMP_BYTES + PAGE_MAP_BYTES + VCOUNT_BYTES) ++ BAD_BLK_BMP_BYTES + PAGE_MAP_BYTES + VCOUNT_BYTES + FTL_TEST_BYTES) #define WR_BUF_PTR(BUF_ID) (WR_BUF_ADDR + ((UINT32)(BUF_ID)) * BYTES_PER_PAGE) #define WR_BUF_ID(BUF_PTR) ((((UINT32)BUF_PTR) - WR_BUF_ADDR) / BYTES_PER_PAGE) @@ -77,9 +77,12 @@ #define PAGE_MAP_ADDR (BAD_BLK_BMP_ADDR + BAD_BLK_BMP_BYTES) // page mapping table #define PAGE_MAP_BYTES ((NUM_LPAGES * sizeof(UINT32) + BYTES_PER_SECTOR - 1) / BYTES_PER_SECTOR * BYTES_PER_SECTOR) -#define VCOUNT_ADDR (PAGE_MAP_ADDR + PAGE_MAP_BYTES) +#define VCOUNT_ADDR (PAGE_MAP_ADDR + PAGE_MAP_BYTES) #define VCOUNT_BYTES ((NUM_BANKS * VBLKS_PER_BANK * sizeof(UINT16) + BYTES_PER_SECTOR - 1) / BYTES_PER_SECTOR * BYTES_PER_SECTOR) +#define FTL_TEST_ADDR (VCOUNT_ADDR + VCOUNT_BYTES) +#define FTL_TEST_BYTES 0x400000 + // #define BLKS_PER_BANK VBLKS_PER_BANK diff -urN OpenSSD-1.1.0/ftl_greedy/ftl_test.c OpenSSD-1.1.0_rev/ftl_greedy/ftl_test.c --- OpenSSD-1.1.0/ftl_greedy/ftl_test.c 1970-01-01 09:00:00.000000000 +0900 +++ OpenSSD-1.1.0_rev/ftl_greedy/ftl_test.c 2016-05-03 14:48:00.158861000 +0900 @@ -0,0 +1,718 @@ +// Copyright 2012 INDILINX Co., Ltd. +// +// This file is part of Jasmine. +// +// Jasmine is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Jasmine is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Jasmine. See the file COPYING. +// If not, see . +// +// LogblockFTL source file +// + +#include "jasmine.h" + +//---------------------------------- +// macro +//---------------------------------- + +//---------------------------------- +// Global Variables +//---------------------------------- +UINT32 gnRandValue = 0x15881588; +UINT32 gpnSavedValues = (UINT32 *)FTL_TEST_ADDR; + +extern UINT32 g_ftl_read_buf_id; +extern UINT32 g_ftl_write_buf_id; + +//---------------------------------- +// FTL internal function prototype +//---------------------------------- +UINT32 _GetRandValue(void); +BOOL32 _TestCase00(void); +BOOL32 _TestCase01(void); +BOOL32 _TestCase02(void); +BOOL32 _TestCase03(void); +BOOL32 _TestCase04(void); +BOOL32 _TestCase05(void); +BOOL32 _TestCase06(void); +BOOL32 _TestCase07(void); + +//---------------------------------- +// FTL external function implementation +//---------------------------------- +void ftl_test(void) +{ + _TestCase00(); + _TestCase01(); + _TestCase02(); + _TestCase03(); + _TestCase04(); + _TestCase05(); + _TestCase06(); + _TestCase07(); +} + +//---------------------------------- +// FTL internal function implementation +//---------------------------------- + +UINT32 _GetRandValue(void) +{ + gnRandValue = gnRandValue * 1103515245 + 12345; + return gnRandValue; +} + +BOOL32 _TestCase00(void) +{ + UINT32 nStartLPN = 0; + UINT32 nLPN; + UINT32 nWriteValue; + UINT32 nReadValue; + BOOL32 bFail = FALSE; + + uart_printf("DBG> _TestCase00 Start"); + + ftl_read(0, SECTORS_PER_PAGE); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + } + else + { + nReadValue = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + } + + if (0xFFFFFFFF != nReadValue) + { + uart_printf("ERR> Data Miscompare1 : nReadValue 0x%x", nReadValue); + bFail = TRUE; + goto T0; + } + + nWriteValue = _GetRandValue(); + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id) + 512, nWriteValue); + ftl_write(1, 1); + + ftl_read(0, 1); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + } + else + { + nReadValue = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + } + + if (0xFFFFFFFF != nReadValue) + { + uart_printf("ERR> Data Miscompare2 : nReadValue 0x%x", nReadValue); + bFail = TRUE; + goto T0; + } + + ftl_read(2, 1); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(NUM_RD_BUFFERS - 1) + 1024); + } + else + { + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(g_ftl_read_buf_id - 1) + 1024); + } + + if (0xFFFFFFFF != nReadValue) + { + uart_printf("ERR> Data Miscompare3 : nReadValue 0x%x", nReadValue); + bFail = TRUE; + goto T0; + } + + ftl_read(1, 1); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(NUM_RD_BUFFERS - 1) + 512); + } + else + { + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(g_ftl_read_buf_id - 1) + 512); + } + + if (nWriteValue != nReadValue) + { + uart_printf("ERR> Data Miscompare4 : nWriteValue 0x%x, nReadValue 0x%x", nWriteValue, nReadValue); + bFail = TRUE; + goto T0; + } + +T0: + if (TRUE == bFail) + { + uart_printf("ERR> _TestCase00 Failed"); + } + else + { + uart_printf("DBG> _TestCase00 End"); + } + + return bFail; +} + +BOOL32 _TestCase01(void) +{ + UINT32 nStartLPN = 0; + UINT32 nNumLPNs = 10240; // 8 bank * 10 Block, Let NUM_LOG_BLOCKS be less than 10 + UINT32 nLPN; + UINT32 nWriteValue; + UINT32 nReadValue; + BOOL32 bFail = FALSE; + + uart_printf("DBG> _TestCase01 Start : nStartLPN 0x%x, nNumLPNs 0x%x", nStartLPN, nNumLPNs); + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + nWriteValue = _GetRandValue(); + _write_dram_32(WR_BUF_PTR(g_ftl_write_buf_id), nWriteValue); + + ftl_write(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + ftl_read(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + } + else + { + nReadValue = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + } + + if (nWriteValue != nReadValue) + { + uart_printf("ERR> Data Miscompare : nLPN 0x%x, nWriteValue 0x%x, nReadValue 0x%x", nLPN, nWriteValue, nReadValue); + bFail = TRUE; + goto T1; + } + } + +T1: + if (TRUE == bFail) + { + uart_printf("ERR> _TestCase01 Failed"); + } + else + { + uart_printf("DBG> _TestCase01 End"); + } + + return bFail; +} + +BOOL32 _TestCase02(void) +{ + UINT32 nStartLPN = 0; + UINT32 nNumLPNs = 10240; // 8 bank * 10 Block, Let NUM_LOG_BLOCKS be less than 10 + UINT32 nLPN; + UINT32 nWriteValue; + UINT32 nReadValue; + BOOL32 bFail = FALSE; + + uart_printf("DBG> _TestCase02 Start : nStartLPN 0x%x, nNumLPNs 0x%x", nStartLPN, nNumLPNs); + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + nWriteValue = nLPN; + _write_dram_32(WR_BUF_PTR(g_ftl_write_buf_id), nWriteValue); + + ftl_write(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + } + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + ftl_read(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + } + else + { + nReadValue = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + } + + if (nLPN != nReadValue) + { + uart_printf("ERR> Data Miscompare : nLPN 0x%x, nWriteValue 0x%x, nReadValue 0x%x", nLPN, nLPN, nReadValue); + bFail = TRUE; + goto T2; + } + } + +T2: + if (TRUE == bFail) + { + uart_printf("ERR> _TestCase02 Failed"); + } + else + { + uart_printf("DBG> _TestCase02 End"); + } + + return bFail; +} + +BOOL32 _TestCase03(void) +{ + UINT32 nCount; + UINT32 nIndex; + UINT32 nWriteValue; + UINT32 nReadValue; + BOOL32 bFail = FALSE; + + uart_printf("DBG> _TestCase03 Start"); + + for (nCount = 0; nCount < 3; nCount++) + { + for (nIndex = 0; nIndex < PAGES_PER_VBLK; nIndex++) + { + nWriteValue = _GetRandValue(); + _write_dram_32(WR_BUF_PTR(g_ftl_write_buf_id), nWriteValue); + + ftl_write(nIndex * SECTORS_PER_PAGE * NUM_BANKS, SECTORS_PER_PAGE); + ftl_read(nIndex * SECTORS_PER_PAGE * NUM_BANKS, SECTORS_PER_PAGE); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + } + else + { + nReadValue = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + } + + if (nWriteValue != nReadValue) + { + uart_printf("ERR> Data Miscompare : nLPN 0x%x, nWriteValue 0x%x, nReadValue 0x%x", nIndex, nWriteValue, nReadValue); + bFail = TRUE; + goto T3; + } + } + } + +T3: + if (TRUE == bFail) + { + uart_printf("ERR> _TestCase03 Failed"); + } + else + { + uart_printf("DBG> _TestCase03 End"); + } + + return bFail; +} + +BOOL32 _TestCase04(void) +{ + UINT32 nCount; + UINT32 nStartLPN = 0; + UINT32 nNumLPNs = 10240; // 8 bank * 10 Block, Let NUM_LOG_BLOCKS be less than 10 + UINT32 nLPN; + UINT32 nWriteValue; + UINT32 nReadValue; + UINT32 nReadLPN; + BOOL32 bFail = FALSE; + + for (nLPN = 0; nLPN < nNumLPNs; nLPN++) + { + // 4Byte Random Value + _write_dram_32((UINT32)gpnSavedValues + nLPN * 4, 0); + } + + uart_printf("DBG> _TestCase04 Start : nStartLPN 0x%x, nNumLPNs 0x%x", nStartLPN, nNumLPNs); + + for (nCount = 0; nCount < 3; nCount++) + { + uart_printf("DBG> Count (%d/%d)", nCount + 1, 3); + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + nWriteValue = _GetRandValue(); + // 4Byte LPN + 4Byte Random Value + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id), nLPN); + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id) + 4, nWriteValue); + + // Save Random Value + _write_dram_32((UINT32)gpnSavedValues + (nLPN - nStartLPN) * 4, nWriteValue); + + ftl_write(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + } + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + ftl_read(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadLPN = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(NUM_RD_BUFFERS - 1) + 4); + } + else + { + nReadLPN = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(g_ftl_read_buf_id - 1) + 4); + } + + nWriteValue = _read_dram_32((UINT32)gpnSavedValues + (nLPN - nStartLPN) * 4); + if ((nLPN != nReadLPN) || (nWriteValue != nReadValue)) + { + uart_printf("ERR> Data Miscompare : nLPN 0x%x, nWriteValue 0x%x, nReadLPN 0x%x, nReadValue 0x%x", nLPN, nWriteValue, nReadLPN, nReadValue); + bFail = TRUE; + goto T4; + } + } + } + +T4: + if (TRUE == bFail) + { + uart_printf("ERR> _TestCase04 Failed"); + } + else + { + uart_printf("DBG> _TestCase04 End"); + } + + return bFail; +} + +BOOL32 _TestCase05(void) +{ + UINT32 nCount; + UINT32 nStartLPN = 0; + UINT32 nNumLPNs = 10240; // 8 bank * 10 Block, Let NUM_LOG_BLOCKS be less than 10 + UINT32 nLPN; + UINT32 nWriteValue; + UINT32 nReadValue; + UINT32 nReadLPN; + BOOL32 bFail = FALSE; + + for (nLPN = 0; nLPN < nNumLPNs; nLPN++) + { + // 4Byte Random Value + _write_dram_32((UINT32)gpnSavedValues + nLPN * 4, 0); + } + + uart_printf("DBG> _TestCase05 Start : nStartLPN 0x%x, nNumLPNs 0x%x", nStartLPN, nNumLPNs); + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + nWriteValue = _GetRandValue(); + // 4Byte LPN + 4Byte Random Value + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id), nLPN); + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id) + 4, nWriteValue); + + // Save Random Value + _write_dram_32((UINT32)gpnSavedValues + (nLPN - nStartLPN) * 4, nWriteValue); + + ftl_write(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + } + + for (nCount = 0; nCount < 10; nCount++) + { + // Random LPN + nLPN = _GetRandValue() % nNumLPNs + nStartLPN; + + nWriteValue = _GetRandValue(); + // 4Byte LPN + 4Byte Random Value + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id), nLPN); + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id) + 4, nWriteValue); + + // Save Random Value + _write_dram_32((UINT32)gpnSavedValues + (nLPN - nStartLPN) * 4, nWriteValue); + + ftl_write(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + } + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + ftl_read(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadLPN = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(NUM_RD_BUFFERS - 1) + 4); + } + else + { + nReadLPN = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(g_ftl_read_buf_id - 1) + 4); + } + + nWriteValue = _read_dram_32((UINT32)gpnSavedValues + (nLPN - nStartLPN) * 4); + if ((nLPN != nReadLPN) || (nWriteValue != nReadValue)) + { + uart_printf("ERR> Data Miscompare : nLPN 0x%x, nWriteValue 0x%x, nReadLPN 0x%x, nReadValue 0x%x", nLPN, nWriteValue, nReadLPN, nReadValue); + bFail = TRUE; + goto T5; + } + } + +T5: + if (TRUE == bFail) + { + uart_printf("ERR> _TestCase05 Failed"); + } + else + { + uart_printf("DBG> _TestCase05 End"); + } + + return bFail; +} + +BOOL32 _TestCase06(void) +{ + UINT32 nCount; + UINT32 nStartLPN = 0; + UINT32 nNumLPNs = 10240; // 8 bank * 10 Block, Let NUM_LOG_BLOCKS be less than 10 + UINT32 nLPN; + UINT32 nSectorOffset; + UINT32 nWriteValue; + UINT32 nReadValue; + UINT32 nReadLBA; + UINT32 nStartLBA; + UINT32 nSectorCount; + BOOL32 bFail = FALSE; + UINT32 nWriteBufAddr; + + for (nStartLBA = 0; nStartLBA < SECTORS_PER_PAGE * nNumLPNs; nStartLBA++) + { + // 4Byte Random Value + _write_dram_32((UINT32)gpnSavedValues + nStartLBA * 4, 0); + } + + uart_printf("DBG> _TestCase06 Start : nStartLPN 0x%x, nNumLPNs 0x%x", nStartLPN, nNumLPNs); + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + nWriteValue = _GetRandValue(); + for (nSectorOffset = 0; nSectorOffset < SECTORS_PER_PAGE; nSectorOffset++) + { + // 4Byte LPN + 4Byte Random Value + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id) + (nSectorOffset * 512), (nLPN * SECTORS_PER_PAGE + nSectorOffset)); + _write_dram_32((UINT32)WR_BUF_PTR(g_ftl_write_buf_id) + (nSectorOffset * 512) + 4, nWriteValue); + + // Save Random Value + _write_dram_32((UINT32)gpnSavedValues + ((nLPN - nStartLPN) * SECTORS_PER_PAGE + nSectorOffset) * 4, nWriteValue); + } + + ftl_write(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + } + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + ftl_read(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + flash_finish(); + + for (nSectorOffset = 0; nSectorOffset < SECTORS_PER_PAGE; nSectorOffset++) + { + if (0 == g_ftl_read_buf_id) + { + nReadLBA = _read_dram_32((UINT32)RD_BUF_PTR(NUM_RD_BUFFERS - 1) + (nSectorOffset * 512)); + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(NUM_RD_BUFFERS - 1) + (nSectorOffset * 512) + 4); + } + else + { + nReadLBA = _read_dram_32((UINT32)RD_BUF_PTR(g_ftl_read_buf_id - 1) + (nSectorOffset * 512)); + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(g_ftl_read_buf_id - 1) + (nSectorOffset * 512) + 4); + } + + nWriteValue = _read_dram_32((UINT32)gpnSavedValues + ((nLPN - nStartLPN) * SECTORS_PER_PAGE + nSectorOffset) * 4); + if (((nLPN * SECTORS_PER_PAGE + nSectorOffset) != nReadLBA) || (nWriteValue != nReadValue)) + { + uart_printf("ERR> Data Miscompare (PreVerify) : nLBA 0x%x, nWriteValue 0x%x, nReadLBA 0x%x, nReadValue 0x%x", nLPN * SECTORS_PER_PAGE + nSectorOffset, nWriteValue, nReadLBA, nReadValue); + bFail = TRUE; + goto T6; + } + } + } + + for (nCount = 0; nCount < 20; nCount++) + { + uart_printf("DBG> Count (%d/%d)", nCount + 1, 20); + + // Random Sector + nSectorCount = _GetRandValue() % 8000 + 1; + + // Random LPN + nStartLBA = _GetRandValue() % (nNumLPNs * SECTORS_PER_PAGE - nSectorCount + 1); + + nWriteBufAddr = (UINT32)WR_BUF_PTR(g_ftl_write_buf_id) + (nStartLBA % SECTORS_PER_PAGE) * 512; + + for (nSectorOffset = 0; nSectorOffset < nSectorCount; nSectorOffset++) + { + nWriteValue = _GetRandValue(); + // 4Byte LPN + 4Byte Random Value + _write_dram_32(nWriteBufAddr, (nStartLBA + nSectorOffset)); + _write_dram_32(nWriteBufAddr + 4, nWriteValue); + + // Save Random Value + _write_dram_32((UINT32)gpnSavedValues + (nStartLBA + nSectorOffset) * 4, nWriteValue); + + nWriteBufAddr += 512; + if ((UINT32)WR_BUF_PTR(NUM_WR_BUFFERS) <= nWriteBufAddr) + { + nWriteBufAddr = (UINT32)WR_BUF_PTR(0); + } + } + + ftl_write(nStartLBA, nSectorCount); + flash_finish(); + } + + for (nLPN = nStartLPN; nLPN < nStartLPN + nNumLPNs; nLPN++) + { + ftl_read(nLPN * SECTORS_PER_PAGE, SECTORS_PER_PAGE); + flash_finish(); + + for (nSectorOffset = 0; nSectorOffset < SECTORS_PER_PAGE; nSectorOffset++) + { + if (0 == g_ftl_read_buf_id) + { + nReadLBA = _read_dram_32((UINT32)RD_BUF_PTR(NUM_RD_BUFFERS - 1) + (nSectorOffset * 512)); + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(NUM_RD_BUFFERS - 1) + (nSectorOffset * 512) + 4); + } + else + { + nReadLBA = _read_dram_32((UINT32)RD_BUF_PTR(g_ftl_read_buf_id - 1) + (nSectorOffset * 512)); + nReadValue = _read_dram_32((UINT32)RD_BUF_PTR(g_ftl_read_buf_id - 1) + (nSectorOffset * 512) + 4); + } + + nWriteValue = _read_dram_32((UINT32)gpnSavedValues + ((nLPN - nStartLPN) * SECTORS_PER_PAGE + nSectorOffset) * 4); + if (((nLPN * SECTORS_PER_PAGE + nSectorOffset) != nReadLBA) || (nWriteValue != nReadValue)) + { + uart_printf("ERR> Data Miscompare : nLBA 0x%x, nWriteValue 0x%x, nReadLBA 0x%x, nReadValue 0x%x", nLPN * SECTORS_PER_PAGE + nSectorOffset, nWriteValue, nReadLBA, nReadValue); + bFail = TRUE; + goto T6; + } + } + } + +T6: + if (TRUE == bFail) + { + uart_printf("ERR> _TestCase06 Failed"); + } + else + { + uart_printf("DBG> _TestCase06 End"); + } + + return bFail; +} + +BOOL32 _TestCase07(void) +{ + UINT32 nCount; + UINT32 nSubCount; + UINT32 nIndex; + UINT32 nReadValue; + BOOL32 bFail = FALSE; + + uart_printf("DBG> _TestCase07 Start"); + + for (nIndex = 0; nIndex < PAGES_PER_VBLK; nIndex++) + { + _write_dram_32(WR_BUF_PTR(g_ftl_write_buf_id), nIndex); + + ftl_write(nIndex * SECTORS_PER_PAGE * NUM_BANKS, SECTORS_PER_PAGE); + } + + for (nCount = 0; nCount < 3; nCount++) + { + uart_printf("DBG> Count (%d/%d)", nCount + 1, 3); + + for (nSubCount = 0; nSubCount < 100; nSubCount++) + { + nIndex = _GetRandValue() % PAGES_PER_VBLK; + _write_dram_32(WR_BUF_PTR(g_ftl_write_buf_id), nIndex); + + ftl_write(nIndex * SECTORS_PER_PAGE * NUM_BANKS, SECTORS_PER_PAGE); + + ftl_read(nIndex * SECTORS_PER_PAGE * NUM_BANKS, SECTORS_PER_PAGE); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + } + else + { + nReadValue = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + } + + if (nIndex != nReadValue) + { + uart_printf("ERR> Data Miscompare (Verify Imm) : nIndex 0x%x, nReadValue 0x%x", nIndex, nReadValue); + bFail = TRUE; + goto T7; + } + } + + for (nIndex = 0; nIndex < PAGES_PER_VBLK; nIndex++) + { + ftl_read(nIndex * SECTORS_PER_PAGE * NUM_BANKS, SECTORS_PER_PAGE); + flash_finish(); + + if (0 == g_ftl_read_buf_id) + { + nReadValue = _read_dram_32(RD_BUF_PTR(NUM_RD_BUFFERS - 1)); + } + else + { + nReadValue = _read_dram_32(RD_BUF_PTR(g_ftl_read_buf_id - 1)); + } + + if (nIndex != nReadValue) + { + uart_printf("ERR> Data Miscompare : nIndex 0x%x, nReadValue 0x%x", nIndex, nReadValue); + bFail = TRUE; + goto T7; + } + } + } + +T7: + if (TRUE == bFail) + { + uart_printf("ERR> _TestCase07 Failed"); + } + else + { + uart_printf("DBG> _TestCase07 End"); + } + + return bFail; +} diff -urN OpenSSD-1.1.0/include/flash.h OpenSSD-1.1.0_rev/include/flash.h --- OpenSSD-1.1.0/include/flash.h 2011-12-16 18:19:16.000000000 +0900 +++ OpenSSD-1.1.0_rev/include/flash.h 2016-05-03 15:28:23.972975300 +0900 @@ -446,5 +446,6 @@ UINT32 dma_addr, UINT32 const dma_count); void nand_block_erase(UINT32 const bank, UINT32 const vblock); void nand_block_erase_sync(UINT32 const bank, UINT32 const vblock); +void build_bad_blk_list(void); #endif //FLASH_H diff -urN OpenSSD-1.1.0/include/jasmine.h OpenSSD-1.1.0_rev/include/jasmine.h --- OpenSSD-1.1.0/include/jasmine.h 2011-12-16 18:33:22.000000000 +0900 +++ OpenSSD-1.1.0_rev/include/jasmine.h 2016-05-03 15:33:50.099734000 +0900 @@ -26,8 +26,9 @@ #define OPTION_2_PLANE 1 // 1 = 2-plane mode, 0 = 1-plane mode #define OPTION_ENABLE_ASSERT 0 // 1 = enable ASSERT() for debugging, 0 = disable ASSERT() -#define OPTION_FTL_TEST 0 // 1 = FTL test without SATA communication, 0 = normal -#define OPTION_UART_DEBUG 0 // 1 = enable UART message output, 0 = disable +#define OPTION_FTL_TEST 1 // 1 = FTL test without SATA communication, 0 = normal +#define OPTION_UART_DEBUG 1 // 1 = enable UART message output, 0 = disable +#define OPTION_RT_BAD_TEST 1 // 1 = clear bad list, 0 = keep scaned list #define OPTION_SLOW_SATA 0 // 1 = SATA 1.5Gbps, 0 = 3Gbps #define OPTION_SUPPORT_NCQ 0 // 1 = support SATA NCQ (=FPDMA) for AHCI hosts, 0 = support only DMA mode #define OPTION_REDUCED_CAPACITY 0 // reduce the number of blocks per bank for testing purpose @@ -187,5 +188,8 @@ #include "uart.h" #endif +extern UINT32 g_bad_blk_count[NUM_BANKS]; +#define get_bad_blk_cnt(bank) (g_bad_blk_count[bank]) + #endif // JASMINE_H diff -urN OpenSSD-1.1.0/target_spw/flash.c OpenSSD-1.1.0_rev/target_spw/flash.c --- OpenSSD-1.1.0/target_spw/flash.c 2011-08-03 19:38:20.000000000 +0900 +++ OpenSSD-1.1.0_rev/target_spw/flash.c 2016-05-03 15:26:09.973007800 +0900 @@ -21,6 +21,7 @@ const UINT8 c_bank_map[NUM_BANKS] = BANK_MAP; UINT8 c_bank_rmap[NUM_BANKS_MAX] = BANK_RMAP; +UINT32 g_bad_blk_count[NUM_BANKS]; void flash_issue_cmd(UINT32 const bank, UINT32 const sync) { @@ -310,3 +311,107 @@ SETREG(FCONF_TIMECYCLE, time_param); } +void build_bad_blk_list(void) +{ + UINT32 bank, num_entries, result, vblk_offset; + scan_list_t* scan_list = (scan_list_t*) TEMP_BUF_ADDR; + + mem_set_dram(BAD_BLK_BMP_ADDR, NULL, BAD_BLK_BMP_BYTES); + +#if OPTION_RT_BAD_TEST == 0 + disable_irq(); + + flash_clear_irq(); + + for (bank = 0; bank < NUM_BANKS; bank++) { + SETREG(FCP_CMD, FC_COL_ROW_READ_OUT); + SETREG(FCP_BANK, REAL_BANK(bank)); + SETREG(FCP_OPTION, FO_E); + SETREG(FCP_DMA_ADDR, (UINT32) scan_list); + SETREG(FCP_DMA_CNT, SCAN_LIST_SIZE); + SETREG(FCP_COL, 0); + SETREG(FCP_ROW_L(bank), SCAN_LIST_PAGE_OFFSET); + SETREG(FCP_ROW_H(bank), SCAN_LIST_PAGE_OFFSET); + + SETREG(FCP_ISSUE, NULL); + while ((GETREG(WR_STAT) & 0x00000001) != 0); + while (BSP_FSM(bank) != BANK_IDLE); + + num_entries = NULL; + result = OK; + + if (BSP_INTR(bank) & FIRQ_DATA_CORRUPT) { + result = FAIL; + } + else { + UINT32 i; + + num_entries = read_dram_16(&(scan_list->num_entries)); + + if (num_entries > SCAN_LIST_ITEMS) { + result = FAIL; + } + else { + for (i = 0; i < num_entries; i++) { + UINT16 entry = read_dram_16(scan_list->list + i); + UINT16 pblk_offset = entry & 0x7FFF; + + if (pblk_offset == 0 || pblk_offset >= PBLKS_PER_BANK) { +#if OPTION_REDUCED_CAPACITY == FALSE + result = FAIL; +#endif + } + else { + write_dram_16(scan_list->list + i, pblk_offset); + } + } + } + } + + if (result == FAIL) { + num_entries = 0; // We cannot trust this scan list. Perhaps a software bug. + } + else { + write_dram_16(&(scan_list->num_entries), 0); + } + + g_bad_blk_count[bank] = 0; + + for (vblk_offset = 1; vblk_offset < VBLKS_PER_BANK; vblk_offset++) { + BOOL32 bad = FALSE; + +#if OPTION_2_PLANE + { + UINT32 pblk_offset; + + pblk_offset = vblk_offset * NUM_PLANES; + + // fix bug@jasmine v.1.1.0 + if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, pblk_offset) < num_entries + 1) { + bad = TRUE; + } + + pblk_offset = vblk_offset * NUM_PLANES + 1; + + // fix bug@jasmine v.1.1.0 + if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, pblk_offset) < num_entries + 1) { + bad = TRUE; + } + } +#else + { + // fix bug@jasmine v.1.1.0 + if (mem_search_equ_dram(scan_list, sizeof(UINT16), num_entries + 1, vblk_offset) < num_entries + 1) { + bad = TRUE; + } + } +#endif + + if (bad) { + g_bad_blk_count[bank]++; + set_bit_dram(BAD_BLK_BMP_ADDR + bank*(VBLKS_PER_BANK/8 + 1), vblk_offset); + } + } + } +#endif +} diff -urN OpenSSD-1.1.0/target_spw/uart.c OpenSSD-1.1.0_rev/target_spw/uart.c --- OpenSSD-1.1.0/target_spw/uart.c 2011-12-16 18:19:16.000000000 +0900 +++ OpenSSD-1.1.0_rev/target_spw/uart.c 2016-05-03 13:53:57.457711500 +0900 @@ -128,14 +128,17 @@ #include void uart_printf(const char * msg, ...) { - fflush(stdout); - - char out[256]; + char out[256] = {}; va_list ap; + int len = 0; + va_start(ap, msg); - int len = vsnprintf(out, sizeof(out), msg, ap); + len = vsnprintf(out, sizeof(out) - 1, msg, ap); va_end(ap); - out[len] = '\0'; - uart_print(out); + + if ( len >= 0 ) { + out[len] = '\0'; + uart_print(out); + } } #endif // OPTION_UART_DEBUG