int main(void) { _entry:; int i; for (i=0; i < 10; i++) sub(); trl(); trvp(i); trvx(i); trvd(i); trvd(sizeof(long long)); trvd(sizeof(size_t)); trvd(sizeof(void*)); trvd(sizeof(int)); trvd(sizeof(short)); trvd(sizeof(char)); return 0; }
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; }
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; }