ethdown.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 914 行 · 第 1/3 页

C
914
字号
		FlashWriteCommand(pdwBSR, 0xFFFFFFFFUL);
		return 1;
	}
	if (!FlashBSR0(pdwBSR,0x00100010UL) || !FlashBSR0(pdwBSR,0x00200020UL)) {
		*ppszErrorMsg = "FLASH_CONT_ERASE Operation Aborted";
		FlashWriteCommand(pdwBSR, 0x50505050UL);
		// Reset flash to normal mode
		FlashWriteCommand(pdwBSR, 0xFFFFFFFFUL);
		return 1;
	}
	return 1;
} // FlashError()



// The Intel 28F016SV flash chip has twin 256 byte (128 16-bit words) page buffers that can be 
//  filled with data and then programmed into the flash array.  This is faster than issuing 
//  single address flash commands.  This routine will take the data passed in and queue it up 
//  in the page buffers of twin the flash chips.  Once those are full, or I've reached a 256 byte
//  address boundary, I'll give the command to burn the data into the flash array and start
//  filling the other page buffer.
UINT16 FlashWrite( DWORD dwPhysStart, DWORD dwPhysLen, char **ppszErrorMsg )
{
	DWORD *pdwFlashCache;
	volatile DWORD *pdwFlash;
	DWORD dwStartBlock, dwEndBlock, dwBlocksLeft, dwFirstBlockOffset, dwDWORDsLeft;
	DWORD i;

	BOOL bErasing=TRUE;
	DWORD dwStart;

	if(CheckFlashWriteProtect()) {
		*ppszErrorMsg = "Error : write protected.";
		return 1;
	}

	dwStartBlock = (dwPhysStart & 0x01FE0000UL) / FLASH_BLOCK_SIZE;
	dwEndBlock = ((dwPhysStart + dwPhysLen) & 0x01FE0000UL) / FLASH_BLOCK_SIZE;
//	dwStartBlock = (dwPhysStart & (~(FLASH_BLOCK_SIZE-1)) & 0x0FFFFFFFUL) / FLASH_BLOCK_SIZE;
//	dwEndBlock = ((dwPhysStart + dwPhysLen) & (~(FLASH_BLOCK_SIZE-1)) & 0x0FFFFFFFUL) / FLASH_BLOCK_SIZE;
	dwBlocksLeft = dwEndBlock - dwStartBlock + 1;

	// Calculate how far from the beginning of the first block the starting address falls
	dwFirstBlockOffset = (dwPhysStart & 0x0FFFFFFFUL) - 
		((FLASH_START & 0x0FFFFFFFUL) + dwStartBlock * FLASH_BLOCK_SIZE);

	EdbgOutputDebugString( "FlashWrite: dwStartBlock %d dwEndBlock %d dwBlocksLeft %d dwFirstBlockOffset %Xh\r\n",
		dwStartBlock, dwEndBlock, dwBlocksLeft, dwFirstBlockOffset);

	// protect BLOCK 0 (ethernet bootloader block)
	for( i = dwStartBlock; i <= dwEndBlock; i++ ) {
		if(i == 0) {
			*ppszErrorMsg = "Error : Block 0 is the bootloader block. Check the image start address.";
			return 1;
		}
	}

	while (bErasing) {
		bErasing=FALSE;
		for( i = dwStartBlock; i <= dwEndBlock; i++ ) {
			if (EraseStatus[i] != BLOCK_ERASED) {
			//	EdbgOutputDebugString( "FlashWrite: Block%x is NOT BLOCK_ERASED\r\n", i );
				bErasing=TRUE;
				if (FlashErase( FLASH_CONT_ERASE, 0, 0, ppszErrorMsg ))
					return 1;
			}
		}
	}

	dwStart= OEMEthGetSecs();
	while (OEMEthGetSecs()-dwStart < 3) ;

	while( dwBlocksLeft ) {

		for( i = dwStartBlock ; i <= dwEndBlock ; i++ ) {
			EdbgOutputDebugString( "FlashWrite: Block %d\r\n", i );
#if ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
			DisplayAlphaLED (MAKELONG(v_PacketNum, i));
#endif ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
			// Attempt to flash all erased blocks
			if (EraseStatus[i] == BLOCK_ERASED) {
				// Set up the FlashCache pointer and number of words to write
				// If this is the first block, we need to start further along
				if (i == dwStartBlock) {
					pdwFlash = (DWORD *)(dwPhysStart|0xa0000000UL);
					pdwFlashCache = (LPDWORD) FLASH_CACHE + (dwFirstBlockOffset / 4);
					dwDWORDsLeft = (FLASH_BLOCK_SIZE - dwFirstBlockOffset) / 4;
					// If the whole image is less than one block long
					if (dwDWORDsLeft > dwPhysLen / 4)
						dwDWORDsLeft = dwPhysLen / 4;
				}
				else {
					pdwFlash = (DWORD *)((FLASH_START | 0xA0000000UL) + i * FLASH_BLOCK_SIZE);
					pdwFlashCache = (LPDWORD) FLASH_CACHE + 
						( ((FLASH_BLOCK_SIZE - dwFirstBlockOffset) + (i-dwStartBlock-1) * FLASH_BLOCK_SIZE) / 4);
					// If this is the last block we need to cut short the number of DWORDs written
					if (i == dwEndBlock)
						dwDWORDsLeft = (dwPhysLen % FLASH_BLOCK_SIZE) / 4;
					else
						dwDWORDsLeft = FLASH_BLOCK_SIZE / 4;
				}

				if (FlashPageWrite( pdwFlash, pdwFlashCache, dwDWORDsLeft, ppszErrorMsg ))
					return 1;

				dwBlocksLeft--;
				EraseStatus[i] = BLOCK_FLASHED;
			} // If the block was successfully erased
		}
	} // while there are still blocks left to program

	// Close out all the pages.  Wait until they have finished programming and then compare them against
	//  the cache image for consistency.
	if (FlashClose( dwPhysStart, dwPhysLen, ppszErrorMsg )) {
		return 1;
	} else {
		return 0;
	}

}



