- static uint16_t isGoodBlock()
- {
- int blockNum;
- int badblock = 0xFFFF; // or valid block or free block?
- for (blockNum = 0; i < yaftl_info.unkn184_0xA; blockNum++)
- {
- if (yaftl_info.unknStructArray[i].field_8 == 0xFFFF) // need to identify this structure
- {
- return blockNum;
- }
- }
- return (badblock);
- }
- static void ConvertP2C (unsigned int a1, unsigned int a2, unsigned int* blockArray)
- {
- uint32_t _outPageNum, nand_geometry_vfl.total_ce;
- uint32_t v1, v2;
- v1 = a2 * nand_geometry_vfl.pages_per_block;
- v2 = _pagesPerBlock;
- if (!((a1 / nand_geometry_vfl.total_ce) && 0x1))
- v2 = a1 / nand_geometry_vfl.total_ce;
- _outPageNum = v2 | (v1 % nand_geometry_vfl.pages_per_block) | ((v1 - (v1 % nand_geometry_vfl.pages_per_block))*2);
- _outCE = a1 % nand_geometry_vfl.total_ce;
- *blockArray = _outPageNum / nand_geometry_vfl.pages_per_block;
- }
- static void update_blockmap(uint32_t blocks)
- {
- int i = 0;
- memset(freeVFLctxpage, 0xFFFFFFFF, 0x48); // find out where is freeVFLctxpage, this could also be a misnomer
- freeVFLctxpage[0].unkn0 = 1;
- while ((i <= 15) && (nand_geometry_vfl.total_banks >= i))
- {
- freeVFLctxpage[i].unkn1 = i % nand_geometry_vfl.total_ce;
- // &block_number_array[i] <- another global var needs to be identified
- ConvertP2C(i, blocks, &block_number_array[i]);
- i ++;
- }
- }
- unsigned int ConvertC2P(unsigned int _phyBlock, unsigned int* out2, unsigned int* out3) { // just a place holder
- *out2 = 1;
- *out3 = 1;
- return 1;
- }
- unsigned int getBBT (unsigned int _block) // place holder
- {
- return 1;
- }
- unsigned int remapBlock (unsigned int _CE, unsigned int _phyBlock, unsigned int flag1, unsigned int* status)
- {
- uint32_t good_block;
- uint32_t BBT_bit;
- uint32_t v1, v2, out, out2, out3, ret;
- int i;
- good_block = getBBT(_phyBlock); // need to implement this function properly
- if (good_block) {
- if (flag1)
- BBT_bit = good_block;
- //vflcxt[0x698] = 0xf40 for a typical 32GB device
- for(i=0; i < nand_geometry_vfl.blocks_per_ce - (*((uint32_t*)(vflcxt + 0x698)) * nand_geometry_vfl.banks_per_ce); i++ )
- {
- if (_phyBlock == *(uint16_t*(vflcxt + 0x26 + i)))
- break;
- }
- if (i == nand_geometry_vfl.blocks_per_ce - (*((uint32_t*)(vflcxt + 0x698)) * nand_geometry_vfl.banks_per_ce))
- {
- bufferPrintf("Error! \n");
- return 0xE;
- }
- v1 = i / (nand_geometry_vfl.blocks_per_bank - *((uint32_t*)(vflcxt + 0x698)));
- v2 = i % (nand_geometry_vfl.blocks_per_bank - *((uint32_t*)(vflcxt + 0x698)));
- ret = ConvertP2C(_CE + nand_geometry_vfl.total_ce * v1, vflcxt[0x698] + v2, &out);
- if(status != NULL)
- {
- ret = ConvertC2P(_phyBlock, &out2, &out3); // need to implement this function properly
- if (_CE / nand_geometry_vfl.total_ce != out2)
- status = NULL;
- }
- return (out);
- }
- else
- return _phyBlock;
- }
- static void vfl_Phy2C(int ftl_pageNum, int* phyCE, int* phyPageNum)
- {
- uint32_t v1, v2, v3, v4;
- uint32_t phyBlock, ret;
- v1 = ftl_pageNum % nand_geometry_vfl.total_bank;
- v2 = ftl_pageNum / nand_geometry_vfl.pages_per_block_total_bank;
- ret = ConvertP2C(v1, v2, &phyBlock);
- //printf("sub_5FF2A4EC: v1=%d, v2=%d, phyBlock=0x%04X\n",v1,v2,phyBlock);
- *phyCE = v1 % nand_geometry_vfl.total_ce;
- ret = remapBlock(*phyCE, phyBlock, 0, NULL);
- // printf("sub_5FF2A4EC: v1=%d, v2=%d, phyBlock=0x%04X, ret=%d\n",v1,v2,phyBlock,ret);
- v3 = pagesPerBlock * (nand_geometry_vfl.bytes_per_page * (ret / nand_geometry_vfl.blocks_per_bank) + (ret % nand_geometry_vfl.blocks_per_bank));
- v4 = (ftl_pageNum % nand_geometry_vfl.pages_per_block_total_bank) / nand_geometry_vfl.total_bank;
- *phyPageNum = v3 + v4;
- }
- static int VFL_ReadScatteredPagesInVb(uint32_t* buf, uint16_t num_pages, uint8_t* data, UNKNBUFFERSTRUCT* meta, uint32_t* unkn, uint32_t flag1, uint32_t flag2, uint32_t* status)
- {
- int pages;
- uint8_t vstatus = 0;
- if (unkn != NULL)
- *unkn = 0;
- for (pages = 0; pages <= num_pages; pages++)
- {
- vfl_Phy2C(*(buf + i), &awScatteredReadCS[pages], &awScatteredReadPages[pages]); // have seen these but forgot where they are initialized
- }
- int ret = h2fmi_Read_Scattered_Pages(&awScatteredReadCS[0], &awScatteredReadPages[0], data, meta, num_pages, &vstatus, unkn, flag1);
- if ((ret != 0) && (nand_geometry_vfl.status <= vstatus))
- {
- bufferPrintf("VFL_ReadScatteredPagesInVb: mark page for refresh! \r\n");
- *unkn = 1;
- }
- if (status != NULL)
- *status = ret;
- if (ret > 1)
- {
- update_blockmap(*buf / nand_geometry_ftl.pages_per_block_total_banks);
- return 0;
- }
- return 1;
- }
- static int YAFTL_readMultiPages(uint32_t* buf, uint32_t num_pages, a1, uint8_t* databuffer, UNKNBUFFERSTRUCT* unknBuf_array, a4, a5)
- {
- UNKNBUFFERSTRUCT* metabuf_array = unknBuf_array;
- int unkn = 0;
- int status;
- int ret_multi;
- int ret_read;
- if (unknBuf_array == NULL)
- metabuf_array = buffer20;
- for (i = 0; i < (num_pages / nand_geometry_ftl.pages_per_block_total_banks); i++)
- {
- ret_multi = VFL_ReadScatteredPagesInVb(&buf[(i * nand_geometry_ftl.pages_per_block_total_banks)],nand_geometry_ftl.pages_per_block_total_banks, databuffer + i * nand_geometry_ftl.pages_per_block_total_banks * nand_geometry_ftl.bytes_per_page_ftl, metabuf_array, &unkn, 0, a4, &status);
- if(!ret_multi)
- {
- bufferPrintf("yaftl:_readMultiPages: We got read failure!!\r\n");
- int flag = 1;
- int j;
- for (j = 0; j < nand_geometry_ftl.pages_per_block_total_banks; j++)
- {
- ret_read = YAFTL_readPage(buf[(i * nand_geometry_ftl.pages_per_block_total_banks) + j], databuffer + (i * nand_geometry_ftl.pages_per_block_total_banks + j) * nand_geometry_ftl.bytes_per_page_ftl, metabuf_array[i * nand_geometry_ftl.pages_per_block_total_banks + j], a4, 1, a5)
- if (ret_read)
- flag = 0;
- status = ret_read;
- }
- if (flag)
- bufferPrintf("yaftl:_readMultiPages: We were able to overcome read failure!!\r\n");
- }
- else
- {
- if (status)
- return 0;
- }
- int blk;
- blk = databuffer[(i + 1) * nand_geometry_ftl.pages_per_block_total_banks] / nand_geometry_ftl.pages_per_block_total_banks;
- yaftl_info.block_array[blk].unkn3 ++;
- }
- if (num_pages == (i * nand_geometry_ftl.pages_per_block_total_banks))
- return 1;
- int yaBlk = buf[(i - 1) * nand_geometry_ftl.pages_per_block_total_banks] / nand_geometry_ftl.pages_per_block_total_banks;
- yaftl_info.block_array[blk].unkn3 ++;
- unkn = 0;
- ret_multi = VFL_ReadScatteredPagesInVb(&buf[(i - 1) * nand_geometry_ftl.pages_per_block_total_banks], num_pages % nand_geometry_ftl.pages_per_block_total_banks, databuffer + (i - 1) * nand_geometry_ftl.pages_per_block_total_banks * nand_geometry_ftl.bytes_per_page_ftl, metabuf_array, &unkn, 0, a4, &status);
- if(!ret_multi)
- {
- bufferPrintf("yaftl:_readMultiPages: We got read failure!!\r\n");
- flag = 1;
- for (j = 0; j < nand_geometry_ftl.pages_per_block_total_banks; j++)
- {
- ret_read = YAFTL_readPage(buf[(i-1) * nand_geometry_ftl.pages_per_block_total_banks + j], databuffer + ((i-1) * nand_geometry_ftl.pages_per_block_total_banks + j) * nand_geometry_ftl.bytes_per_page_ftl, metabuf_array[(i-1) * nand_geometry_ftl.pages_per_block_total_banks + j], a4, 1, a5);
- if (ret_read)
- flag = 0;
- status = ret_read;
- }
- if (flag)
- {
- bufferPrintf("yaftl:_readMultiPages: We were able to overcome read failure!!\r\n");
- return 1;
- }
- else
- return 0;
- }
- else
- {
- if (status >= 1)
- return 0;
- return (1 - status);
- }
- }
- static int yaftl_verifyMetaData(uint32_t page_num, spareData* meta, uint32_t pages)
- {
- int i;
- for (i = 0; i != pages; i++)
- {
- if (meta[i]->lpn != (page_num + i))
- {
- bufferPrintf("YAFTL_Read: mismatch between lpn and metadata! \r\n");
- return 0;
- }
- if (meta[i]->pagetype & 0x40)
- return 0;
- }
- return 1;
- }
- static int YAFTL_Read (uint32_t page_num, uint32_t page_count, uint32_t* buf)
- {
- int noBuf;
- int temp;
- int unkBlock;
- noBuf = (buf > 1) ? 0 : (1 - buf);
- if (noBuf && (page_count != 1))
- return (0x80000001);
- if ((page_num + page_count) >= yaftl_info.total_pages_ftl)
- return (0x80000001);
- set_ftl_region(page_num, 0, page_count, buf);
- yaftl_info.unk140_n1 = 0xFFFFFFFF;
- yaftl_info.unk33C = 0;
- if ((page_count == 1) && noBuf)
- yaftl_info.unknBuffer3_ftl = 0xFFFFFFFF;
- uint32_t nothingToDo = (page_count == 1) ? (noBuf & 1) : 0;
- int ret = 0;
- uint32_t pagesRead = 0;
- uint16_t v30 = 0;
- uint32_t v2c = 0;
- uint32_t readbuf = buf;
- while (pagesRead != page_count)
- {
- uint32_t ftl_block = (page_num + pagesRead) / yaftl_info.unkn3A_0x800;
- if ((yaftl_info.tocArray[ftl_block].TOCUnkMember1 == 0xFFFF) && (yaftl_info.tocArray[ftl_block].indexPage == 0xFFFFFFFF))
- {
- if (nothingToDo)
- return 0;
- if (yaftl_readMultiPages(yaftl_info.unknBuffer3_ftl, var30, var2C, nothingToDo, 0, 1)
- {
- if (!(yaftl_verifyMetaData(page_num + (var2C - buf) / nand_geometry_ftl.bytes_per_page_ftl, yaftl_info.buffer20, var30)))
- ret = 0x80000002;
- }
- else
- {
- ret = 0x80000002;
- }
- var30 = 0;
- pagesRead ++;
- readbuf += nand_geometry_ftl.bytes_per_page_ftl;
- }
- else
- {
- if (yaftl_info.tocArray[ftl_block].TOCUnkMember1 != 0xFFFF)
- {
- yaftl_info.unknStructArray[yaftl_info.tocArray[ftl_block].TOCUnkMember1].field_8 ++ // need to id the structure
- temp = *(uint32_t*)(&yaftl_info.unknStructArray[yaftl_info.tocArray[ftl_block].TOCUnkMember1].buffer[(page_num + pagesRead) % yaftl_info.unkn3A_0x800]);
- }
- else
- {
- if ((unkBlock = isGoodBlock()) == 0xFFFF)
- {
- if (yaftl_info.unk140_n1 != ftl_block)
- {
- if ((ret = YAFTL_readPage(yaftl_info.tocArray[ftl_block].indexPage, yaftl_info.pageBuffer1, 0, 0, 1,1)) == 0)
- {
- yaftl_info.unk140_n1 = ftl_block;
- }
- else
- {
- set_ftl_region(0, 0, 0, 0);
- return ret;
- }
- }
- temp = yaftl_info.pageBuffer1[(page_num + pagesRead) % yaftl_info.unkn3A_0x800];
- }
- else
- {
- if (ret = (YAFTL_readPage(yaftl_info.tocArray[ftl_block].indexPage, &yaftl_info.unknStructArray[unkBlock].buffer[0], 0, 0, 1, 1)) == 0)
- yaftl_info.unkn4C --; // initiated in _readcxtinfo
- unknStructArray[unkBlock].field_A = 2; // need structure figured out of size 12 bytes
- unknStructArray[unkBlock].field_8 = 1;
- unknStructArray[unkBlock].field_4 = ftl_block;
- yaftl_info.tocArray[ftl_block].TOCUnkMember1 = unkBlock;
- temp = *(uint32_t*)(&unknStructArray[yaftl_info.tocArray[ftl_block].TOCUnkMember1].buffer[(page_num + pagesRead) % yaftl_info.unkn3A_0x800]);
- else
- {
- set_ftl_region(0, 0, 0, 0);
- return ret;
- }
- }
- if (temp == 0xFFFFFFFF)
- {
- if (nothingToDo)
- return 0;
- if (yaftl_readMultiPages(yaftl_info.unknBuffer3_ftl, var30, var2C, nothingToDo, 0, 1)
- {
- if (!(yaftl_verifyMetaData(page_num + (var2C - buf) / nand_geometry_ftl.bytes_per_page_ftl, yaftl_info.buffer20, var30)))
- ret = 0x80000002;
- }
- else
- {
- ret = 0x80000002;
- }
- }
- else
- {
- yaftl_info.unknBuffer3_ftl[var30] = yaftl_info.pageBuffer1[(page_num + pagesRead) % yaftl_info.unkn3A_0x800];
- var30 ++;
- if (var2C == 0)
- var2C = readBuf;
- if (var30 == nand_geometry_ftl.pages_per_block_total_banks)
- {
- if (nothingToDo)
- return 0;
- if (yaftl_readMultiPages(yaftl_info.unknBuffer3_ftl, var30, var2C, nothingToDo, 0, 1)
- {
- if (!(yaftl_verifyMetaData(page_num + (var2C - buf) / nand_geometry_ftl.bytes_per_page_ftl, yaftl_info.buffer20, var30)))
- ret = 0x80000002;
- }
- else
- {
- ret = 0x80000002;
- }
- }
- }
- var30 = 0;
- var2C = 0;
- pagesRead ++;
- readbuf += nand_geometry_ftl.bytes_per_page_ftl;
- }
- }
- }
- if (var30 == 0)
- {
- if (nothingToDo)
- return (0x80000002);
- set_ftl_region(0, 0, 0, 0);
- return ret;
- }
- if (nothingToDo)
- return 0;
- if (yaftl_readMultiPages(yaftl_info.unknBuffer3_ftl, var30, var2C, nothingToDo, 0, 1)
- {
- if (!(yaftl_verifyMetaData(page_num + (var2C - buf) / nand_geometry_ftl.bytes_per_page_ftl, yaftl_info.buffer20, var30)))
- ret = 0x80000002;
- }
- else
- {
- ret = 0x80000002;
- }
- set_ftl_region(0, 0, 0, 0);
- return ret;
- }