// Generic function to write a UBL or Application header and the associated data static Uint32 LOCAL_writeData(NAND_InfoHandle hNandInfo, Uint8 *srcBuf, Uint32 totalPageCnt) { Uint32 blockNum,pageNum,pageCnt; Uint32 numBlks; Uint32 i; Uint8 *dataPtr; gNandTx = (Uint8 *) UTIL_allocMem(NAND_MAX_PAGE_SIZE); gNandRx = (Uint8 *) UTIL_allocMem(NAND_MAX_PAGE_SIZE); for (i=0; i<NAND_MAX_PAGE_SIZE; i++) { gNandTx[i]=0xff; gNandRx[i]=0xff; } // Get total number of blocks needed numBlks = 0; while ( (numBlks*hNandInfo->pagesPerBlock) < totalPageCnt ) { numBlks++; } DEBUG_printString("Number of blocks needed for data: "); DEBUG_printHexInt(numBlks); DEBUG_printString("\r\n"); // Start in block 1 (leave block 0 alone) blockNum = 1; // Unprotect all blocks of the device if (NAND_unProtectBlocks(hNandInfo, blockNum, (hNandInfo->numBlocks-1)) != E_PASS) { blockNum++; DEBUG_printString("Unprotect failed.\r\n"); return E_FAIL; } while (blockNum < hNandInfo->numBlocks) { // Find first good block while (NAND_badBlockCheck(hNandInfo,blockNum) != E_PASS) { blockNum++; } // Erase the current block NAND_eraseBlocks(hNandInfo,blockNum,1); // Start writing in page 0 of current block pageNum = 0; pageCnt = 0; // Setup data pointer dataPtr = srcBuf; // Start page writing loop do { DEBUG_printString((Uint8 *)"Writing image data to block "); DEBUG_printHexInt(blockNum); DEBUG_printString((Uint8 *)", page "); DEBUG_printHexInt(pageNum); DEBUG_printString((Uint8 *)"\r\n"); // Write the AIS image data to the NAND device if (NAND_writePage(hNandInfo, blockNum, pageNum, dataPtr) != E_PASS) { DEBUG_printString("Write failed. Marking block as bad...\n"); NAND_reset(hNandInfo); NAND_badBlockMark(hNandInfo,blockNum); dataPtr -= pageNum * hNandInfo->dataBytesPerPage; blockNum++; continue; } UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, blockNum, pageNum, dataPtr, gNandRx) != E_PASS) { DEBUG_printString("Verify failed. Marking block as bad...\n"); NAND_reset(hNandInfo); NAND_badBlockMark(hNandInfo,blockNum); dataPtr -= pageNum * hNandInfo->dataBytesPerPage; blockNum++; continue; } pageNum++; pageCnt++; dataPtr += hNandInfo->dataBytesPerPage; if (pageNum == hNandInfo->pagesPerBlock) { // A block transition needs to take place; go to next good block do { blockNum++; } while (NAND_badBlockCheck(hNandInfo,blockNum) != E_PASS); // Erase the current block NAND_eraseBlocks(hNandInfo,blockNum,1); pageNum = 0; } } while (pageCnt < totalPageCnt); NAND_protectBlocks(hNandInfo); break; } return E_PASS; }
// Generic function to write a UBL or Application header and the associated data static Uint32 LOCAL_writeHeaderAndData(NAND_InfoHandle hNandInfo, NANDWRITER_Boot *nandBoot, Uint8 *srcBuf) { Uint32 endBlockNum; Uint32 *headerPtr; Uint32 blockNum; Uint32 count; Uint32 countMask; Uint32 numBlks; Uint32 pageNum; Uint32 i; Uint8 *dataPtr; gNandTx = (Uint8 *) UTIL_allocMem(NAND_MAX_PAGE_SIZE); gNandRx = (Uint8 *) UTIL_allocMem(NAND_MAX_PAGE_SIZE); for (i=0; i<NAND_MAX_PAGE_SIZE; i++) { gNandTx[i]=0xff; gNandRx[i]=0xff; } // Get total number of blocks needed numBlks = 0; while ( (numBlks * hNandInfo->pagesPerBlock) < (nandBoot->numPage + 1) ) { numBlks++; } DEBUG_printString("Number of blocks needed for header and data: "); DEBUG_printHexInt(numBlks); DEBUG_printString("\r\n"); // Check whether writing UBL or APP (based on destination block) blockNum = nandBoot->block; if (blockNum == DEVICE_NAND_RBL_SEARCH_START_BLOCK) { endBlockNum = DEVICE_NAND_RBL_SEARCH_END_BLOCK; } else if (blockNum == DEVICE_NAND_UBL_SEARCH_START_BLOCK) { endBlockNum = DEVICE_NAND_UBL_SEARCH_END_BLOCK; } else { // Block number is out of range return E_FAIL; } NAND_WRITE_RETRY: if (blockNum > endBlockNum) { return E_FAIL; } DEBUG_printString("Attempting to start write in block number "); DEBUG_printHexInt(blockNum); DEBUG_printString(".\r\n"); // Unprotect all needed blocks of the Flash if (NAND_unProtectBlocks(hNandInfo,blockNum,numBlks) != E_PASS) { blockNum++; DEBUG_printString("Unprotect failed.\r\n"); goto NAND_WRITE_RETRY; } // Setup header to be written headerPtr = (Uint32 *) gNandTx; headerPtr[0] = nandBoot->magicNum; //Magic Number headerPtr[1] = nandBoot->entryPoint; //Entry Point headerPtr[2] = nandBoot->numPage; //Number of Pages headerPtr[3] = blockNum; //Starting Block Number headerPtr[4] = 1; //Starting Page Number - always start data in page 1 (this header goes in page 0) if ( (blockNum>=DEVICE_NAND_RBL_SEARCH_START_BLOCK) && (blockNum <= DEVICE_NAND_RBL_SEARCH_END_BLOCK) ) { headerPtr[5] = 0; //nandBoot->ldAddress; } else if ( (blockNum>=DEVICE_NAND_UBL_SEARCH_START_BLOCK) && (blockNum<=DEVICE_NAND_UBL_SEARCH_END_BLOCK) ) { headerPtr[5] = nandBoot->ldAddress; //nandBoot->ldAddress; } else { // Block number is out of range return E_FAIL; } pageNum = 0; // Erase the block where the header goes and the data starts if (NAND_eraseBlocks(hNandInfo,blockNum,numBlks) != E_PASS) { blockNum++; DEBUG_printString("Erase failed\n"); goto NAND_WRITE_RETRY; } DEBUG_printString("Writing header data to Block "); DEBUG_printHexInt(blockNum); DEBUG_printString(", Page "); DEBUG_printHexInt(pageNum); DEBUG_printString("\r\n"); if (NAND_writePage(hNandInfo, blockNum, pageNum, gNandTx) != E_PASS) { blockNum++; DEBUG_printString("Write failed\n"); NAND_reset(hNandInfo); goto NAND_WRITE_RETRY; } UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, blockNum, pageNum, gNandTx, gNandRx) != E_PASS) { DEBUG_printString("Verify failed. Attempting to clear page\n"); NAND_reset(hNandInfo); NAND_eraseBlocks(hNandInfo,blockNum,numBlks); blockNum++; NAND_reset(hNandInfo); goto NAND_WRITE_RETRY; } // Start writing in page 1 of current block (header was in page 0) count = 1; // The following assumes power of 2 pagesPerBlock - *should* always be valid countMask = (Uint32) hNandInfo->pagesPerBlock - 1; dataPtr = srcBuf; do { DEBUG_printString((Uint8 *)"Writing image data to Block "); DEBUG_printHexInt(blockNum); DEBUG_printString((Uint8 *)", Page "); DEBUG_printHexInt(count & countMask); DEBUG_printString((Uint8 *)"\r\n"); // Write the UBL or APP data on a per page basis if (NAND_writePage(hNandInfo, blockNum, (count & countMask), dataPtr) != E_PASS) { blockNum++; DEBUG_printString("Write failed\n"); goto NAND_WRITE_RETRY; } UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, blockNum, (count & countMask), dataPtr, gNandRx) != E_PASS) { DEBUG_printString("Verify failed. Attempting to clear page\n"); NAND_reset(hNandInfo); NAND_eraseBlocks(hNandInfo,blockNum,numBlks); blockNum++; goto NAND_WRITE_RETRY; } count++; dataPtr += hNandInfo->dataBytesPerPage; if (!(count & countMask)) { do { blockNum++; } while (NAND_badBlockCheck(hNandInfo,blockNum) != E_PASS); } } while (count <= nandBoot->numPage); NAND_protectBlocks(hNandInfo); return E_PASS; }
static Uint32 LOCAL_NANDWriteHeaderAndData(NAND_InfoHandle hNandInfo, NANDBOOT_HeaderHandle nandBoot, Uint8 *srcBuf) { Uint32 endBlockNum; Uint32 *ptr; Uint32 blockNum,pageNum,pageCnt,i; Uint32 numBlks; Uint8 *hNandWriteBuf,*hNandReadBuf; // Allocate mem for write and read buffers hNandWriteBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage); hNandReadBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage); // Clear buffers for (i=0; i < hNandInfo->dataBytesPerPage; i++) { hNandWriteBuf[i] = 0xFF; hNandReadBuf[i] = 0xFF; } // Get total number of blocks needed numBlks = 0; while ( (numBlks * hNandInfo->pagesPerBlock) < (nandBoot->numPage + 1) ) { numBlks++; } DEBUG_printString("Number of blocks needed for header and data: 0x"); DEBUG_printHexInt(numBlks); DEBUG_printString("\r\n"); // Check whether writing UBL or APP (based on destination block) blockNum = nandBoot->block; if (blockNum == DEVICE_NAND_RBL_SEARCH_START_BLOCK) endBlockNum = DEVICE_NAND_RBL_SEARCH_END_BLOCK; else if (blockNum == DEVICE_NAND_UBL_SEARCH_START_BLOCK) endBlockNum = DEVICE_NAND_UBL_SEARCH_END_BLOCK; else return E_FAIL; // Block number is out of range NAND_WRITE_RETRY: if (blockNum > endBlockNum) return E_FAIL; // Go to first good block if (NAND_badBlockCheck(hNandInfo,blockNum) != E_PASS) { blockNum++; goto NAND_WRITE_RETRY; } DEBUG_printString("Attempting to start in block number 0x"); DEBUG_printHexInt(blockNum); DEBUG_printString(".\n"); // Unprotect all needed blocks of the Flash if (NAND_unProtectBlocks(hNandInfo,blockNum,numBlks) != E_PASS) { blockNum++; DEBUG_printString("Unprotect failed\r\n"); goto NAND_WRITE_RETRY; } // Erase the block where the header goes and the data starts if (NAND_eraseBlocks(hNandInfo,blockNum,numBlks) != E_PASS) { blockNum++; DEBUG_printString("Erase failed\r\n"); goto NAND_WRITE_RETRY; } // Setup header to be written ptr = (Uint32 *) hNandWriteBuf; ptr[0] = nandBoot->magicNum; ptr[1] = nandBoot->entryPoint; ptr[2] = nandBoot->numPage; ptr[3] = blockNum; //always start data in current block ptr[4] = 1; //always start data in page 1 (this header goes in page 0) ptr[5] = nandBoot->ldAddress; // Write the header to page 0 of the current blockNum DEBUG_printString("Writing header data to Block "); DEBUG_printHexInt(blockNum); DEBUG_printString(", Page "); DEBUG_printHexInt(0); DEBUG_printString("\r\n"); if (NAND_writePage(hNandInfo, blockNum, 0, hNandWriteBuf) != E_PASS) { blockNum++; DEBUG_printString("Write failed!\r\n"); goto NAND_WRITE_RETRY; } UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, blockNum, 0, hNandWriteBuf, hNandReadBuf) != E_PASS) { blockNum++; DEBUG_printString("Write verify failed!\r\n"); goto NAND_WRITE_RETRY; } pageCnt = 1; pageNum = 1; do { DEBUG_printString("Writing image data to Block "); DEBUG_printHexInt(blockNum); DEBUG_printString(", Page "); DEBUG_printHexInt(pageNum); DEBUG_printString("\r\n"); // Write the UBL or APP data on a per page basis if (NAND_writePage(hNandInfo, blockNum, pageNum, srcBuf) != E_PASS) { blockNum++; DEBUG_printString("Write failed!\r\n"); goto NAND_WRITE_RETRY; } UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, blockNum, pageNum, srcBuf, hNandReadBuf) != E_PASS) { blockNum++; DEBUG_printString("Write verify failed!\r\n"); goto NAND_WRITE_RETRY; } srcBuf += hNandInfo->dataBytesPerPage; pageCnt++; pageNum++; if (pageNum == hNandInfo->pagesPerBlock) { blockNum++; pageNum = 0; } } while (pageCnt < (nandBoot->numPage+1)); NAND_protectBlocks(hNandInfo); return E_PASS; }
Uint32 LOCAL_NANDWriteHeaderAndData(NAND_InfoHandle hNandInfo, NANDBOOT_HeaderHandle hNandBoot, Uint8 *srcBuf) { Uint32 *ptr; Uint32 currBlockNum,currPageNum,pageCnt,i; Uint32 numBlks, numBlksRemaining; trl_(); trvx_(hNandBoot->startBlock); trvx(hNandBoot->endBlock); trvx(srcBuf); hNandWriteBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage); hNandReadBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage); extern __FAR__ Uint32 EXTERNAL_RAM_START, EXTERNAL_RAM_END; trvx(&EXTERNAL_RAM_START); trvx(hNandWriteBuf); trvx(hNandReadBuf); // Unprotect all needed blocks of the flash if (NAND_unProtectBlocks(hNandInfo,hNandBoot->startBlock,hNandBoot->endBlock-hNandBoot->startBlock+1) != E_PASS) { DEBUG_printString("Unprotect failed\r\n"); return E_FAIL; } // Check if device is write protected if (NAND_isWriteProtected(hNandInfo)) { DEBUG_printString("NAND is write protected!\r\n"); return E_FAIL; } // Get total number of blocks needed for each copy numBlks = 0; while ( (numBlks * hNandInfo->pagesPerBlock) < (hNandBoot->numPage + 1) ) { numBlks++; } DEBUG_printString("Number of blocks needed for header and data: 0x"); DEBUG_printHexInt(numBlks); DEBUG_printString("\r\n"); // Init internal current block number counter currBlockNum = hNandBoot->startBlock; // Go to first good block while (NAND_badBlockCheck(hNandInfo,currBlockNum) != E_PASS) { DEBUG_printString("NAND block "); DEBUG_printHexInt(currBlockNum); DEBUG_printString(" is bad!!!\r\n"); currBlockNum++; // Now check to make sure we aren't already out of space if (currBlockNum > (hNandBoot->endBlock + numBlks - 1 )) { DEBUG_printString("No good blocks in allowed range!!!\r\n"); return E_FAIL; } } DEBUG_printString("Attempting to start in block number 0x"); DEBUG_printHexInt(currBlockNum); DEBUG_printString(".\r\n"); // Keep going while we have room to place another copy do { numBlksRemaining = numBlks; // Erase the block where the header goes and the data starts if (NAND_eraseBlocks(hNandInfo,currBlockNum,numBlks) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Erase failed\r\n"); continue; } trl(); // Clear write buffer ptr = (Uint32 *) hNandWriteBuf; for (i=0; i < hNandInfo->dataBytesPerPage >> 2; i++) { ptr[i] = 0xFFFFFFFF; } trl(); // Setup header to be written ptr[0] = hNandBoot->magicNum; ptr[1] = hNandBoot->entryPoint; ptr[2] = hNandBoot->numPage; ptr[3] = currBlockNum; //always start data in current block ptr[4] = 1; //always start data in page 1 (this header goes in page 0) ptr[5] = hNandBoot->ldAddress; // Write the header to page 0 of the current blockNum DEBUG_printString("Writing header and image data to Block "); DEBUG_printHexInt(currBlockNum); DEBUG_printString(", Page "); DEBUG_printHexInt(0); DEBUG_printString("\r\n"); trl(); #ifdef DM35X_REVB #define DM35X_REVC #endif #ifdef DM35X_REVC if (NAND_writePage_ubl_header(hNandInfo, currBlockNum, 0, hNandWriteBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Write failed!\r\n"); continue; } #else if (NAND_writePage(hNandInfo, currBlockNum, 0, hNandWriteBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Write failed!\r\n"); continue; } #endif UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, currBlockNum, 0, hNandWriteBuf, hNandReadBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Write verify failed!\r\n"); continue; } pageCnt = 1; currPageNum = 1; do { // Write the UBL or APP data on a per page basis if (NAND_writePage(hNandInfo, currBlockNum, currPageNum, srcBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Write failed, skipping block!\r\n"); if ( (numBlksRemaining == numBlks) || (hNandBoot->forceContigImage) ) break; // If we are still in the first block, we have to go rewrite the header too else { srcBuf -= (hNandInfo->dataBytesPerPage * currPageNum); trvx(srcBuf); pageCnt -= currPageNum; currPageNum = 0; continue; } } UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, currBlockNum, currPageNum, srcBuf, hNandReadBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString(RED"Write verify failed, skipping block!\r\n"NOCOLOR); if ( (numBlksRemaining == numBlks) || (hNandBoot->forceContigImage) ) break; // If we are still in the first block, we have to go rewrite the header too else { srcBuf -= (hNandInfo->dataBytesPerPage * currPageNum); trvx(srcBuf); pageCnt -= currPageNum; currPageNum = 0; continue; } } srcBuf += hNandInfo->dataBytesPerPage; pageCnt++; currPageNum++; // If we need to go the next block, or our image is complete, increment current block num if ( (currPageNum == hNandInfo->pagesPerBlock) || (pageCnt >= (hNandBoot->numPage+1)) ) { trvi(currPageNum); currBlockNum++; numBlksRemaining--; srcBuf -= hNandInfo->dataBytesPerPage * currPageNum; currPageNum = 0; } } while ( (pageCnt < (hNandBoot->numPage+1)) && ((currBlockNum + numBlksRemaining - 1)<=hNandBoot->endBlock) ); trvi(pageCnt); } while( (currBlockNum + numBlks - 1)<=hNandBoot->endBlock ); // Protect all blocks NAND_protectBlocks(hNandInfo); // We succeeded in writing all copies that would fit return E_PASS; }