UINT16 FlashPageWrite( volatile DWORD *pdwFlash, DWORD *pdwFlashCache, DWORD dwDWORDsLeft, char **ppszErrorMsg )
{
	volatile DWORD *pdwBSR, *pdwGSR, *pdw;
	DWORD	i, dwCount;

	if(CheckFlashWriteProtect()) {
		*ppszErrorMsg = "Error : write protected.";
		return 1;
	}

	pdwBSR = (DWORD *)( ( ((DWORD)pdwFlash) & (~(FLASH_BLOCK_SIZE-1)) ) + 8 );	// 64bit
	pdwGSR = pdwBSR + 2;	// 64bit
//	EdbgOutputDebugString( "FlashPageWrite: BSR=%Xh GSR=%Xh\r\n",pdwBSR,pdwGSR);
	EdbgOutputDebugString( "FlashPageWrite: From %Xh to %Xh Length %Xh\r\n",pdwFlashCache,pdwFlash,dwDWORDsLeft*4);

	// Loop until we've written the entire page
	while( dwDWORDsLeft ) {

		// Read Extended Status Registers
		FlashWriteCommand(pdwBSR, 0x71717171UL);
		// Wait until the block is no longer busy with other page writes
		while(!FlashBSR1(pdwBSR,0x00800080UL)) ;

		// Wait until a page buffer is available
		while(!FlashGSR1(pdwGSR,0x00040004UL))
			EdbgOutputDebugString( "GSR=%Xh\r\n",*pdwGSR);

//		EdbgOutputDebugString( "Load page BSR=%Xh %d words left.\r\n",pdwBSR,dwDWORDsLeft);
		// Start sequential load to page buffer
		FlashWriteCommand(pdwBSR, 0xE0E0E0E0UL);
		// Write Word Count Low.  Decrement once since a count of 0 corresponds to a single write.
		if (dwDWORDsLeft & 0xFFFFFF00UL)
			dwCount = 128 * 2;
		else
			dwCount = dwDWORDsLeft;
		FlashWriteCommand(pdwBSR, (((dwCount+1)/2-1) << 16) | ((dwCount+1)/2-1));
		// Write Word Count High.  This is a don't care for 28F016SV because page buffer is only 256 bytes long.
		FlashWriteCommand(pdwBSR, 0);

//		EdbgOutputDebugString( "pdwFlash=%Xh dwCount=%d : %Xh words left.\r\n",pdwFlash,dwCount,dwDWORDsLeft);

		pdw = pdwFlash;
		for( i = 0 ; i < (dwCount+1)/2 ; i++ ) {	// dwCount x 2 dword
//			FlashWriteCommand((pdwFlash + i), *pdwFlashCache++);
			*pdwFlash++ = *pdwFlashCache++;
			*pdwFlash++ = *pdwFlashCache++;
		}

		// Read Extended Status Registers
		FlashWriteCommand(pdwBSR, 0x71717171UL);

		// Wait until there is space in the command queue
		while(!FlashBSR0(pdwBSR,0x00080008UL)) ;

		FlashWriteCommand(pdwBSR, 0x0C0C0C0CUL);
		// Write Word Count Low.  Decrement once since a count of 0 corresponds to a single write.
		FlashWriteCommand(pdwBSR, (((dwCount+1)/2-1) << 16) | ((dwCount+1)/2-1));
		// Write Word Count High.  This is a don't care for 28F016SV because page buffer is only 256 bytes long.
		FlashWriteCommand(pdw, 0);

		// Read Extended Status Registers
		FlashWriteCommand(pdwBSR, 0x71717171UL);

		// Wait until operation complete
		while(!FlashBSR1(pdwBSR,0x00800080UL)) ;

		// Check for operation errors
		if (!FlashBSR0(pdwBSR, 0x00200020UL)) {
			EdbgOutputDebugString( "FlashPageWrite() Error On Page Buffer Write GSR %X, BSR %X\r\n", *pdwGSR, *pdwBSR );
			FlashError( pdwBSR, ppszErrorMsg );
			return 1;
		}

		dwDWORDsLeft -= dwCount;
	} // while there are still DWORDs to write to the page

	return 0;

} // FlashPageWrite()



