OpenSSD Cosmos+ Platform Firmware  0.0.2
The firmware of Cosmos+ OpenSSD Platform for TOSHIBA nand flash module.
ftl_config.c
Go to the documentation of this file.
1
2// ftl_config.c for Cosmos+ OpenSSD
3// Copyright (c) 2017 Hanyang University ENC Lab.
4// Contributed by Yong Ho Song <yhsong@enc.hanyang.ac.kr>
5// Jaewook Kwak <jwkwak@enc.hanyang.ac.kr>
6// Sangjin Lee <sjlee@enc.hanyang.ac.kr>
7//
8// This file is part of Cosmos+ OpenSSD.
9//
10// Cosmos+ OpenSSD is free software; you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation; either version 3, or (at your option)
13// any later version.
14//
15// Cosmos+ OpenSSD is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18// See the GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Cosmos+ OpenSSD; see the file COPYING.
22// If not, see <http://www.gnu.org/licenses/>.
24
26// Company: ENC Lab. <http://enc.hanyang.ac.kr>
27// Engineer: Jaewook Kwak <jwkwak@enc.hanyang.ac.kr>
28//
29// Project Name: Cosmos+ OpenSSD
30// Design Name: Cosmos+ Firmware
31// Module Name: Flash Translation Layer Configuration Manager
32// File Name: ftl_config.c
33//
34// Version: v1.0.0
35//
36// Description:
37// - initialize flash translation layer
38// - check configuration options
39// - initialize NAND device
41
43// Revision History:
44//
45// * v1.0.0
46// - First draft
48
49#include <assert.h>
50#include "debug.h"
51#include "xil_printf.h"
52#include "memory_map.h"
53#include "t4nsc_ucode.h"
54#include "nsc_driver.h"
55
56unsigned int storageCapacity_L;
58
62void InitFTL()
63{
65
66 InitChCtlReg(); // assigned the predefined addresses of channel controllers
67 InitReqPool(); //
70 InitNandArray(); // "[ NAND device reset complete. ]"
71 InitAddressMap(); // "Press 'X' to re-make the bad block table."
72 InitDataBuf(); //
73 InitGcVictimMap(); //
74
75 /*
76 * MB_PER_BLOCK == 16384 * 256 / (1024 * 1024) == 4
77 * MB_PER_SSD == USER_BLOCKS_PER_DIE * USER_DIES * MB_PER_BLOCK == 524288
78 * MB_PER_MIN_FREE_BLOCK_SPACE == USER_DIES * MB_PER_BLOCK
79 * MB_PER_OVER_PROVISION_BLOCK_SPACE == (USER_BLOCKS_PER_DIE * USER_DIES / 10) * MB_PER_BLOCK
80 * BYTES_PER_NVME_BLOCK == 4096
81 */
82 pr_info("[Total bad blocks size: %d MB ]\r\n", mbPerbadBlockSpace); // calculated in `RemapBadBlock()`
83 pr_info("[Total min free block size: %d MB ]\r\n", MB_PER_MIN_FREE_BLOCK_SPACE);
84 pr_info("[Total over provision size: %d MB ]\r\n", MB_PER_OVER_PROVISION_BLOCK_SPACE);
85
88 ((1024 * 1024) / BYTES_PER_NVME_BLOCK);
89
90 pr_info("[ storage capacity %d MB ]\r\n", storageCapacity_L / ((1024 * 1024) / BYTES_PER_NVME_BLOCK));
91 pr_info("[ ftl configuration complete. ]\r\n");
92}
93
94static void nfc_install_ucode(unsigned int *bram0)
95{
96 int i;
97 for (i = 0; i < T4NSCu_Common_CodeWordLength; i++)
98 {
99 bram0[i] = T4NSCuCode_Common[i];
100 }
101 for (i = 0; i < T4NSCu_PlainOps_CodeWordLength; i++)
102 {
104 }
105}
106
107/* the mapped base addresses of NAND Storage Controllers */
108unsigned int NSCS[] = {
111};
112
115
120{
121 int i;
122 if (USER_CHANNELS < 1)
123 assert(!"[WARNING] Configuration Error: Channel [WARNING]");
124
125 for (i = 0; i < USER_CHANNELS; i++)
126 {
127 nfc_install_ucode((unsigned int *)NSC_UCODES[i]);
128 V2FInitializeHandle(&chCtlReg[i], (void *)NSCS[i]);
129 nfc_set_dqs_delay(i, 28);
130 }
131
132 // nfc_set_dqs_delay(0, 31);
133 // nfc_set_dqs_delay(1, 31);
134 // nfc_set_dqs_delay(5, 4);
135 // nfc_set_dqs_delay(6, 18);
136}
137
176{
177 unsigned int chNo, wayNo, reqSlotTag;
178 int i;
179
180 for (chNo = 0; chNo < USER_CHANNELS; ++chNo)
181 for (wayNo = 0; wayNo < USER_WAYS; ++wayNo)
182 {
183 reqSlotTag = GetFromFreeReqQ();
190 reqPoolPtr->reqPool[reqSlotTag].nandInfo.physicalCh = chNo;
191 reqPoolPtr->reqPool[reqSlotTag].nandInfo.physicalWay = wayNo;
192 reqPoolPtr->reqPool[reqSlotTag].nandInfo.physicalBlock = 0; // dummy
193 reqPoolPtr->reqPool[reqSlotTag].nandInfo.physicalPage = 0; // dummy
195 SelectLowLevelReqQ(reqSlotTag);
196
197 reqSlotTag = GetFromFreeReqQ();
204 reqPoolPtr->reqPool[reqSlotTag].nandInfo.physicalCh = chNo;
205 reqPoolPtr->reqPool[reqSlotTag].nandInfo.physicalWay = wayNo;
206 reqPoolPtr->reqPool[reqSlotTag].nandInfo.physicalBlock = 0; // dummy
207 reqPoolPtr->reqPool[reqSlotTag].nandInfo.physicalPage = 0; // dummy
209 SelectLowLevelReqQ(reqSlotTag);
210 }
211
217
218 for (i = 0; i < USER_CHANNELS; i++)
219 {
220 int j;
221 unsigned char *idData = (unsigned char *)(TEMPORARY_PAY_LOAD_ADDR + 16);
222 V2FReadIdSync(&chCtlReg[i], 0, idData);
223 pr_info("Ch %d ReadId: ", i);
224 for (j = 0; j < 6; j++)
225 pr_raw("%x ", idData[j]);
226 pr("\r\n");
227 }
228
229 xil_printf("[ NAND device reset complete. ]\r\n");
230}
231
243{
244 // geometry configutations of flash memory
246 assert(!"[WARNING] Configuration Error: Channel [WARNING]");
248 assert(!"[WARNING] Configuration Error: WAY [WARNING]");
250 assert(!"[WARNING] Configuration Error: BLOCK [WARNING]");
252 assert(!"[WARNING] Configuration Error: BIT_PER_FLASH_CELL [WARNING]");
253
254 // the size of some area are variable, make sure there is no overlap
256 assert(!"[WARNING] Configuration Error: Data buffer size is too large to be allocated to predefined range "
257 "[WARNING]");
259 assert(!"[WARNING] Configuration Error: Metadata for NAND request completion process is too large to be "
260 "allocated to predefined range [WARNING]");
262 assert(!"[WARNING] Configuration Error: Metadata of FTL is too large to be allocated to DRAM [WARNING]");
263}
void InitAddressMap()
Initialize the translation related maps.
unsigned int mbPerbadBlockSpace
void InitDataBuf()
Initialization process of the Data buffer.
Definition: data_buffer.c:85
#define pr_info(fmt,...)
Definition: debug.h:86
#define pr(fmt,...)
Definition: debug.h:79
#define pr_raw
Definition: debug.h:78
unsigned int NSC_UCODES[]
Definition: ftl_config.c:113
void InitNandArray()
Send RESET and SET_FEATURE to all the flash dies.
Definition: ftl_config.c:175
void InitChCtlReg()
Initialize the base addresses of all channel controllers.
Definition: ftl_config.c:119
T4REGS chCtlReg[USER_CHANNELS]
Definition: ftl_config.c:57
unsigned int NSCS[]
Definition: ftl_config.c:108
void CheckConfigRestriction()
Check the configurations are legal before the initializations start.
Definition: ftl_config.c:242
void InitFTL()
The entry function for FTL initialization.
Definition: ftl_config.c:62
unsigned int storageCapacity_L
Definition: ftl_config.c:56
#define NSC_5_BASEADDR
Definition: ftl_config.h:83
#define USER_CHANNELS
Definition: ftl_config.h:207
#define NSC_2_BASEADDR
Definition: ftl_config.h:110
#define NSC_5_UCODEADDR
Definition: ftl_config.h:82
#define BITS_PER_FLASH_CELL
Definition: ftl_config.h:205
#define NSC_0_BASEADDR
Definition: ftl_config.h:128
#define NSC_1_BASEADDR
Definition: ftl_config.h:119
#define NSC_7_UCODEADDR
Definition: ftl_config.h:64
#define BYTES_PER_NVME_BLOCK
Definition: ftl_config.h:194
#define NSC_4_UCODEADDR
Definition: ftl_config.h:91
#define NSC_3_BASEADDR
Definition: ftl_config.h:101
#define NSC_6_BASEADDR
Definition: ftl_config.h:74
#define MB_PER_SSD
Definition: ftl_config.h:238
#define NSC_4_BASEADDR
Definition: ftl_config.h:92
#define NSC_MAX_WAYS
Definition: ftl_config.h:176
#define NSC_0_UCODEADDR
Definition: ftl_config.h:127
#define SLC_MODE
Definition: ftl_config.h:201
#define NSC_3_UCODEADDR
Definition: ftl_config.h:100
#define MB_PER_OVER_PROVISION_BLOCK_SPACE
Definition: ftl_config.h:241
#define USER_BLOCKS_PER_LUN
Definition: ftl_config.h:206
#define NSC_2_UCODEADDR
Definition: ftl_config.h:109
#define NSC_MAX_CHANNELS
Definition: ftl_config.h:175
#define NSC_6_UCODEADDR
Definition: ftl_config.h:73
#define MAIN_BLOCKS_PER_LUN
Definition: ftl_config.h:153
#define NSC_7_BASEADDR
Definition: ftl_config.h:65
#define MB_PER_MIN_FREE_BLOCK_SPACE
Definition: ftl_config.h:239
#define USER_WAYS
Definition: ftl_config.h:208
#define NSC_1_UCODEADDR
Definition: ftl_config.h:118
void InitGcVictimMap()
#define RESERVED_DATA_BUFFER_BASE_ADDR
Definition: memory_map.h:85
#define FTL_MANAGEMENT_END_ADDR
Definition: memory_map.h:117
#define DATA_BUFFER_MAP_ADDR
Definition: memory_map.h:95
#define TEMPORARY_PAY_LOAD_ADDR
Definition: memory_map.h:92
#define COMPLETE_FLAG_TABLE_ADDR
Definition: memory_map.h:89
#define DRAM_END_ADDR
Definition: memory_map.h:122
void V2FInitializeHandle(T4REGS *t4regs, void *t4nscRegisterBaseAddress)
Definition: nsc_driver.c:100
void nfc_set_dqs_delay(int channel, unsigned int newValue)
Definition: nsc_driver.c:59
void V2FReadIdSync(T4REGS *t4regs, int way, unsigned int *statusReport)
Definition: nsc_driver.c:333
unsigned int GetFromFreeReqQ()
Get a free request from the free request queue.
void InitReqPool()
Initialize the request pool and the request queues.
P_REQ_POOL reqPoolPtr
#define REQ_SLOT_TAG_NONE
#define REQ_OPT_BLOCK_SPACE_TOTAL
#define REQ_CODE_RESET
#define REQ_OPT_DATA_BUF_NONE
#define REQ_CODE_SET_FEATURE
#define REQ_OPT_NAND_ADDR_PHY_ORG
#define REQ_TYPE_NAND
#define REQ_OPT_ROW_ADDR_DEPENDENCY_NONE
void SyncAllLowLevelReqDone()
Do schedule until all the requests are done.
void InitReqScheduler()
Initialize scheduling related tables.
void InitDependencyTable()
void SelectLowLevelReqQ(unsigned int reqSlotTag)
Dispatch given NVMe/NAND request to corresponding request queue.
unsigned int physicalBlock
unsigned int physicalWay
unsigned int physicalPage
unsigned int physicalCh
unsigned int dataBufFormat
Type of address stored in the SSD_REQ_FORMAT::dataBufInfo.
unsigned int nandAddr
Type of address stored in the SSD_REQ_FORMAT::nandInfo.
unsigned int blockSpace
unsigned int rowAddrDependencyCheck
SSD_REQ_FORMAT reqPool[AVAILABLE_OUNTSTANDING_REQ_COUNT]
REQ_OPTION reqOpt
unsigned int reqCode
NAND_INFO nandInfo
unsigned int reqType
unsigned int prevBlockingReq
const int T4NSCu_Common_CodeWordLength
Definition: t4nsc_ucode.h:109
unsigned int T4NSCuCode_PlainOps[]
Definition: t4nsc_ucode.h:70
unsigned int T4NSCuCode_Common[]
Definition: t4nsc_ucode.h:4
const int T4NSCu_PlainOps_CodeWordLength
Definition: t4nsc_ucode.h:111