static Uint32 nandwriter() { Uint32 numPagesAIS; NAND_InfoHandle hNandInfo; FILE *fPtr; Uint8 *aisPtr; Int32 aisFileSize = 0,aisAllocSize = 0; Int8 fileName[256]; Int32 i=0; DEBUG_printString("Starting OMAP-L137 NANDWriter.\r\n"); // Initialize NAND Flash hNandInfo = NAND_open((Uint32)&NANDStart, 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 AIS file name to flash (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); aisFileSize = ftell(fPtr); if(aisFileSize == 0) { DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n"); fclose (fPtr); return E_FAIL; } numPagesAIS = 0; while ( (numPagesAIS * hNandInfo->dataBytesPerPage) < aisFileSize ) { numPagesAIS++; } //We want to allocate an even number of pages. aisAllocSize = numPagesAIS * hNandInfo->dataBytesPerPage; // Setup pointer in RAM aisPtr = (Uint8 *) UTIL_allocMem(aisAllocSize); // Clear memory for (i=0; i<aisAllocSize; i++) aisPtr[i]=0xFF; // Go to start of file fseek(fPtr,0,SEEK_SET); // Read file data if (aisFileSize != fread(aisPtr, 1, aisFileSize, fPtr)) { DEBUG_printString("\tWARNING: File Size mismatch.\r\n"); } // Close file fclose (fPtr); // Write the file data to the NAND flash if (LOCAL_writeData(hNandInfo, aisPtr, numPagesAIS) != E_PASS) { printf("\tERROR: Write failed.\r\n"); return E_FAIL; } } return E_PASS; }
static Uint32 norwriter() { NOR_InfoHandle hNorInfo; FILE *fPtr; Uint8 *appPtr; Int32 appFileSize = 0; Int8 fileName[256]; Uint32 baseAddress = 0; DEBUG_printString( "Starting NORWriter.\r\n"); // Initialize NOR Flash hNorInfo = NOR_open((Uint32)&NORStart, (Uint8)DEVICE_emifBusWidth() ); if (hNorInfo == NULL) { DEBUG_printString( "\tERROR: NOR Initialization failed.\r\n" ); return E_FAIL; } // Set base address to start putting data at baseAddress = hNorInfo->flashBase; // Read the UBL file from host DEBUG_printString("Enter the binary AIS application file name (enter 'none' to skip): \r\n"); #ifndef INPUT_FILE DEBUG_readString(fileName); fflush(stdin); #else strcpy(fileName, "../../../../../proj/ais/tcas_decoder.ais"); #endif 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; } // Initialize the pointer appFileSize = 0; // Read file size fseek(fPtr,0,SEEK_END); appFileSize = ftell(fPtr); // Check to make sure image was read correctly if(appFileSize == 0) { DEBUG_printString("\tERROR: File read failed.\r\n"); fclose (fPtr); return E_FAIL; } // Check to make sure the app image will fit else if ( appFileSize > hNorInfo->flashSize ) { DEBUG_printString("\tERROR: File too big.. Closing program.\r\n"); fclose (fPtr); } // Setup pointer in RAM appPtr = (Uint8 *) UTIL_allocMem(appFileSize); fseek(fPtr,0,SEEK_SET); if (appFileSize != fread(appPtr, 1, appFileSize, fPtr)) { DEBUG_printString("\tWARNING: File Size mismatch.\r\n"); } fclose (fPtr); // Erase the NOR flash to accomadate the file size if (NOR_erase( hNorInfo, baseAddress, appFileSize ) != E_PASS) { DEBUG_printString("\tERROR: Erasing NOR failed.\r\n"); return E_FAIL; } // Write the application data to the flash if (NOR_writeBytes( hNorInfo, baseAddress, appFileSize, (Uint32)appPtr) != E_PASS) { DEBUG_printString("\tERROR: Writing NOR failed.\r\n"); return E_FAIL; } } 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; }
Uint32 UARTBOOT_copy(void) { #if defined(UBL_NAND) NANDBOOT_HeaderObj nandBoot; NAND_InfoHandle hNandInfo; #elif defined(UBL_NOR) NOR_InfoHandle hNorInfo; #endif UARTBOOT_HeaderObj ackHeader; Uint32 bootCmd; UART_tryAgain: DEBUG_printString("Starting UART Boot...\r\n"); // UBL Sends 'BOOTUBL/0' if (LOCAL_sendSequence("BOOTUBL") != E_PASS) goto UART_tryAgain; // Receive the BOOT command if(LOCAL_recvCommand(&bootCmd) != E_PASS) goto UART_tryAgain; // Send ^^^DONE\0 to indicate command was accepted if ( LOCAL_sendSequence(" DONE") != E_PASS ) goto UART_tryAgain; switch(bootCmd) { #if defined(UBL_NOR) case UBL_MAGIC_NOR_BIN_BURN: { // Initialize the NOR Flash hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth()) ; if (hNorInfo == NULL) { DEBUG_printString("NOR_open() failed!"); goto UART_tryAgain; } // Get the APP (should be u-boot) into binary form if ( LOCAL_recvHeaderAndData(&ackHeader) != E_PASS ) goto UART_tryAgain; // Erasing the Flash if ( NOR_erase(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt) != E_PASS ) goto UART_tryAgain; // Write the actual application to the flash if ( NOR_writeBytes(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt, (Uint32)ackHeader.imageBuff) != E_PASS ) goto UART_tryAgain; // Return DONE when UBL flash operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point for code execution gEntryPoint = hNorInfo->flashBase; break; } case UBL_MAGIC_NOR_GLOBAL_ERASE: { // Initialize the NOR Flash hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth()) ; if (hNorInfo == NULL) { DEBUG_printString("NOR_open() failed!"); goto UART_tryAgain; } // Erasing the Flash if (NOR_globalErase(hNorInfo) != E_PASS) { DEBUG_printString("\r\nErase failed.\r\n"); } else { DEBUG_printString("\r\nErase completed successfully.\r\n"); } // Return DONE when erase operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point for code execution // Go to reset in this case since no code was downloaded gEntryPoint = 0x0; break; } #elif defined(UBL_NAND) case UBL_MAGIC_NAND_BIN_BURN: { // Initialize the NAND Flash hNandInfo = NAND_open((Uint32)&EMIFStart); if ( hNandInfo == NULL ) { DEBUG_printString("NAND_open() failed!"); goto UART_tryAgain; } // ------ Get UBL Data and Write it to Flash ------ // Get the UBL header and data if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS) goto UART_tryAgain; // Setup the NANDBOOT header that will be stored in flash nandBoot.magicNum = ackHeader.magicNum; nandBoot.entryPoint = ackHeader.startAddr; nandBoot.page = 1; // The page is always page 0 for the UBL header, so we use page 1 for data nandBoot.block = DEVICE_NAND_RBL_SEARCH_START_BLOCK; // Set starting block to begin the write attempts nandBoot.ldAddress = ackHeader.loadAddr; // This field doesn't matter for the UBL header // Calculate the number of NAND pages needed to store the UBL image nandBoot.numPage = 0; while ( (nandBoot.numPage * hNandInfo->dataBytesPerPage) < (ackHeader.byteCnt)) { nandBoot.numPage++; } // Write header to page 0 of block 1(or up to block 5) // Write the UBL to the same block, starting at page 1 DEBUG_printString("Writing UBL to NAND flash\r\n"); if (LOCAL_NANDWriteHeaderAndData(hNandInfo, &nandBoot, ackHeader.imageBuff) != E_PASS) goto UART_tryAgain; // Return DONE when UBL flash operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // ------ Get Application Data and Write it to Flash ------ // Get the application header and data if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS) goto UART_tryAgain; // Setup the NANDBOOT header that will be stored in flash nandBoot.magicNum = ackHeader.magicNum; // Rely on the host applciation to send over the right magic number (safe or bin) nandBoot.entryPoint = ackHeader.startAddr; // Use the entrypoint received in ACK header nandBoot.page = 1; // The page is always page 0 for the header, so we use page 1 for data nandBoot.block = DEVICE_NAND_UBL_SEARCH_START_BLOCK; // Set the starting block for application nandBoot.ldAddress = ackHeader.loadAddr; // The load address is only important if this is a binary image // Calculate the number of NAND pages needed to store the APP image nandBoot.numPage = 0; while ( (nandBoot.numPage * hNandInfo->dataBytesPerPage) < ackHeader.byteCnt ) { nandBoot.numPage++; } // Write header to page 0 of block 1(or up to block 5) // Write the UBL to the same block, starting at page 1 DEBUG_printString("Writing APP to NAND flash\r\n"); if (LOCAL_NANDWriteHeaderAndData(hNandInfo,&nandBoot, ackHeader.imageBuff) != E_PASS) goto UART_tryAgain; // Return DONE when UBL flash operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point to nowhere, since there isn't an appropriate binary image to run */ gEntryPoint = 0x0; break; } // end case UBL_MAGIC_NAND_BIN_BURN case UBL_MAGIC_NAND_GLOBAL_ERASE: { // Initialize the NAND Flash hNandInfo = NAND_open((Uint32)&EMIFStart); if ( hNandInfo == NULL ) { DEBUG_printString("NAND_open() failed!"); goto UART_tryAgain; } // Unprotect the NAND Flash NAND_unProtectBlocks(hNandInfo, DEVICE_NAND_RBL_SEARCH_START_BLOCK, DEVICE_NAND_UBL_SEARCH_END_BLOCK-1); // Erase all the pages of the device if (NAND_eraseBlocks(hNandInfo, DEVICE_NAND_RBL_SEARCH_START_BLOCK, DEVICE_NAND_UBL_SEARCH_END_BLOCK-1) != E_PASS) { DEBUG_printString("Erase failed.\r\n"); goto UART_tryAgain; } else { DEBUG_printString("Erase completed successfully.\r\n"); } // Protect the device NAND_protectBlocks(hNandInfo); // Return DONE when erase operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point for code execution // Go to reset in this case since no code was downloaded gEntryPoint = 0x0; break; } #endif default: { DEBUG_printString("Boot command not supported!"); return E_FAIL; } } LOCAL_sendSequence(" DONE"); return E_PASS; }
Uint32 UARTBOOT_copy(void) { #if defined(UBL_NAND) NANDBOOT_HeaderObj nandBoot; NAND_InfoHandle hNandInfo; #elif defined(UBL_NOR) NORBOOT_HeaderObj norBoot; NOR_InfoHandle hNorInfo; #endif UARTBOOT_HeaderObj ackHeader; Uint32 bootCmd; UART_tryAgain: DEBUG_printString("Starting UART Boot...\r\n"); // UBL Sends 'BOOTUBL/0' if (LOCAL_sendSequence("BOOTUBL") != E_PASS) goto UART_tryAgain; // Receive the BOOT command if(LOCAL_recvCommand(&bootCmd) != E_PASS) goto UART_tryAgain; // Send ^^^DONE\0 to indicate command was accepted if ( LOCAL_sendSequence(" DONE") != E_PASS ) goto UART_tryAgain; switch(bootCmd) { #if defined(UBL_NOR) case UBL_MAGIC_NOR_FLASH_NO_UBL: { // Initialize the NOR Flash hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth()); if (hNorInfo == NULL) { DEBUG_printString("NOR_open() failed!"); goto UART_tryAgain; } // Get the APP (should be u-boot) into binary form if ( LOCAL_recvHeaderAndData(&ackHeader) != E_PASS ) goto UART_tryAgain; // Erasing the Flash if ( NOR_erase(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt) != E_PASS ) goto UART_tryAgain; // Write the actual application to the flash if ( NOR_writeBytes(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt, (Uint32)ackHeader.imageBuff) != E_PASS ) goto UART_tryAgain; // Return DONE when UBL flash operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point for code execution gEntryPoint = hNorInfo->flashBase; break; } case UBL_MAGIC_NOR_FLASH: { Uint32 blockSize, blockAddr; // Initialize the NAND Flash hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth()); if ( hNorInfo == NULL ) { DEBUG_printString("NOR_open() failed!"); goto UART_tryAgain; } // ------ Get UBL Data and Write it to Flash ------ // Get the UBL header and data if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS) goto UART_tryAgain; // Erasing the Flash if ( NOR_erase(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt) != E_PASS ) goto UART_tryAgain; // Write the UBL data to the start of the NOR flash DEBUG_printString("Writing UBL to NOR flash\r\n"); if (NOR_writeBytes(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt, (Uint32)ackHeader.imageBuff) != E_PASS ) goto UART_tryAgain; // Return DONE when UBL flash operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Get block size and base of block where UBL was written NOR_getBlockInfo(hNorInfo,hNorInfo->flashBase+ackHeader.byteCnt,&blockSize,&blockAddr); // Get the application header and data if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS) goto UART_tryAgain; // Setup the NORBOOT header that will be stored in flash norBoot.magicNum = ackHeader.magicNum; norBoot.entryPoint = ackHeader.startAddr; norBoot.appSize = ackHeader.byteCnt; norBoot.ldAddress = ackHeader.loadAddr; // Erasing the Flash if ( NOR_erase(hNorInfo,(blockAddr + blockSize), (ackHeader.byteCnt + sizeof(NORBOOT_HeaderObj))) != E_PASS ) goto UART_tryAgain; // Write the NORBOOT header to the flash DEBUG_printString("Writing APP to NOR flash\r\n"); if (NOR_writeBytes(hNorInfo,(blockAddr + blockSize), sizeof(NORBOOT_HeaderObj), (Uint32)&norBoot) != E_PASS ) goto UART_tryAgain; // Write the application data to the flash if ( NOR_writeBytes(hNorInfo,(blockAddr + blockSize + sizeof(NORBOOT_HeaderObj)), norBoot.appSize, (Uint32)ackHeader.imageBuff) != E_PASS ) goto UART_tryAgain; // Return DONE when UBL flash operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point to nowhere, since there isn't an appropriate binary image to run */ gEntryPoint = 0x0; break; } case UBL_MAGIC_NOR_ERASE: { // Initialize the NOR Flash hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth()) ; if (hNorInfo == NULL) { DEBUG_printString("NOR_open() failed!"); goto UART_tryAgain; } // Erasing the Flash if (NOR_globalErase(hNorInfo) != E_PASS) { DEBUG_printString("\r\nErase failed.\r\n"); } else { DEBUG_printString("\r\nErase completed successfully.\r\n"); } // Return DONE when erase operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point for code execution // Go to reset in this case since no code was downloaded gEntryPoint = 0x0; break; } #elif defined(UBL_NAND) case UBL_MAGIC_NAND_FLASH: { Uint32 i; // Initialize the NAND Flash hNandInfo = NAND_open((Uint32)&EMIFStart, (Uint8) DEVICE_emifBusWidth() ); if ( hNandInfo == NULL ) { DEBUG_printString("NAND_open() failed!"); goto UART_tryAgain; } // Allocate mem for write and read buffers (only once) hNandWriteBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage); hNandReadBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage); trvx(hNandWriteBuf); trvx(hNandReadBuf); // Clear buffers for (i=0; i < hNandInfo->dataBytesPerPage; i++) { hNandWriteBuf[i] = 0xFF; hNandReadBuf[i] = 0xFF; } // ------ Get UBL Data and Write it to Flash ------ // Get the UBL header and data if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS) goto UART_tryAgain; // Setup fixed elements of the NANDBOOT header that will be stored in flash for UBL nandBoot.magicNum = ackHeader.magicNum; nandBoot.entryPoint = ackHeader.startAddr; nandBoot.page = 1; // The page is always page 0 for the UBL header, so we use page 1 for data nandBoot.ldAddress = ackHeader.loadAddr; // This field doesn't matter for the UBL header nandBoot.forceContigImage = TRUE; nandBoot.startBlock = DEVICE_NAND_RBL_SEARCH_START_BLOCK; nandBoot.endBlock = DEVICE_NAND_RBL_SEARCH_END_BLOCK; // Calculate the number of NAND pages needed to store the UBL image nandBoot.numPage = 0; while ( (nandBoot.numPage * hNandInfo->dataBytesPerPage) < (ackHeader.byteCnt)) { nandBoot.numPage++; } // Write multiple copies of the UBL to the appropriate RBL search blocks DEBUG_printString("Writing UBL to NAND flash\r\n"); if (LOCAL_NANDWriteHeaderAndData(hNandInfo, &nandBoot, ackHeader.imageBuff) != E_PASS) { DEBUG_printString("Writing failed!"); goto UART_tryAgain; } // Return DONE when UBL flash operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // ------ Get Application Data and Write it to Flash ------ // Get the application header and data if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS) goto UART_tryAgain; // Setup fixed elements of the NANDBOOT header that will be stored in flash for APP nandBoot.magicNum = ackHeader.magicNum; // Rely on the host applciation to send over the right magic number (safe or bin) nandBoot.entryPoint = ackHeader.startAddr; // Use the entrypoint received in ACK header nandBoot.page = 1; // The page is always page 0 for the header, so we use page 1 for data nandBoot.ldAddress = ackHeader.loadAddr; // The load address is only important if this is a binary image nandBoot.forceContigImage = FALSE; nandBoot.startBlock = DEVICE_NAND_UBL_SEARCH_START_BLOCK; nandBoot.endBlock = DEVICE_NAND_UBL_SEARCH_END_BLOCK; // Calculate the number of NAND pages needed to store the APP image nandBoot.numPage = 0; while ( (nandBoot.numPage * hNandInfo->dataBytesPerPage) < ackHeader.byteCnt ) { nandBoot.numPage++; } // Write multiple copies of the APP to the appropriate UBL search blocks DEBUG_printString("Writing APP to NAND flash\r\n"); if (LOCAL_NANDWriteHeaderAndData(hNandInfo, &nandBoot, ackHeader.imageBuff) != E_PASS) { DEBUG_printString("Writing failed!"); goto UART_tryAgain; } // Return DONE when UBL flash operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point to nowhere, since there isn't an appropriate binary image to run */ gEntryPoint = 0x0; break; } case UBL_MAGIC_NAND_ERASE: { // Initialize the NAND Flash hNandInfo = NAND_open((Uint32)&EMIFStart, (Uint8) DEVICE_emifBusWidth() ); if ( hNandInfo == NULL ) { DEBUG_printString("NAND_open() failed!"); goto UART_tryAgain; } // Unprotect the NAND Flash NAND_unProtectBlocks(hNandInfo, DEVICE_NAND_RBL_SEARCH_START_BLOCK, DEVICE_NAND_UBL_SEARCH_END_BLOCK-1); // Erase all the pages of the device if (NAND_eraseBlocks(hNandInfo, DEVICE_NAND_RBL_SEARCH_START_BLOCK, DEVICE_NAND_UBL_SEARCH_END_BLOCK-1) != E_PASS) { DEBUG_printString("Erase failed.\r\n"); goto UART_tryAgain; } else { DEBUG_printString("Erase completed successfully.\r\n"); } // Protect the device NAND_protectBlocks(hNandInfo); // Return DONE when erase operation has been completed if ( LOCAL_sendSequence(" DONE") != E_PASS ) return E_FAIL; // Set the entry point for code execution // Go to reset in this case since no code was downloaded gEntryPoint = 0x0; break; } #elif defined(UBL_SDMMC) case UBL_MAGIC_SDMMC_FLASH: { break; } case UBL_MAGIC_SDMMC_ERASE: { break; } #endif default: { DEBUG_printString("Boot command not supported!"); return E_FAIL; } } LOCAL_sendSequence(" DONE"); return E_PASS; }