Example #1
0
File: dio.c Project: CSRedRat/ldt
int input(int dev, void *buf, int size)
{
	ret = 0;
#ifdef VERBOSE
_entry:
	trl_();
	trvd(size);
#endif
	if (dev < 0 || wo)
		return 0;
	switch (io_type) {
	case mmap_io:
		memcpy(buf, mem, size);
		ret = size;
		break;
	case ioctl_io:
		ioctl(dev, _IOC(_IOC_READ, ioctl_type, ioctl_num, size & _IOC_SIZEMASK), buf);
		ret = size;
		break;
	case file_io:
	default:
		ret = read(dev, buf, size);
	}
	return ret;
}
Example #2
0
File: dio.c Project: CSRedRat/ldt
int output(int dev, void *buf, int size)
{
#ifdef VERBOSE
_entry:
	trl_();
	trvd(size);
#endif
	ret = 0;
	if (dev < 0 || ro)
		return 0;
	switch (io_type) {
	case mmap_io:
		memcpy(mem, buf, size);
		ret = size;
		break;
	case ioctl_io:
		ioctl(dev, _IOC(_IOC_WRITE, ioctl_type, ioctl_num, size & _IOC_SIZEMASK), buf);
		break;
	case file_io:
	default:
		ret = write(dev, buf, size);
	}
	return ret;
}
Example #3
0
File: dio.c Project: CSRedRat/ldt
int io_start(int dev)
{
	struct pollfd pfd[2];
	ssize_t data_in_len, data_out_len, len_total = 0;
	int i = 0;

	/* TODO: wo, ro */
	pfd[0].fd = fileno(stdin);
	pfd[0].events = POLLIN;
	pfd[1].fd = dev;
	pfd[1].events = POLLIN;
	while (poll(pfd, sizeof(pfd) / sizeof(pfd[0]), -1) > 0) {
#ifdef VERBOSE
		trvd_(i);
		trvx_(pfd[0].revents);
		trvx_(pfd[1].revents);
		trln();
#endif
		data_in_len = 0;
		if (pfd[0].revents & POLLIN) {
			pfd[0].revents = 0;
			ret = data_in_len = read(fileno(stdin), inbuf, buf_size);
			if (data_in_len < 0) {
				usleep(100000);
				break;
			}
			if (!data_in_len && !ignore_eof) {
				/* read returns 0 on End Of File */
				break;
			}
#ifdef VERBOSE
			trvd_(data_in_len);
			trln();
#endif
again:
			chkne(ret = output(dev, inbuf, data_in_len));
			if (ret < 0 && errno == EAGAIN) {
				usleep(100000);
				goto again;
			}
			if (data_in_len > 0)
				len_total += data_in_len;
		}
		data_out_len = 0;
		if (pfd[1].revents & POLLIN) {
			pfd[1].revents = 0;
			chkne(ret = data_out_len = input(dev, outbuf, buf_size));
			if (data_out_len < 0) {
				usleep(100000);
				break;
			}
			if (!data_out_len) {
				/* EOF, don't expect data from the file any more
				   but wee can continue to write */
				pfd[1].events = 0;
			}
			if (!data_out_len && !ignore_eof) {
				/* read returns 0 on End Of File */
				break;
			}
			write(fileno(stdout), outbuf, data_out_len);
			if (data_out_len > 0)
				len_total += data_out_len;
		}
#ifdef VERBOSE
		trl_();
		trvd_(i);
		trvd_(len_total);
		trvd_(data_in_len);
		trvd_(data_out_len);
		trln();
#endif
		if ((!ignore_eof && pfd[0].revents & POLLHUP) || pfd[1].revents & POLLHUP)
			break;
		i++;
		if (loops && i >= loops)
			break;
		usleep(1000 * delay);
	}
#ifdef VERBOSE
	trl_();
	trvd_(i);
	trvd_(len_total);
	trvd_(data_in_len);
	trvd_(data_out_len);
	trln();
#endif
	return ret;
}
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;
}