UINT16 FlashClose( DWORD dwPhysStart, DWORD dwPhysLen, char **ppszErrorMsg )
{
	volatile DWORD *pdwBSR;
	DWORD	dwStartBlock, dwEndBlock, dwCurBlock;
	DWORD	*pdwFlash, *pdwFlashCache;
	DWORD	i,j,k;
	DWORD dwStart;

	// Compute starting and ending block numbers
	dwStartBlock = (dwPhysStart & 0x01FE0000UL) / FLASH_BLOCK_SIZE;
	dwEndBlock = ((dwPhysStart + dwPhysLen) & 0x01FE0000UL) / FLASH_BLOCK_SIZE;

	EdbgOutputDebugString( "Closing Out Flash Image at %X of length %X (Blocks %u to %u)\r\n",
		dwPhysStart, dwPhysLen, dwStartBlock, dwEndBlock );

	dwStart= OEMEthGetSecs();
	while (OEMEthGetSecs()-dwStart < 3) ;

	// Make sure that all the blocks have finished before letting them go on, otherwise you
	//  might get bad values out of it.
	pdwBSR = (DWORD *)((FLASH_START | 0xA0000000UL) + dwStartBlock * FLASH_BLOCK_SIZE + 8);	// 64bit
	for( dwCurBlock = dwStartBlock; dwCurBlock <= dwEndBlock; dwCurBlock++ ) {
		pdwBSR = (DWORD *)((FLASH_START | 0xA0000000UL) + dwCurBlock * FLASH_BLOCK_SIZE + 8);	// 64bit
		FlashWriteCommand(pdwBSR, 0x71717171UL);

		// Wait for the page to indicate ready, meaning that everything has been written
		while(!FlashBSR1(pdwBSR, 0x00800080UL));

		// If we're crossing a bank boundary, reset the last bank's flash to read array mode
		if (dwCurBlock % FLASH_BLOCKS_PER_BANK == FLASH_BLOCKS_PER_BANK - 1)
			FlashWriteCommand(pdwBSR, 0xFFFFFFFFUL);
	}

	// Reset flash to read array mode
	FlashWriteCommand(pdwBSR, 0xFFFFFFFFUL);

	// Disable SH3 writing to the flash
//	*pwCpuCsr &= 0xFEFD;

	// Do a compare against the FlashCache[] and see if it all looks right
	EdbgOutputDebugString( "Comparing Flash vs FlashCache...\r\n dwPhysStart=%Xh FLASH_CACHE=%Xh length=%Xh\r\n",dwPhysStart,FLASH_CACHE,dwPhysLen);
	pdwFlash = (DWORD *)dwPhysStart;
	pdwFlashCache = (LPDWORD)FLASH_CACHE;
	for( i = 0 ; i < dwPhysLen/4 ; i++ ) {
		j = *pdwFlash;
		k = *pdwFlashCache;
		if (j != k) {
			EdbgOutputDebugString( "Beat!\r\n" );
			EdbgOutputDebugString( "Flash               - FlashCache\r\n" );
			for( j=0 ; j<16 ; j++ ) {
				EdbgOutputDebugString( "%X : %X - %X : %X\r\n", pdwFlash, *pdwFlash, pdwFlashCache, *pdwFlashCache );
				pdwFlash++;
				pdwFlashCache++;
			}
			*ppszErrorMsg = "Error Comparing Flash vs FlashCache";
			return 1;
		}
		pdwFlash++;
		pdwFlashCache++;
	}
	EdbgOutputDebugString( "Jammin'!\r\n" );
	return 0;
}



