bmt.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <string.h>
  32. #include <stdio.h>
  33. #include <platform/mtk_nand_ops.h>
  34. #include <platform/bmt.h>
  35. typedef struct {
  36. char signature[3];
  37. u8 version;
  38. u8 bad_count; // bad block count in pool
  39. u8 mapped_count; // mapped block count in pool
  40. u8 checksum;
  41. u8 reseverd[13];
  42. } phys_bmt_header;
  43. typedef struct {
  44. phys_bmt_header header;
  45. bmt_entry table[MAX_BMT_SIZE];
  46. } phys_bmt_struct;
  47. typedef struct {
  48. char signature[3];
  49. } bmt_oob_data;
  50. static char MAIN_SIGNATURE[] = "BMT";
  51. static char OOB_SIGNATURE[] = "bmt";
  52. #define SIGNATURE_SIZE (3)
  53. #define MAX_DAT_SIZE 0x4000
  54. #define MAX_OOB_SIZE 0x800
  55. extern flashdev_info devinfo;
  56. #if defined(MTK_TLC_NAND_SUPPORT)
  57. extern bool mtk_nand_write_tlc_block_hw(struct nand_chip *chip,
  58. uint8_t *buf, u32 mapped_block);
  59. extern bool mtk_block_istlc(u64 addr);
  60. extern unsigned char g_spare_buf[MAX_OOB_SIZE];
  61. #endif
  62. static struct nand_chip *nand_chip_bmt;
  63. #define PAGE_SIZE_BMT (nand_chip_bmt->page_size)
  64. #if !defined(MTK_TLC_NAND_SUPPORT)
  65. #define BLOCK_SIZE_BMT (nand_chip_bmt->sector_size == 512?nand_chip_bmt->erasesize : nand_chip_bmt->erasesize*2)
  66. #define OFFSET(block) (((u64)block) * BLOCK_SIZE_BMT)
  67. #define PAGE_ADDR(block) ((block) * (BLOCK_SIZE_BMT / PAGE_SIZE_BMT))
  68. #else
  69. #define BLOCK_SIZE_BMT (devinfo.blocksize * 1024)
  70. #define PAGE_PER_SIZE_BMT ((devinfo.blocksize * 1024) / devinfo.pagesize)
  71. //#define OFFSET(block) (((u64)block) * BLOCK_SIZE_BMT)
  72. #define PAGE_ADDR(block) ((block) * PAGE_PER_SIZE_BMT)
  73. extern u64 OFFSET(u32 block);//return logical address
  74. #endif
  75. /*********************************************************************
  76. * Flash is splited into 2 parts, system part is for normal system *
  77. * system usage, size is system_block_count, another is replace pool *
  78. * +-------------------------------------------------+ *
  79. * | system_block_count | bmt_block_count | *
  80. * +-------------------------------------------------+ *
  81. *********************************************************************/
  82. static u32 total_block_count; // block number in flash
  83. u32 system_block_count;
  84. static int bmt_block_count; // bmt table size
  85. static int page_per_block; // page per count
  86. static u32 bmt_block_index; // bmt block index
  87. static bmt_struct bmt; // dynamic created global bmt table
  88. __attribute__((aligned(64))) static u8 dat_buf[MAX_DAT_SIZE];
  89. static u8 oob_buf[MAX_OOB_SIZE];
  90. static bool pool_erased;
  91. extern bool nand_erase_hw (u64 offset);
  92. extern bool mark_block_bad_hw(u64 offset);
  93. extern int nand_write_page_hw(u32 page, u8 *dat, u8 *oob);
  94. /***************************************************************
  95. *
  96. * Interface adaptor for preloader/uboot/kernel
  97. * These interfaces operate on physical address, read/write
  98. * physical data.
  99. *
  100. ***************************************************************/
  101. int nand_read_page_bmt(u32 page, u8 * dat, u8 * oob)
  102. {
  103. return nand_exec_read_page_hw(nand_chip_bmt, page, PAGE_SIZE_BMT, dat, oob);
  104. }
  105. bool nand_block_bad_bmt(u64 offset)
  106. {
  107. return nand_block_bad_hw(nand_chip_bmt, offset);
  108. }
  109. // actually uboot should never use the following 3 functions Fix me kai
  110. bool nand_erase_bmt(u64 offset)
  111. {
  112. return nand_erase_hw(offset);
  113. }
  114. int mark_block_bad_bmt(u64 offset)
  115. {
  116. #if !defined(MTK_TLC_NAND_SUPPORT)
  117. return mark_block_bad_hw(offset);
  118. #endif
  119. }
  120. bool nand_write_page_bmt(u32 page, u8 * dat, u8 * oob)
  121. {
  122. return nand_write_page_hw(page, dat, oob);
  123. }
  124. /***************************************************************
  125. * *
  126. * static internal function *
  127. * *
  128. ***************************************************************/
  129. static void dump_bmt_info(bmt_struct * bmt)
  130. {
  131. int i;
  132. dprintf(INFO, "BMT v%d. total %d mapping:\n", bmt->version, bmt->mapped_count);
  133. for (i = 0; i < bmt->mapped_count; i++) {
  134. dprintf(INFO, "\tbad block (0x%x) has been mapped to block (0x%x)\n", bmt->table[i].bad_index, bmt->table[i].mapped_index);
  135. }
  136. }
  137. static bool match_bmt_signature(u8 * dat, u8 * oob)
  138. {
  139. if (memcmp(dat + MAIN_SIGNATURE_OFFSET, MAIN_SIGNATURE, SIGNATURE_SIZE)) {
  140. dprintf(INFO, "[%s]0x%x,0x%x,0x%x,0x%x \n", __FUNCTION__, *((UINT32 *) dat), *(((UINT32 *) dat) + 1), *(((UINT32 *) dat) + 2), *(((UINT32 *) dat) + 3));
  141. return false;
  142. }
  143. if (memcmp(oob + OOB_SIGNATURE_OFFSET, OOB_SIGNATURE, SIGNATURE_SIZE)) {
  144. dprintf(INFO, "main signature match, oob signature doesn't match, but ignore\n");
  145. }
  146. return true;
  147. }
  148. static u8 cal_bmt_checksum(phys_bmt_struct * phys_table, int bmt_size)
  149. {
  150. u32 i;
  151. u8 checksum = 0;
  152. u8 *dat = (u8 *) phys_table;
  153. checksum += phys_table->header.version;
  154. checksum += phys_table->header.mapped_count;
  155. dat += sizeof(phys_bmt_header);
  156. for (i = 0; i < bmt_size * sizeof(bmt_entry); i++) {
  157. checksum += dat[i];
  158. }
  159. return checksum;
  160. }
  161. // return -1 for unmapped block, and bad block index if mapped.
  162. static int is_block_mapped(int index)
  163. {
  164. int i;
  165. for (i = 0; i < bmt.mapped_count; i++) {
  166. if (index == bmt.table[i].mapped_index)
  167. return i;
  168. }
  169. return -1;
  170. }
  171. static bool is_page_used(u8 * dat, u8 * oob)
  172. {
  173. if (2048 == PAGE_SIZE_BMT) {
  174. return ((oob[13] != 0xFF) || (oob[14] != 0xFF));
  175. } else {
  176. return ((oob[OOB_INDEX_OFFSET] != 0xFF) || (oob[OOB_INDEX_OFFSET + 1] != 0xFF));
  177. }
  178. }
  179. static bool valid_bmt_data(phys_bmt_struct * phys_table)
  180. {
  181. int i;
  182. u8 checksum = cal_bmt_checksum(phys_table, bmt_block_count);
  183. if (phys_table->header.checksum != checksum) {
  184. dprintf(INFO, "BMT Data checksum error: %x %x\n", phys_table->header.checksum, checksum);
  185. return false;
  186. }
  187. dprintf(INFO, "BMT Checksum is: 0x%x\n", phys_table->header.checksum);
  188. for (i = 0; i < phys_table->header.mapped_count; i++) {
  189. if (phys_table->table[i].bad_index >= total_block_count || phys_table->table[i].mapped_index >= total_block_count || phys_table->table[i].mapped_index < system_block_count) {
  190. dprintf(INFO, "index error: bad_index: %d, mapped_index: %d\n", phys_table->table[i].bad_index, phys_table->table[i].mapped_index);
  191. return false;
  192. }
  193. }
  194. dprintf(INFO, "Valid BMT, version v%d\n", phys_table->header.version);
  195. return true;
  196. }
  197. static void fill_nand_bmt_buffer(bmt_struct * bmt, u8 * dat, u8 * oob)
  198. {
  199. phys_bmt_struct *phys_bmt = NULL;
  200. phys_bmt = (phys_bmt_struct *)malloc(sizeof(phys_bmt_struct));
  201. if (!phys_bmt) {
  202. ASSERT(0);
  203. }
  204. dump_bmt_info(bmt);
  205. // fill phys_bmt_struct structure with bmt_struct
  206. memset(phys_bmt, 0xFF, sizeof(phys_bmt_struct));
  207. memcpy(phys_bmt->header.signature, MAIN_SIGNATURE, SIGNATURE_SIZE);
  208. phys_bmt->header.version = BMT_VERSION;
  209. // phys_bmt.header.bad_count = bmt->bad_count;
  210. phys_bmt->header.mapped_count = bmt->mapped_count;
  211. memcpy(phys_bmt->table, bmt->table, sizeof(bmt_entry) * bmt_block_count);
  212. phys_bmt->header.checksum = cal_bmt_checksum(phys_bmt, bmt_block_count);
  213. memcpy(dat + MAIN_SIGNATURE_OFFSET, phys_bmt, sizeof(phys_bmt_struct));
  214. memcpy(oob + OOB_SIGNATURE_OFFSET, OOB_SIGNATURE, SIGNATURE_SIZE);
  215. memcpy(dat + MAIN_SIGNATURE_OFFSET + sizeof(phys_bmt_struct),
  216. &(bmt->data_bmt), sizeof(data_bmt_struct));
  217. free(phys_bmt);
  218. }
  219. // return valid index if found BMT, else return 0
  220. static int load_bmt_data(int start, int pool_size)
  221. {
  222. int bmt_index = start + pool_size - 1;
  223. phys_bmt_struct *phys_table = NULL;
  224. int i;
  225. phys_table = (phys_bmt_struct *)malloc(sizeof(phys_bmt_struct));
  226. if (!phys_table) {
  227. ASSERT(0);
  228. }
  229. dprintf(INFO, "[%s]: begin to search BMT from block 0x%x\n", __FUNCTION__, bmt_index);
  230. dprintf(INFO, "[%s]: bmt_index=0x%x, start=0x%x, pool_size=0x%x, \n", __FUNCTION__, bmt_index, start, pool_size);
  231. for (bmt_index = start + pool_size - 1; bmt_index >= start; bmt_index--) {
  232. dprintf(INFO, "[%s]: bmt_index=0x%x-- ", __FUNCTION__, bmt_index);
  233. if (nand_block_bad_bmt(OFFSET(bmt_index))) {
  234. dprintf(INFO, "Skip bad block: %d\n", bmt_index);
  235. continue;
  236. }
  237. #if defined(MTK_TLC_NAND_SUPPORT)
  238. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  239. && (devinfo.tlcControl.normaltlc))
  240. devinfo.tlcControl.slcopmodeEn = TRUE; //change to slc mode
  241. #endif
  242. memset(dat_buf, 0xAA, sizeof(dat_buf));
  243. memset(oob_buf, 0xAA, sizeof(oob_buf));
  244. if (!nand_read_page_bmt(PAGE_ADDR(bmt_index), dat_buf, oob_buf)) {
  245. dprintf(INFO, "Error found when read block %d\n", bmt_index);
  246. continue;
  247. }
  248. if (!match_bmt_signature(dat_buf, oob_buf)) {
  249. dprintf(INFO, "[%s]: match_bmt_signature out! \n", __FUNCTION__);
  250. continue;
  251. }
  252. dprintf(INFO, "Match bmt signature @ block: 0x%x\n", bmt_index);
  253. memcpy(phys_table, dat_buf + MAIN_SIGNATURE_OFFSET, sizeof(phys_bmt_struct));
  254. if (!valid_bmt_data(phys_table)) {
  255. dprintf(INFO, "BMT data is not correct %d\n", bmt_index);
  256. continue;
  257. } else {
  258. bmt.mapped_count = phys_table->header.mapped_count;
  259. bmt.version = phys_table->header.version;
  260. memcpy(bmt.table, phys_table->table, bmt.mapped_count * sizeof(bmt_entry));
  261. memcpy(&bmt.data_bmt,
  262. (dat_buf + MAIN_SIGNATURE_OFFSET + sizeof(phys_bmt_struct)),
  263. sizeof(data_bmt_struct));
  264. dprintf(INFO, "Data bmt bad_count:%d start_block:0x%x, end_block:0x%x\n", bmt.data_bmt.bad_count,
  265. bmt.data_bmt.start_block, bmt.data_bmt.end_block);
  266. dprintf(INFO, "bmt found at block: %d, mapped block: %d\n", bmt_index, bmt.mapped_count);
  267. #if !defined(MTK_TLC_NAND_SUPPORT)
  268. for (i = 0; i < bmt.mapped_count; i++) {
  269. if (!nand_block_bad_bmt(OFFSET(bmt.table[i].bad_index))) {
  270. dprintf(INFO, "block 0x%x is not mark bad, should be power lost last time\n", bmt.table[i].bad_index);
  271. mark_block_bad_bmt(OFFSET(bmt.table[i].bad_index));
  272. }
  273. }
  274. #endif
  275. free(phys_table);
  276. return bmt_index;
  277. }
  278. }
  279. free(phys_table);
  280. dprintf(INFO, "bmt block not found!\n");
  281. return 0;
  282. }
  283. /*************************************************************************
  284. * Find an available block and erase. *
  285. * start_from_end: if true, find available block from end of flash. *
  286. * else, find from the beginning of the pool *
  287. * need_erase: if true, all unmapped blocks in the pool will be erased *
  288. *************************************************************************/
  289. static int find_available_block(bool start_from_end)
  290. {
  291. int i; // , j;
  292. u32 block = system_block_count;
  293. int direction;
  294. dprintf(INFO, "Try to find_available_block, pool_erase: %d\n", pool_erased);
  295. #if defined(MTK_TLC_NAND_SUPPORT)
  296. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  297. && (devinfo.tlcControl.normaltlc))
  298. devinfo.tlcControl.slcopmodeEn = TRUE;
  299. #endif
  300. #if !defined(MTK_TLC_NAND_SUPPORT)
  301. if (!pool_erased) {
  302. dprintf(INFO, "Erase all un-mapped blocks in pool\n");
  303. for (i = 0; i < bmt_block_count; i++) {
  304. if (block == bmt_block_index) {
  305. dprintf(INFO, "Skip bmt block 0x%x\n", block);
  306. continue;
  307. }
  308. if (nand_block_bad_bmt(OFFSET(block + i))) {
  309. dprintf(INFO, "Skip bad block 0x%x\n", block + i);
  310. continue;
  311. }
  312. if (is_block_mapped(block + i) >= 0) {
  313. dprintf(INFO, "Skip mapped block 0x%x\n", block + i);
  314. continue;
  315. }
  316. //xiaolei: erase non-mapped block by SLC mode firstly
  317. //then, before using as each Mode, should erase by that Mode first.
  318. if (!nand_erase_bmt(((u64)(block + i)) * (devinfo.blocksize * 1024))) {
  319. dprintf(INFO, "Erase block 0x%x failed\n", block + i);
  320. mark_block_bad_bmt(OFFSET(block + i));
  321. }
  322. }
  323. pool_erased = 1;
  324. }
  325. #endif
  326. if (start_from_end) {
  327. block = total_block_count - 1;
  328. direction = -1;
  329. } else {
  330. block = system_block_count;
  331. direction = 1;
  332. }
  333. for (i = 0; i < bmt_block_count; i++, block += direction) {
  334. if (block == bmt_block_index) {
  335. dprintf(INFO, "Skip bmt block 0x%x\n", block);
  336. continue;
  337. }
  338. if (nand_block_bad_bmt(OFFSET(block))) {
  339. dprintf(INFO, "Skip bad block 0x%x\n", block);
  340. continue;
  341. }
  342. if (is_block_mapped(block) >= 0) {
  343. dprintf(INFO, "Skip mapped block 0x%x\n", block);
  344. continue;
  345. }
  346. #if defined(MTK_TLC_NAND_SUPPORT)
  347. if (!nand_erase_bmt(((u64)block) * (devinfo.blocksize * 1024))) {
  348. dprintf(INFO, "Erase block 0x%x failed\n", block);
  349. mark_block_bad_bmt(OFFSET(block));
  350. }
  351. #endif
  352. dprintf(INFO, "Find block 0x%x available\n", block);
  353. return block;
  354. }
  355. return 0;
  356. }
  357. static unsigned short get_bad_index_from_oob(u8 * oob_buf)
  358. {
  359. unsigned short index;
  360. if (2048 == PAGE_SIZE_BMT) { // sector 1024 FDM size = 16, mark location moved
  361. memcpy(&index, oob_buf + 13, OOB_INDEX_SIZE);
  362. } else {
  363. memcpy(&index, oob_buf + OOB_INDEX_OFFSET, OOB_INDEX_SIZE);
  364. }
  365. return index;
  366. }
  367. void set_bad_index_to_oob(u8 * oob, u16 index)
  368. {
  369. if (2048 == PAGE_SIZE_BMT) {
  370. memcpy(oob + 13, &index, sizeof(index));
  371. } else {
  372. memcpy(oob + OOB_INDEX_OFFSET, &index, sizeof(index));
  373. }
  374. }
  375. static int migrate_from_bad(u64 offset, u8 * write_dat, u8 * write_oob)
  376. {
  377. int page;
  378. #if defined(MTK_TLC_NAND_SUPPORT)
  379. u32 error_block = (u32)(offset / (devinfo.blocksize * 1024));
  380. u32 error_page = (u32)(offset >> nand_chip_bmt->page_shift) % page_per_block;
  381. u32 orig_block = error_block;
  382. u32 idx;
  383. bool tlc_mode_block = FALSE;
  384. int bRet;
  385. #else
  386. u32 error_block = (u32)(offset / BLOCK_SIZE_BMT);
  387. u32 error_page = (u32)(offset / PAGE_SIZE_BMT) % page_per_block;
  388. #endif
  389. int to_index;
  390. u32 tick = 1;
  391. memcpy(oob_buf, write_oob, MAX_OOB_SIZE);
  392. to_index = find_available_block(false);
  393. if (!to_index) {
  394. dprintf(INFO, "Cannot find an available block for BMT\n");
  395. return 0;
  396. }
  397. #if defined(MTK_TLC_NAND_SUPPORT)
  398. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  399. && (devinfo.tlcControl.normaltlc)) {
  400. if (error_block >= system_block_count) { // mapped block become bad, find original bad block
  401. for (idx = 0; idx < bmt_block_count; idx++) {
  402. if (bmt.table[idx].mapped_index == error_block) {
  403. orig_block = bmt.table[idx].bad_index;
  404. break;
  405. }
  406. }
  407. }
  408. tlc_mode_block = mtk_block_istlc(orig_block * (devinfo.blocksize * 1024));
  409. if (!tlc_mode_block) {
  410. devinfo.tlcControl.slcopmodeEn = TRUE; //slc mode
  411. tick = 3;
  412. } else {
  413. devinfo.tlcControl.slcopmodeEn = false;
  414. }
  415. }
  416. #endif
  417. #if defined(MTK_TLC_NAND_SUPPORT)
  418. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  419. && (devinfo.tlcControl.normaltlc) && tlc_mode_block) {
  420. if (error_block >= system_block_count)
  421. set_bad_index_to_oob(oob_buf, orig_block);
  422. else
  423. set_bad_index_to_oob(oob_buf, error_block);
  424. //erase block by slc mode in find_available_block
  425. //should erase block by tlc mode for tlc block
  426. memcpy(g_spare_buf, oob_buf, MAX_OOB_SIZE);
  427. nand_erase_bmt(((u64)to_index) * (devinfo.blocksize * 1024));
  428. bRet = mtk_nand_write_tlc_block_hw(nand_chip_bmt, write_dat, to_index);
  429. if (bRet != 0) {
  430. dprintf(INFO, "Write to page 0x%x fail\n", PAGE_ADDR(to_index) + error_page);
  431. mark_block_bad_bmt(OFFSET(to_index));
  432. return migrate_from_bad(offset, write_dat, write_oob);
  433. }
  434. } else
  435. #endif
  436. {
  437. {
  438. // migrate error page first
  439. dprintf(INFO, "Write error page: 0x%x\n", error_page);
  440. if (!write_dat) {
  441. nand_read_page_bmt(PAGE_ADDR(error_block) + error_page, dat_buf, NULL);
  442. write_dat = dat_buf;
  443. }
  444. // memcpy(oob_buf, write_oob, MAX_OOB_SIZE);
  445. if (error_block < system_block_count)
  446. set_bad_index_to_oob(oob_buf, error_block); // if error_block is already a mapped block, original mapping index is in OOB.
  447. if (!nand_write_page_bmt(PAGE_ADDR(to_index) + error_page, write_dat, oob_buf)) {
  448. dprintf(INFO, "Write to page 0x%x fail\n", PAGE_ADDR(to_index) + error_page);
  449. mark_block_bad_bmt(OFFSET(to_index));
  450. return migrate_from_bad(offset, write_dat, write_oob);
  451. }
  452. }
  453. for (page = 0; page < page_per_block; page+=tick) {
  454. if ((u32)page != error_page) {
  455. nand_read_page_bmt(PAGE_ADDR(error_block) + page, dat_buf, oob_buf);
  456. if (is_page_used(dat_buf, oob_buf)) {
  457. if (error_block < system_block_count) {
  458. set_bad_index_to_oob(oob_buf, error_block);
  459. }
  460. dprintf(INFO, "\tmigrate page 0x%x to page 0x%x\n",PAGE_ADDR(error_block) + page, PAGE_ADDR(to_index) + page);
  461. if (!nand_write_page_bmt(PAGE_ADDR(to_index) + page, dat_buf, oob_buf)) {
  462. dprintf(INFO, "Write to page 0x%x fail\n", PAGE_ADDR(to_index) + page);
  463. mark_block_bad_bmt(OFFSET(to_index));
  464. return migrate_from_bad(offset, write_dat, write_oob);
  465. }
  466. }
  467. }
  468. }
  469. }
  470. dprintf(INFO, "Migrate from 0x%x to 0x%x done!\n", error_block, to_index);
  471. return to_index;
  472. }
  473. static bool write_bmt_to_flash(u8 * dat, u8 * oob)
  474. {
  475. bool need_erase = true;
  476. dprintf(INFO, "Try to write BMT\n");
  477. if (bmt_block_index == 0) {
  478. // if we don't have index, we don't need to erase found block as it has been erased in find_available_block()
  479. need_erase = false;
  480. if (!(bmt_block_index = find_available_block(true))) {
  481. dprintf(INFO, "Cannot find an available block for BMT\n");
  482. return false;
  483. }
  484. }
  485. dprintf(INFO, "Find BMT block: 0x%x\n", bmt_block_index);
  486. #if defined(MTK_TLC_NAND_SUPPORT)
  487. if ((devinfo.NAND_FLASH_TYPE == NAND_FLASH_TLC)
  488. && (devinfo.tlcControl.normaltlc))
  489. devinfo.tlcControl.slcopmodeEn = TRUE; //change to slc mode
  490. #endif
  491. if (need_erase) {
  492. if (!nand_erase_bmt(((u64)bmt_block_index) * (devinfo.blocksize * 1024))) {
  493. dprintf(INFO, "BMT block erase fail, mark bad: 0x%x\n", bmt_block_index);
  494. mark_block_bad_bmt(OFFSET(bmt_block_index));
  495. bmt_block_index = 0;
  496. return write_bmt_to_flash(dat, oob); // recursive call
  497. }
  498. }
  499. if (!nand_write_page_bmt(PAGE_ADDR(bmt_block_index), dat, oob)) {
  500. dprintf(INFO, "Write BMT data fail, need to write again\n");
  501. mark_block_bad_bmt(OFFSET(bmt_block_index));
  502. // bmt.bad_count++;
  503. bmt_block_index = 0;
  504. return write_bmt_to_flash(dat, oob); // recursive call
  505. }
  506. dprintf(INFO, "Write BMT data to block 0x%x success\n", bmt_block_index);
  507. return true;
  508. }
  509. /*******************************************************************
  510. * Reconstruct bmt, called when found bmt info doesn't match bad
  511. * block info in flash.
  512. *
  513. * Return NULL for failure
  514. *******************************************************************/
  515. bmt_struct *reconstruct_bmt(bmt_struct * bmt)
  516. {
  517. int i;
  518. int index = system_block_count;
  519. unsigned short bad_index;
  520. int mapped;
  521. bmt->version = BMT_VERSION;
  522. bmt->bad_count = 0;
  523. bmt->mapped_count = 0;
  524. memset(bmt->table, 0, bmt_block_count * sizeof(bmt_entry));
  525. for (i = 0; i < bmt_block_count; i++, index++) {
  526. if (nand_block_bad_bmt(OFFSET(index))) {
  527. dprintf(INFO, "Skip bad block: 0x%x\n", index);
  528. continue;
  529. }
  530. nand_read_page_bmt(PAGE_ADDR(index), dat_buf, oob_buf);
  531. if ((bad_index = get_bad_index_from_oob(oob_buf)) >= system_block_count) {
  532. dprintf(INFO, "get bad index: 0x%x\n", bad_index);
  533. if (bad_index != 0xFFFF)
  534. dprintf(INFO, "Invalid bad index found in block 0x%x, bad index 0x%x\n", index, bad_index);
  535. continue;
  536. }
  537. dprintf(INFO, "Block 0x%x is mapped to bad block: 0x%x\n", index, bad_index);
  538. if (!nand_block_bad_bmt(OFFSET(bad_index))) {
  539. dprintf(INFO, "\tbut block 0x%x is not marked as bad, invalid mapping\n", bad_index);
  540. continue; // no need to erase here, it will be erased later when trying to write BMT
  541. }
  542. if ((mapped = is_block_mapped(bad_index)) >= 0) {
  543. dprintf(INFO, "bad block 0x%x is mapped to 0x%x, should be caused by power lost, replace with one\n", bmt->table[mapped].bad_index, bmt->table[mapped].mapped_index);
  544. bmt->table[mapped].mapped_index = index; // use new one instead.
  545. } else {
  546. bmt->table[bmt->mapped_count].bad_index = bad_index;
  547. bmt->table[bmt->mapped_count].mapped_index = index;
  548. bmt->mapped_count++;
  549. }
  550. dprintf(INFO, "Add mapping: 0x%x -> 0x%x to BMT\n", bad_index, index);
  551. }
  552. dprintf(INFO, "Scan replace pool done, mapped block: %d\n", bmt->mapped_count);
  553. memset(oob_buf, 0xFF, sizeof(oob_buf));
  554. fill_nand_bmt_buffer(bmt, dat_buf, oob_buf);
  555. if (!write_bmt_to_flash(dat_buf, oob_buf)) {
  556. dprintf(INFO, "TRAGEDY: cannot find a place to write BMT!!!!\n");
  557. }
  558. return bmt;
  559. }
  560. /*******************************************************************
  561. * [BMT Interface]
  562. *
  563. * Description:
  564. * Init bmt from nand. Reconstruct if not found or data error
  565. *
  566. * Parameter:
  567. * size: size of bmt and replace pool
  568. *
  569. * Return:
  570. * NULL for failure, and a bmt struct for success
  571. *******************************************************************/
  572. bmt_struct *init_bmt(struct nand_chip * chip, int size)
  573. {
  574. if (size > 0 && size < MAX_BMT_SIZE) {
  575. dprintf(INFO, "Init bmt table, size: %d\n", size);
  576. bmt_block_count = size;
  577. } else {
  578. dprintf(INFO, "Invalid bmt table size: %d\n", size);
  579. return NULL;
  580. }
  581. nand_chip_bmt = chip;
  582. system_block_count = (u32)(chip->chipsize / (devinfo.blocksize * 1024));
  583. total_block_count = bmt_block_count + system_block_count;
  584. page_per_block = (devinfo.blocksize * 1024) / devinfo.pagesize;
  585. dprintf(INFO, "bmt count: %d, system count: %d\n", bmt_block_count, system_block_count);
  586. pool_erased = 0;
  587. memset(bmt.table, 0, size * sizeof(bmt_entry));
  588. if ((bmt_block_index = load_bmt_data(system_block_count, size))) {
  589. dprintf(INFO, "Load bmt data success @ block 0x%x\n", bmt_block_index);
  590. //dump_bmt_info(&bmt);
  591. return &bmt;
  592. } else {
  593. dprintf(INFO, "Load bmt data fail, need re-construct!\n");
  594. #if defined(MTK_TLC_NAND_SUPPORT)
  595. //cannot go here by normal flow on TLC NAND. bmt table can not be restructed by reading oob of each bmt pool block.
  596. //because it is invisiable of SLC/TLC MODE in bmt pool.
  597. return NULL;
  598. #else
  599. if (reconstruct_bmt(&bmt))
  600. return &bmt;
  601. else
  602. return NULL;
  603. #endif
  604. }
  605. }
  606. /*******************************************************************
  607. * [BMT Interface]
  608. *
  609. * Description:
  610. * Update BMT.
  611. *
  612. * Parameter:
  613. * offset: update block/page offset.
  614. * reason: update reason, see update_reason_t for reason.
  615. * dat/oob: data and oob buffer for write fail.
  616. *
  617. * Return:
  618. * Return true for success, and false for failure.
  619. *******************************************************************/
  620. unsigned short get_mapping_block_index(u32 index)
  621. {
  622. data_bmt_struct *data_bmt_info = &bmt.data_bmt;
  623. int i;
  624. if (index > system_block_count) {
  625. dprintf(INFO, "Given index exceed: 0x%x > 0x%x\n", index, system_block_count);
  626. return index;
  627. }
  628. if ((index >= data_bmt_info->start_block) && (index < data_bmt_info->end_block)) {
  629. for (i = 0; i < data_bmt_info->bad_count; i++) {
  630. if (data_bmt_info->entry[i].bad_index == index) {
  631. dprintf(INFO, "$$$$$FTL partition bad block at 0x%x, bad_count:%d\n",
  632. index, data_bmt_info->bad_count);
  633. return DATA_BAD_BLK;
  634. }
  635. }
  636. } else {
  637. for (i = 0; i < bmt.mapped_count; i++) {
  638. if (bmt.table[i].bad_index == index) {
  639. dprintf(INFO, "Redirect 0x%x to 0x%x\n", index, bmt.table[i].mapped_index);
  640. return bmt.table[i].mapped_index;
  641. }
  642. }
  643. }
  644. return index;
  645. }
  646. bool update_bmt(u64 offset, update_reason_t reason, u8 * dat, u8 * oob)
  647. {
  648. int map_index;
  649. int orig_bad_block = -1;
  650. int i;
  651. u32 bad_index = (u32)(offset / (devinfo.blocksize * 1024));
  652. data_bmt_struct *data_bmt_info = &bmt.data_bmt;
  653. if ((bad_index >= data_bmt_info->start_block)
  654. && (bad_index < data_bmt_info->end_block)) {
  655. if (get_mapping_block_index(bad_index) != DATA_BAD_BLK) {
  656. dprintf(INFO, "update_bmt DATA bad block is 0x%x, bad_count:%d\n",
  657. bad_index, data_bmt_info->bad_count);
  658. data_bmt_info->entry[data_bmt_info->bad_count].bad_index = bad_index;
  659. data_bmt_info->entry[data_bmt_info->bad_count].flag = reason;
  660. data_bmt_info->bad_count++;
  661. } else
  662. return false;
  663. } else {
  664. if (reason == UPDATE_WRITE_FAIL) {
  665. dprintf(INFO, "Write fail, need to migrate\n");
  666. if (!(map_index = migrate_from_bad(offset, dat, oob))) {
  667. dprintf(INFO, "migrate fail\n");
  668. return false;
  669. }
  670. } else {
  671. if (!(map_index = find_available_block(false))) {
  672. dprintf(INFO, "Cannot find block in pool\n");
  673. return false;
  674. }
  675. }
  676. }
  677. if ((u32)bad_index >= system_block_count) {
  678. for (i = 0; i < bmt_block_count; i++) {
  679. if (bmt.table[i].mapped_index == bad_index) {
  680. orig_bad_block = bmt.table[i].bad_index;
  681. break;
  682. }
  683. }
  684. dprintf(INFO, "Mapped block becomes bad, orig bad block is 0x%x\n", orig_bad_block);
  685. bmt.table[i].mapped_index = map_index;
  686. } else {
  687. bmt.table[bmt.mapped_count].mapped_index = map_index;
  688. bmt.table[bmt.mapped_count].bad_index = bad_index;
  689. bmt.mapped_count++;
  690. }
  691. memset(oob_buf, 0xFF, sizeof(oob_buf));
  692. fill_nand_bmt_buffer(&bmt, dat_buf, oob_buf);
  693. if (!write_bmt_to_flash(dat_buf, oob_buf))
  694. return false;
  695. mark_block_bad_bmt(offset);
  696. return true;
  697. }
  698. int get_data_bmt(data_bmt_struct *data_bmt)
  699. {
  700. if (bmt.data_bmt.version == DATA_BMT_VERSION) {
  701. memcpy(data_bmt, &bmt.data_bmt, sizeof(data_bmt_struct));
  702. return 0;
  703. }
  704. return 1;
  705. }