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; }
// 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; }
static Uint32 nandwriter() { Uint32 numPagesUBL; Uint32 numPagesAPP; NANDWRITER_Boot gNandBoot; NAND_InfoHandle hNandInfo; FILE *fPtr; Uint8 *ublPtr, *appPtr; Int32 ublFileSize = 0,ublAllocSize = 0, appFileSize = 0,appAllocSize = 0; Int8 fileName[256]; Int8 answer[24]; Int32 i=0; DEBUG_printString("Starting DM644x_NANDWriter.\r\n"); // Initialize NAND Flash hNandInfo = NAND_open((Uint32)&EMIFStart, (Uint8) DEVICE_emifBusWidth() ); if (hNandInfo == NULL) { DEBUG_printString( "\tERROR: NAND Initialization failed.\r\n" ); return E_FAIL; } // Read the file from host DEBUG_printString("Enter the binary UBL file Name (enter 'none' to skip) :\r\n"); DEBUG_readString(fileName); fflush(stdin); if (strcmp(fileName,"none") != 0) { // Open an File from the hard drive fPtr = fopen(fileName, "rb"); if(fPtr == NULL) { DEBUG_printString("\tERROR: File "); DEBUG_printString(fileName); DEBUG_printString(" open failed.\r\n"); return E_FAIL; } // Read file size fseek(fPtr,0,SEEK_END); ublFileSize = ftell(fPtr); if(ublFileSize == 0) { DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n"); fclose (fPtr); return E_FAIL; } numPagesUBL = 0; while ( (numPagesUBL * hNandInfo->dataBytesPerPage) < ublFileSize ) { numPagesUBL++; } //We want to allocate an even number of pages. ublAllocSize = numPagesUBL * hNandInfo->dataBytesPerPage; // Setup pointer in RAM ublPtr = (Uint8 *) UTIL_allocMem(ublAllocSize); for (i=0; i<ublAllocSize; i++) ublPtr[i]=0x00; fseek(fPtr,0,SEEK_SET); if (ublFileSize != fread(ublPtr, 1, ublFileSize, fPtr)) { DEBUG_printString("\tWARNING: File Size mismatch.\r\n"); } fclose (fPtr); gNandBoot.magicNum = UBL_MAGIC_SAFE; gNandBoot.block = DEVICE_NAND_RBL_SEARCH_START_BLOCK; gNandBoot.page = 0; gNandBoot.numPage = numPagesUBL; gNandBoot.entryPoint = 0x0100; // This fixed entry point will work with the UBLs gNandBoot.ldAddress = 0; // This doesn't matter for the UBL if (LOCAL_writeHeaderAndData(hNandInfo,&gNandBoot,ublPtr) != E_PASS) { printf("\tERROR: Write failed.\r\n"); return E_FAIL; } } // Read the file from host DEBUG_printString("Enter the U-boot or application file name (enter 'none' to skip):\r\n"); DEBUG_readString(fileName); fflush(stdin); if (strcmp(fileName,"none") != 0) { // Open an File from the hard drive fPtr = fopen(fileName, "rb"); if(fPtr == NULL) { DEBUG_printString("\tERROR: File "); DEBUG_printString(fileName); DEBUG_printString(" open failed.\r\n"); return E_FAIL; } // Read file size fseek(fPtr,0,SEEK_END); appFileSize = ftell(fPtr); if(appFileSize == 0) { DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n"); fclose (fPtr); return E_FAIL; } numPagesAPP = 0; while ( (numPagesAPP * hNandInfo->dataBytesPerPage) < (appFileSize) ) { numPagesAPP++; } // We want to allocate an even number of pages. appAllocSize = numPagesAPP * hNandInfo->dataBytesPerPage; // Setup pointer in RAM appPtr = (Uint8 *) UTIL_allocMem(appAllocSize); fseek(fPtr,0,SEEK_SET); if (appFileSize != fread(appPtr, 1, appFileSize, fPtr)) { DEBUG_printString("\tWARNING: File Size mismatch\n"); } fclose(fPtr); // Get the entry point and load addresses DEBUG_printString("Enter the U-boot or application entry point (in hex): \n"); DEBUG_readString(answer); gNandBoot.entryPoint = strtoul(answer, NULL, 16); fflush(stdin); if ( (gNandBoot.entryPoint < DEVICE_DDR2_START_ADDR) || (gNandBoot.entryPoint >= DEVICE_DDR2_END_ADDR) ) { DEBUG_printString("\tWARNING: Entry point not in acceptable range - using default 0x81080000.\r\n"); gNandBoot.entryPoint = 0x81080000; } else { DEBUG_printString("Selected entry point is "); DEBUG_printHexInt(gNandBoot.entryPoint); DEBUG_printString("\r\n"); } DEBUG_printString("Enter the U-boot or application load address (in hex): \r\n"); DEBUG_readString(answer); gNandBoot.ldAddress = strtoul(answer, NULL, 16); if ( (gNandBoot.ldAddress < DEVICE_DDR2_START_ADDR) || (gNandBoot.ldAddress >= DEVICE_DDR2_END_ADDR) ) { DEBUG_printString("\tWARNING: Load address not in acceptable range - using default 0x81080000.\r\n"); gNandBoot.ldAddress = 0x81080000; } gNandBoot.magicNum = UBL_MAGIC_BIN_IMG; gNandBoot.block = DEVICE_NAND_UBL_SEARCH_START_BLOCK; gNandBoot.page = 0; gNandBoot.numPage = numPagesAPP; if (LOCAL_writeHeaderAndData(hNandInfo, &gNandBoot, appPtr) != E_PASS) { DEBUG_printString("\tERROR: Write Failed\n"); return E_FAIL; } } 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; }
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; }
void main(void) { Uint8 regValue; // Init the memory alloc routines UTIL_setCurrMemPtr(0); // System init if (DEVICE_init() != E_PASS) { DEBUG_printString("Device initialization failed.\r\n"); return; } // Give some time for I2C bus to settle (power-supply issue?) UTIL_waitLoop(4000000); // Make sure our board and chip can read the NOR via EMIF if (I2C_ECP_write(I2C_ECP_VMX_REG,0x20) != E_PASS) { DEBUG_printString("Write to ECP EMIF/VP control register has failed.\r\n"); return; } DEVICE_pinmuxControl( 0, DEVICE_PINMUX_EMIF_MASK, DEVICE_PINMUX_EMIF_EN ); // Start body of UBL DEBUG_printString("Starting UBL - "); DEBUG_printString(UBL_FLASH_TYPE); DEBUG_printString(" Flash, v"); DEBUG_printString( UBL_VERSION_STRING ); DEBUG_printString("\r\n"); // Find and copy the application image from the NOR flash if (NORBOOT_copy() != E_PASS) { DEBUG_printString( "\tERROR: Application boot failed.\r\n" ); return; } // Modify board-level and chip-level settings to prep for application run // Set board-level muxes for video ports if (I2C_ECP_write(I2C_ECP_VMX_REG,0x44) != E_PASS) { DEBUG_printString("Write to ECP VP control register appears to have failed."); return; } // Set video port capture clocks for SD capture if (I2C_ECP_write(I2C_ECP_CMD_REG,0x08) != E_PASS) { DEBUG_printString("Write to ECP command register appears to have failed."); return; } // Set board-level muxes for audio codecs(AIC33s) if (I2C_ECP_write(I2C_ECP_McASP_MUX_CTRL_REG,0x19) != E_PASS) { DEBUG_printString("Write to ECP McASP control register appears to have failed."); return; } // Do one read to force the last write to complete I2C_ECP_read(I2C_ECP_McASP_MUX_CTRL_REG,®Value); DEBUG_printString("Board-level setup complete.\r\n"); // Set chip-level pin muxes for audio ports DEVICE_pinmuxControl( 0, DEVICE_PINMUX_MCASP_MASK, DEVICE_PINMUX_MCASP_EN ); // Set chip-level pin muxes for video ports DEVICE_pinmuxControl( 0, DEVICE_PINMUX_VP0_MASK | DEVICE_PINMUX_VP1_MASK | DEVICE_PINMUX_VP34_MASK | DEVICE_PINMUX_VP2_MASK, DEVICE_PINMUX_VP0_EN | DEVICE_PINMUX_VP1_EN | DEVICE_PINMUX_VP34_EN | DEVICE_PINMUX_VP2_EN ); DEBUG_printString("Chip-level setup complete.\r\n"); // Pass control to the entry point in RAM DEBUG_printString("Passing control to entry point at "); DEBUG_printHexInt(gEntryPoint); DEBUG_printString(".\r\n"); bootFunction = (AIS_fxnPtr) gEntryPoint; (*bootFunction)(); }
static Uint32 nandreader_ROM() { #if (1) Uint32 i,j, status; NAND_InfoHandle hNandInfo = &gMyNandInfo; #else Uint32 numPagesUBL; Uint32 numPagesAPP; Uint32 status; NANDWRITER_Boot gNandBoot; NAND_InfoHandle hNandInfo = &gMyNandInfo; FILE *fPtr; Uint8 *ublPtr, *appPtr; Int32 ublFileSize = 0,ublAllocSize = 0, appFileSize = 0,appAllocSize = 0; Int8 fileName[256]; Int8 answer[24]; #endif DEBUG_printString("Starting NANDReader_ROM.\r\n"); // Initialize NAND Flash (ROM init routine) status = NANDInit(); if (status != E_PASS) { DEBUG_printString( "\tERROR: NAND Initialization failed.\r\n" ); return E_FAIL; } hNandInfo->dataBytesPerPage = NANDFLASH_PAGESIZE(gNandInfo.page_size); hNandInfo->CSOffset = 0; hNandInfo->busWidth = (gNandInfo.nand_width==0)?BUS_8BIT:BUS_16BIT; hNandInfo->dataBytesPerOp = 512; hNandInfo->devID = gNandInfo.dev_code; hNandInfo->flashBase = 0x02000000; hNandInfo->spareBytesPerOp = 16; hNandInfo->pagesPerBlock = 0x1 << (gNandInfo.blk_shift - gNandInfo.page_shift); hNandInfo->isLargePage = gNandInfo.big_block; hNandInfo->numColAddrBytes = gNandInfo.page_shift >> 3; hNandInfo->numRowAddrBytes = gNandInfo.addr_cycles - hNandInfo->numColAddrBytes; #if (0) // Read the file from host DEBUG_printString("Enter the binary UBL file Name (enter 'none' to skip) :\r\n"); DEBUG_readString(fileName); fflush(stdin); if (strcmp(fileName,"none") != 0) { // Open an File from the hard drive fPtr = fopen(fileName, "rb"); if(fPtr == NULL) { DEBUG_printString("\tERROR: File "); DEBUG_printString(fileName); DEBUG_printString(" open failed.\r\n"); return E_FAIL; } // Read file size fseek(fPtr,0,SEEK_END); ublFileSize = ftell(fPtr); if(ublFileSize == 0) { DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n"); fclose (fPtr); return E_FAIL; } numPagesUBL = 0; while ( (numPagesUBL * hNandInfo->dataBytesPerPage) < ublFileSize ) { numPagesUBL++; } //We want to allocate an even number of pages. ublAllocSize = numPagesUBL * hNandInfo->dataBytesPerPage; // Setup pointer in RAM ublPtr = (Uint8 *) UTIL_allocMem(ublAllocSize); for (i=0; i<ublAllocSize; i++) ublPtr[i]=0x00; fseek(fPtr,0,SEEK_SET); if (ublFileSize != fread(ublPtr, 1, ublFileSize, fPtr)) { DEBUG_printString("\tWARNING: File Size mismatch.\r\n"); } fclose (fPtr); gNandBoot.magicNum = UBL_MAGIC_SAFE; gNandBoot.block = DEVICE_NAND_RBL_SEARCH_START_BLOCK; gNandBoot.page = 0; gNandBoot.numPage = numPagesUBL; gNandBoot.entryPoint = 0x0100; // This fixed entry point will work with the UBLs gNandBoot.ldAddress = 0; // This doesn't matter for the UBL if (LOCAL_readHeaderAndData(hNandInfo,&gNandBoot,ublPtr) != E_PASS) { printf("\tERROR: Read failed.\r\n"); return E_FAIL; } } // Read the file from host DEBUG_printString("Enter the U-boot or application file name (enter 'none' to skip):\r\n"); DEBUG_readString(fileName); fflush(stdin); if (strcmp(fileName,"none") != 0) { // Open an File from the hard drive fPtr = fopen(fileName, "rb"); if(fPtr == NULL) { DEBUG_printString("\tERROR: File "); DEBUG_printString(fileName); DEBUG_printString(" open failed.\r\n"); return E_FAIL; } // Read file size fseek(fPtr,0,SEEK_END); appFileSize = ftell(fPtr); if(appFileSize == 0) { DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n"); fclose (fPtr); return E_FAIL; } numPagesAPP = 0; while ( (numPagesAPP * hNandInfo->dataBytesPerPage) < (appFileSize) ) { numPagesAPP++; } // We want to allocate an even number of pages. appAllocSize = numPagesAPP * hNandInfo->dataBytesPerPage; // Setup pointer in RAM appPtr = (Uint8 *) UTIL_allocMem(appAllocSize); fseek(fPtr,0,SEEK_SET); if (appFileSize != fread(appPtr, 1, appFileSize, fPtr)) { DEBUG_printString("\tWARNING: File Size mismatch\n"); } fclose(fPtr); // Get the entry point and load addresses DEBUG_printString("Enter the U-boot or application entry point (in hex): \n"); DEBUG_readString(answer); gNandBoot.entryPoint = strtoul(answer, NULL, 16); fflush(stdin); if ( (gNandBoot.entryPoint < DEVICE_DDR2_START_ADDR) || (gNandBoot.entryPoint >= DEVICE_DDR2_END_ADDR) ) { DEBUG_printString("\tWARNING: Entry point not in acceptable range - using default 0x81080000.\r\n"); gNandBoot.entryPoint = 0x81080000; } else { DEBUG_printString("Selected entry point is "); DEBUG_printHexInt(gNandBoot.entryPoint); DEBUG_printString("\r\n"); } DEBUG_printString("Enter the U-boot or application load address (in hex): \r\n"); DEBUG_readString(answer); gNandBoot.ldAddress = strtoul(answer, NULL, 16); if ( (gNandBoot.ldAddress < DEVICE_DDR2_START_ADDR) || (gNandBoot.ldAddress >= DEVICE_DDR2_END_ADDR) ) { DEBUG_printString("\tWARNING: Load address not in acceptable range - using default 0x81080000.\r\n"); gNandBoot.ldAddress = 0x81080000; } gNandBoot.magicNum = UBL_MAGIC_BIN_IMG; gNandBoot.block = DEVICE_NAND_UBL_SEARCH_START_BLOCK; gNandBoot.page = 0; gNandBoot.numPage = numPagesAPP; if (LOCAL_readHeaderAndData(hNandInfo, &gNandBoot, appPtr) != E_PASS) { DEBUG_printString("\tERROR: Write Failed\n"); return E_FAIL; } } #else for (i = 1; i <= 5; i++) { for (j=0; j < hNandInfo->pagesPerBlock; j++) { DEBUG_printString("Block "); DEBUG_printHexInt(i); DEBUG_printString(", Page "); DEBUG_printHexInt(j); if (NANDReadPage(i,j,gNandRx) != E_PASS) { DEBUG_printString("\r\n\tRead failed\r\n"); break; } DEBUG_printString("\r\n\t1st Word = "); DEBUG_printHexInt(((Uint32 *)gNandRx)[0]); DEBUG_printString("\r\n\t2nd Word = "); DEBUG_printHexInt(((Uint32 *)gNandRx)[1]); DEBUG_printString("\r\n\t3rd Word = "); DEBUG_printHexInt(((Uint32 *)gNandRx)[2]); DEBUG_printString("\r\n\t4th Word = "); DEBUG_printHexInt(((Uint32 *)gNandRx)[3]); DEBUG_printString("\r\n"); } } #endif return E_PASS; }