void UploadDeviceInfo( DWORD dwBank )
{
	volatile DWORD *pdwGSR;

	pdwGSR = (DWORD *)((FLASH_START | 0xA0000000UL) + dwBank * 32UL * FLASH_BLOCK_SIZE + 16);
	FlashWriteCommand(pdwGSR, 0x71717171UL);
	// Wait for command queues to be less than full
	while(!FlashGSR0(pdwGSR,0x00080008UL))
		EdbgOutputDebugString( "UploadDeviceInfo::Waiting for Command Q %X\r\n", *pdwGSR );

	while(!FlashGSR1(pdwGSR,0x00800080UL))
		EdbgOutputDebugString( "UploadDeviceInfo::Waiting for Ready 1 %X\r\n", *pdwGSR );
	FlashWriteCommand(pdwGSR, 0x99999999UL);
	FlashWriteCommand(pdwGSR, 0xD0D0D0D0UL);

	// Optionally read out the device info.
/*
	FlashWriteCommand(pdwGSR, 0x71717171UL);
	while(!FlashGSR1(pdwGSR,0x00800080UL))
		EdbgOutputDebugString( "UploadDeviceInfo::Waiting for Ready 2 %X\r\n", *pdwGSR );
	if (!FlashGSR0(pdwGSR, 0x20202020UL))
		EdbgOutputDebugString( "Page Buffer Read Failed %X%X\r\n", *(pdwGSR), *(pdwGSR+1) );
	else {
		FlashWriteCommand(pdwGSR, 0x72727272UL);
		FlashWriteCommand(pdwGSR, 0x75757575UL);
		EdbgOutputDebugString( "Device Revision Code %X%X\r\n", *(pdwGSR+2), *(pdwGSR+3));
		FlashWriteCommand(pdwGSR, 0x75757575UL);
		EdbgOutputDebugString( "Device Proliferation Code %X%X\r\n", *(pdwGSR+26), *(pdwGSR+27) );
	}
*/
}
#endif ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?