⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfiamd.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    for (ix = 0; ix < thisCFI->multiplier; ix++)	cmdBuffer |= AMD_READ_ARRAY << (8 * ix);    flashPtr[0x55 * thisCFI->multiplier] = cmdBuffer;    return flOK;    }#if 0/****************************************************************************** * cfiAmdLeftoverBytesWrite - Write trailing bytes from aligned write *  * This is a helper routine to cfiAmdWrite(), which writes in chunks, 1, 2, and * 4 bytes wide. The trailing bytes are written from here bye reading 4 bytes  * from flash and OR-ing in the data to be written. Note that when programming  * flash, a 1 can be tuned to 0 but a 0 cannot be turned to 1. */LOCAL void cfiAmdLeftoverBytesWrite    (    FLFlash vol,    const void FAR1 *buffer,    FlashPTR flashPtr,    int length    )    {    /* data is a 1's mask, so we only try overwriting the     * bytes we desire ie. written a 1 should not change     * the state of an erase bit      */    int byteCount;    ULONG data = 0xffffffff;    /* clear out the bytes we are going to overwrite */    for(byteCount = 0; byteCount<length; byteCount++)        data &= ~(0xff << (byteCount*8));    /* set the bits we dont want to clear in our data */    data |= CFI_LONGSWAP(* (ULONG *) buffer);    }#endif/****************************************************************************** * cfiAmdWrite - Write a block of bytes to Flash * * This routine will be registered as the MTD vol.write routine. Given a pointer  * to a buffer that must be written, the write width determined from the  * identification process is used the stepping stone to interate through the buffer. *							 * Parameters:                                          *	vol		: Pointer identifying drive *      address		: Card address to write to *      buffer		: Address of data to write			 *	length		: Number of bytes to write		 *	overwrite	: TRUE if overwriting old Flash contents *			  FALSE if old contents are known to be erased	 *                                                                      * Returns:                                                            *	FLStatus	: 0 on success, failed otherwise	 */LOCAL FLStatus cfiAmdWrite    (    FLFlash vol,    CardAddress address,    const void FAR1 *buffer,    int length,    FLBoolean overwrite    )    {    /* Set timeout to 5 seconds from now */    unsigned long writeTimeout = flMsecCounter + 5000;    int cLength;    CardAddress cAddr = address;    FlashPTR base;    FlashPTR flashPtr;    UINT32 unlock1 = 0;    UINT32 unlock2 = 0;    UINT32 setup_write = 0;    UINT32 read_array = 0;    int i;    CFI_DWORD tmpDWord;    CFI_WORD  tmpWord;#define bFlashPtr  flashPtr#define bBuffer ((const unsigned char FAR1 *) buffer)#define wFlashPtr ((FlashWPTR) flashPtr)#define wBuffer ((const unsigned short FAR1 *) buffer)#define dFlashPtr ((FlashDPTR) flashPtr)#define dBuffer ((const unsigned long FAR1 *) buffer)    /* Setup the commands first */    for (i = 0; i < thisCFI->multiplier; i++)	{	unlock1 	|= AMD_UNLOCK_1 << (i * 8);	unlock2 	|= AMD_UNLOCK_2 << (i * 8);	setup_write	|= AMD_SETUP_WRITE << (i * 8);	read_array	|= AMD_READ_ARRAY << (i * 8);	}    if (flWriteProtected(vol.socket))	return flWriteProtect;    i = 0;     while ((thisCFI->secInfo[i].sectorBaseAdrs <= address) && (i < thisCFI->sectorsInCFI))	i++;    i--;    base = (FlashPTR)		  vol.map(&vol, thisCFI->secInfo[i].sectorBaseAdrs,		    vol.interleaving * thisCFI->interleaveWidth);    flashPtr = (FlashPTR)		  vol.map(&vol, address,		    vol.interleaving * thisCFI->interleaveWidth);    cLength = length;    if (vol.interleaving * thisCFI->interleaveWidth == 1) 	{        while (cLength >= 1)   	    {	    *(UCHAR *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;    	    *(UCHAR *)(base + 		(thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;    	    *(UCHAR *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;	    *bFlashPtr = *bBuffer;	    while (bFlashPtr[0] != bBuffer[0] && flMsecCounter < writeTimeout) 	        {	        if ((bFlashPtr[0] & AMD_D5) && bFlashPtr[0] != bBuffer[0]) 		    {		    bFlashPtr[0] = read_array;#ifdef DEBUG_PRINT		    DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif		    return flWriteFault;		    }	        }	    cLength--;	    cAddr++;	    buffer++;	    bFlashPtr++;	    }        }    else if (vol.interleaving * thisCFI->interleaveWidth == 2)  	{	while (cLength >= 2) 	    {	    *(USHORT *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;    	    *(USHORT *)(base + 		(thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;    	    *(USHORT *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;	    *wFlashPtr = *wBuffer;	    while ((wFlashPtr[0] != wBuffer[0]) && 				    (flMsecCounter < writeTimeout))		{		if (((wFlashPtr[0] & AMD_D5) && 		    ((wFlashPtr[0] ^ wBuffer[0]) &   0xff)) ||		    ((wFlashPtr[0] & (AMD_D5 * 0x100)) 		     && ((wFlashPtr[0] ^ wBuffer[0]) & 0xff00))) 		    {		    wFlashPtr[0] = read_array;#ifdef DEBUG_PRINT	            DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif		    return flWriteFault;		    }		}	    cLength -= 2;	    cAddr += 2;	    buffer += 2;	    flashPtr += 2;	    }	if (cLength > 0)            {	    /* copy data from flash to tmpWord */	    tmpWord.ushort = wFlashPtr[0];	    /* now fill in the left over byte */	    tmpWord.uchar[0] = *(char *)buffer;	    *(USHORT *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;    	    *(USHORT *)(base + 		(thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;    	    *(USHORT *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;	    *wFlashPtr = tmpWord.ushort; 	    while ((wFlashPtr[0] != tmpWord.ushort) && 				    (flMsecCounter < writeTimeout))		{		if (((wFlashPtr[0] & AMD_D5) && 		    ((wFlashPtr[0] ^ tmpWord.ushort) &   0xff)) ||		    ((wFlashPtr[0] & (AMD_D5 * 0x100)) 		     && ((wFlashPtr[0] ^ tmpWord.ushort) & 0xff00))) 		    {		    wFlashPtr[0] = read_array;#ifdef DEBUG_PRINT	            DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif		    return flWriteFault;		    }		}	    cAddr += cLength;	    buffer += cLength;	    flashPtr += cLength;	    cLength = 0;	    }	    /* cfiAmdLeftoverBytesWrite(&vol, buffer, flashPtr, cLength); */	}    else /* if (vol.interleaving >= 4) */ 	{	while (cLength >= 4) 	    {	    *(UINT32 *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;    	    *(UINT32 *)(base + 		(thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;    	    *(UINT32 *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;	    *dFlashPtr = *dBuffer;	    while ((dFlashPtr[0] != dBuffer[0]) && 			    (flMsecCounter < writeTimeout)) 		{		if (thisCFI-> interleaveWidth == 1)		    {		    /* We have 4 8 bit devices */		    if (((dFlashPtr[0] & AMD_D5) && 			((dFlashPtr[0] ^ dBuffer[0]) & 0xff)) ||			((dFlashPtr[0] & (AMD_D5 * 0x100)) && 			((dFlashPtr[0] ^ dBuffer[0]) & 0xff00)) ||			((dFlashPtr[0] & (AMD_D5 * 0x10000lu)) && 			((dFlashPtr[0] ^ dBuffer[0]) & 0xff0000lu)) ||			((dFlashPtr[0] & (AMD_D5 * 0x1000000lu)) && 			((dFlashPtr[0] ^ dBuffer[0]) & 0xff000000lu))) 		        {#ifdef DEBUG_PRINT	  DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif		        dFlashPtr[0] = read_array;		        return flWriteFault;		        }		    }		else		    {		    /* Here we assume that the only other option is 2 16 bit devices */		    if (((dFlashPtr[0] & AMD_D5) && 			((dFlashPtr[0] ^ dBuffer[0]) & 0x0000ffff)) ||		        ((dFlashPtr[0] & (AMD_D5 * 0x10000lu)) && 			((dFlashPtr[0] ^ dBuffer[0]) & 0xffff0000)))			{#ifdef DEBUG_PRINT	  DEBUG_PRINT("Debug4-1: write failed in AMD MTD.\n");#endif		        dFlashPtr[0] = read_array;		        return flWriteFault;		        }		    }		    				}	    cLength -= 4;	    cAddr += 4;	    buffer += 4;	    flashPtr += 4;	    }	if (cLength > 0)            {	    tmpDWord.uint32 = 0xffffffff;	    /* read trailing bytes in to temp dword */	    for (i = 0; i < cLength; i++)		tmpDWord.uchar[i] = *((char *)buffer + i);	    /* fill the rest from flash */	    for (    ; i < 4; i++)		tmpDWord.uchar[i] = *(flashPtr + i);	    *(UINT32 *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;    	    *(UINT32 *)(base + 		(thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;    	    *(UINT32 *)(base + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;	    *dFlashPtr = tmpDWord.uint32;	    while ((dFlashPtr[0] != tmpDWord.uint32) && 			    (flMsecCounter < writeTimeout)) 		{		if (thisCFI-> interleaveWidth == 1)		    {		    /* We have 4 8 bit devices */		    if (((dFlashPtr[0] & AMD_D5) && 			((dFlashPtr[0] ^ tmpDWord.uint32) & 0xff)) ||			((dFlashPtr[0] & (AMD_D5 * 0x100)) && 			((dFlashPtr[0] ^ tmpDWord.uint32) & 0xff00)) ||			((dFlashPtr[0] & (AMD_D5 * 0x10000lu)) && 			((dFlashPtr[0] ^ tmpDWord.uint32) & 0xff0000lu)) ||			((dFlashPtr[0] & (AMD_D5 * 0x1000000lu)) && 			((dFlashPtr[0] ^ tmpDWord.uint32) & 0xff000000lu))) 		        {#ifdef DEBUG_PRINT	  DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif		        dFlashPtr[0] = read_array;		        return flWriteFault;		        }		    }		else		    {		    /* Here we assume that the only other option is 16 devices */		    if (((dFlashPtr[0] & AMD_D5) && 			((dFlashPtr[0] ^ tmpDWord.uint32) & 0x0000ffff)) ||		        ((dFlashPtr[0] & (AMD_D5 * 0x10000lu)) && 			((dFlashPtr[0] ^ tmpDWord.uint32) & 0xffff0000)))			{#ifdef DEBUG_PRINT	  DEBUG_PRINT("Debug4-2: write failed in AMD MTD.\n");#endif		        dFlashPtr[0] = read_array;		        return flWriteFault;		        }		    }		    		}	    cAddr += cLength;	    buffer += cLength;	    flashPtr += cLength;	    cLength = 0;	    }	    /* cfiAmdLeftoverBytesWrite(&vol, buffer, flashPtr, cLength); */	}    flashPtr -= length;    buffer = (unsigned char *)buffer - length; /* bBuffer -= length; */    if (tffscmp((void FAR0 *) flashPtr,buffer,length)) 	{#ifdef DEBUG_PRINT	DEBUG_PRINT("Debug: write failed in AMD MTD on verification.\n");#endif	return flWriteFault;	}    return flOK;    }/******************************************************************************* * cfiAmdBootBlockErase - Erase sub blocks within boot block * * Use the boot block data discovered at CFI interrogation time and erase all  * subsectors in the boot block. *							 * Parameters:                                          *	vol		: Pointer identifying drive *      firstErasableBlock : Sector number of start of boot block		 *                                                              * Returns:                                                    *	FLStatus	: 0 on success, failed otherwise */LOCAL FLStatus cfiAmdBootBlockErase    (    FLFlash vol,    int firstErasableBlock    )    {    int iBlock, i;    UINT32 unlock1 = 0;    UINT32 unlock2 = 0;    UINT32 erase_setup = 0;    UINT32 erase_sector = 0;

⌨️ 快捷键说明

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