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

📄 cfiamd.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* Setup the commands first */    for (i = 0; i < thisCFI->multiplier; i++)	{	unlock1 	|= AMD_UNLOCK_1 << (i * 8);	unlock2 	|= AMD_UNLOCK_2 << (i * 8);	erase_setup	|= AMD_SETUP_ERASE << (i * 8);	erase_sector 	|= AMD_SECTOR_ERASE << (i * 8);	}    for (iBlock = firstErasableBlock; 	(iBlock - firstErasableBlock) < thisCFI->bootBlockSectors; 	iBlock++) 	{	int i;	FLBoolean finished;	FlashPTR flashPtr;		/* No need to call mapBase because we know we are on 	 * a unit boundary 	 */	flashPtr = (FlashPTR)		  vol.map(&vol, thisCFI->secInfo[iBlock].sectorBaseAdrs, 0);    	*(UINT32 *)(flashPtr + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;    	*(UINT32 *)(flashPtr + 		(thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;    	*(UINT32 *)(flashPtr + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = erase_setup;    	*(UINT32 *)(flashPtr + 		(thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;    	*(UINT32 *)(flashPtr + 		(thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;    	*(UINT32 *)flashPtr = erase_sector;	do 	    {	    finished = TRUE;	    for (i = 0;i < thisCFI->multiplier;i += thisCFI->interleaveWidth) 		{		if (flashPtr[i] != 0xff) 		    {		    if ((flashPtr[i] & AMD_D5) && flashPtr[i] != 0xff) 			{			flashPtr[i] = AMD_READ_ARRAY;#ifdef DEBUG_PRINT	    		DEBUG_PRINT("Debug: erase failed in AMD MTD.\n");#endif			return flWriteFault;			}		    finished = FALSE;		    }		}	    } while (!finished);	}    return flOK;    }/******************************************************************************* * cfiAmdErase - Erase one or more contiguous Flash erasable blocks	 *						 * This routine will be registered as the MTD vol.erase routine. Sector zero is  * assumed to be the boot block anchor of the boot block on bottom boot devices, * while the first sector of size not equal to vol.erasableBlockSize is assumed  * to be the anchor for top boot devices. *							 * Parameters:                                          *	vol		: Pointer identifying drive *      firstErasableBlock : Number of first block to erase		 *	numOfErasableBlocks: Number of blocks to erase		 *                                                              * Returns:                                                    *	FLStatus	: 0 on success, failed otherwise */LOCAL  FLStatus cfiAmdErase    (    FLFlash vol,    int firstErasableBlock,    int numOfErasableBlocks    )    {    int i;    UINT32 unlock1 = 0;    UINT32 unlock2 = 0;    UINT32 erase_setup = 0;    UINT32 erase_sector = 0;    int thisSector = firstErasableBlock;    int sectorsToErase = numOfErasableBlocks;    UINT32 * unlockAddr1;    UINT32 * unlockAddr2;    if (flWriteProtected(vol.socket))	return flWriteProtect;    if ((thisCFI->bootBlockType == BOOTBLOCK_BOTTOM) && 			    	(firstErasableBlock == 0))	{#ifdef DEBUG_PRINT	DEBUG_PRINT("Debug: Erasing bottom boot block\n");#endif	    cfiAmdBootBlockErase(&vol, 0);	    thisSector += thisCFI->bootBlockSectors;	}	/* Setup the commands first */    for (i = 0; i < thisCFI->multiplier; i++)	{	unlock1 	 |= AMD_UNLOCK_1 << (i * 8);	unlock2 	 |= AMD_UNLOCK_2 << (i * 8);	erase_setup	 |= AMD_SETUP_ERASE << (i * 8);	erase_sector |= AMD_SECTOR_ERASE << (i * 8);	}	        for ( ; thisSector < firstErasableBlock + sectorsToErase; thisSector++) 	{	int i;	FLBoolean finished;	FlashPTR flashPtr;	/* Check if we have hit a boot block region on a top 	 * boot device. If so lets clean it up and move on with 	 * the others	 */	if ((thisCFI->bootBlockType == BOOTBLOCK_TOP) &&	(thisCFI->secInfo[thisSector].sectorSize != vol.erasableBlockSize))	    {#ifdef DEBUG_PRINT	DEBUG_PRINT("Debug: Erasing top boot block\n");#endif	    cfiAmdBootBlockErase(&vol, thisSector);	    break;	    }#ifdef DEBUG_PRINT 	DEBUG_PRINT("Clearing sector %d\n", thisSector);#endif 	/* we know we are on a unit boundary so mapBase is not necessary */	flashPtr = (FlashPTR)		  vol.map(&vol, thisCFI->secInfo[thisSector].sectorBaseAdrs, 0);	unlockAddr1 = (UINT32 *)((long)flashPtr + (thisCFI->unlockAddr1 *thisCFI->multiplier));	unlockAddr2 = (UINT32 *)((long)flashPtr + (thisCFI->unlockAddr2 *thisCFI->multiplier));   	*unlockAddr1 = unlock1;    	*unlockAddr2 = unlock2;	*unlockAddr1 = erase_setup;    	*unlockAddr1 = unlock1;    	*unlockAddr2 = unlock2;    	*(UINT32 *)flashPtr = erase_sector;		do 	    {	    finished = TRUE;	    for (i = 0;i < thisCFI->multiplier;i += thisCFI->interleaveWidth) 		{		if (flashPtr[i] != 0xff) 		    {		    if ((flashPtr[i] & AMD_D5) && flashPtr[i] != 0xff) 			{			int x;			UINT32 c;						for (x = 0, c = 0; x < thisCFI->multiplier; x++)	    		    c |= AMD_READ_ARRAY << (x * 8);			flashPtr[i] = c;#ifdef DEBUG_PRINT	    DEBUG_PRINT("Debug: erase failed in AMD MTD.\n");#endif			return flWriteFault;			}		    finished = FALSE;		    }		}	    } while (!finished);	}    return flOK;    }/*************************************************************************** * cfiscsIdentify - Identification routine for devices conforming to CFI/SC * * Identifies media based on CFI and the AMD/Fujitsu command set and registers * as an MTD for such. This routine should be placed on the MTD list in flcustom.h. * It must be an extern routine. On successful identification, the Flash  * structure is filled out and the write and erase routines registered.  * * Parameters: *      vol             : Pointer identifying drive  * * Returns: *      FLStatus        : 0 on positive identificaion, failed otherwise  * * http://www.amd.com/us-en/FlashMemory/ProductInformation/0,,37_1447_1451_1780%5E1834%5E1955,00.html * * * NOMANUAL * */FLStatus cfiAmdIdentify    (    FLFlash vol    )    {    FlashPTR flashPtr = (FlashPTR) flMap(vol.socket, 0);    FlashWPTR flashWPtr = (FlashWPTR) flashPtr;    FlashDPTR flashDPtr = (FlashDPTR) flashPtr;    UINT32 unlock1 = 0;    UINT32 unlock2 = 0;    UINT32 readID = 0;    UINT32 readArray = 0;    int i;   unsigned primaryTable, secondaryTable;    FLBoolean eightBitMode = FALSE;    int thisSector = 0;		/* running count of sectors for this CFI */    CardAddress sectorBaseAdrs = 0;	/* base address of this sector */    int ix = 0;#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: entering CFIAMD identification routine.\n");#endif    flSetWindowBusWidth(vol.socket, 16);/* use 16-bits */    flSetWindowSpeed(vol.socket, 120);  /* 120 nsec. */    flSetWindowSize(vol.socket, 2);       /* 8 KBytes */    vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)];    thisCFI->bootBlockSectors = 0;    /* Is this an 8 bit device */    flashPtr[0x55] = AMD_READ_ARRAY;    flashPtr[0x55] = QUERY;        if (flashPtr[0x10] == 0x51 && /* 'Q' */        flashPtr[0x11] == 0x52 && /* 'R' */        flashPtr[0x12] == 0x59)   /* 'Y' */        {#ifdef DEBUG_PRINT        DEBUG_PRINT ("Debug: detected single 8 bit device\n");#endif        thisCFI->multiplier = 1;	thisCFI->interleaveWidth = 1;        vol.interleaving = 1;	eightBitMode = TRUE;        goto getCFI;        }    /* Reset to READ_ARRAY and retry. Maybe 16 bit addressing      */    flashPtr[0x55] = AMD_READ_ARRAY;    flashWPtr[0x55] = (USHORT) ((QUERY << 8) | QUERY);     /* Check for two interleaved 8 bit parts */    if (flashPtr[0x20] == 0x51 && /* 'Q' */        flashPtr[0x21] == 0x51 && /* 'Q' */        flashPtr[0x22] == 0x52 && /* 'R' */        flashPtr[0x23] == 0x52 && /* 'R' */        flashPtr[0x24] == 0x59 && /* 'Y' */        flashPtr[0x25] == 0x59)   /* 'Y' */    	{	/* Let's try turning one off */	CFI_WORD_WRITE((FlashWPTR)(&flashPtr[0x55]), AMD_READ_ARRAY);	if (flashPtr[0x20] != 0x51) /* Turned off successfully */	    {	    thisCFI->multiplier = 2;	    thisCFI->interleaveWidth = 1;	    vol.interleaving =2;#ifdef DEBUG_PRINT	    DEBUG_PRINT ("Debug: detected two 8 bit devices\n");#endif	    eightBitMode = TRUE;	    goto getCFI;	    }	}    /* a 16 bit device in 16 bit mode */    if (flashWPtr[0x10] == 'Q' &&         flashWPtr[0x11] == 'R' &&        flashWPtr[0x12] == 'Y')        {       	thisCFI->multiplier = 2;	thisCFI->interleaveWidth = 1;	vol.interleaving = 1;#ifdef DEBUG_PRINT        DEBUG_PRINT ("Debug: detected one 16 bit device\n");#endif	goto getCFI;	}    /* If we have a 16 bit device in 8 bit mode it should ID correctly */    if (flashPtr[0x20] == 0x51 && /* 'Q' */        flashPtr[0x21] == 0x51 && /* 'Q' */        flashPtr[0x22] == 0x52 && /* 'R' */        flashPtr[0x23] == 0x52 && /* 'R' */        flashPtr[0x24] == 0x59 && /* 'Y' */        flashPtr[0x25] == 0x59)   /* 'Y' */        {	thisCFI->multiplier = 2;#ifdef DEBUG_PRINT        DEBUG_PRINT ("Debug: detected a 16 bit device in 8 bit mode\n");#endif    	vol.interleaving =1;	thisCFI->interleaveWidth = 1;	eightBitMode = TRUE;	goto getCFI;    	}    /* Reset to READ_ARRAY and retry. Maybe 32 bit addressing      */    flashWPtr[0x55] = (USHORT) ((AMD_READ_ARRAY << 8) | AMD_READ_ARRAY);     flashDPtr[0x55] = (ULONG) (QUERY << 24| QUERY <<16 | QUERY << 8 | QUERY);     /* A 32 bit device in 8 bit mode and two 16 bit deivec in 8 bit mode will     * appear the same to the querry process. The only way to make the     * distinction is to try and set one device back to read array mode while     * the other remains in query mode */    if (flashPtr[0x40] == 0x51 && /* 'Q' */        flashPtr[0x41] == 0x51 && /* 'Q' */        flashPtr[0x42] == 0x51 && /* 'Q' */        flashPtr[0x43] == 0x51 && /* 'Q' */        flashPtr[0x44] == 0x52 && /* 'R' */        flashPtr[0x45] == 0x52 && /* 'R' */        flashPtr[0x46] == 0x52 && /* 'R' */        flashPtr[0x47] == 0x52 && /* 'R' */        flashPtr[0x48] == 0x59 && /* 'Y' */        flashPtr[0x49] == 0x59 && /* 'Y' */        flashPtr[0x4a] == 0x59 && /* 'Y' */        flashPtr[0x4b] == 0x59)   /* 'Y' */        {	/* See if we can turn one off */	flashPtr[0x154] = AMD_READ_ARRAY;	if ((flashPtr[0x40] != 0x51) && (flashPtr[0x41] == 0x51))	    {	/* Turned one device off successfully */	    flashPtr[0x154] = QUERY; 	/* turn it back on to querry mode */	    vol.interleaving = 2;#ifdef DEBUG_PRINT	    DEBUG_PRINT ("Debug: detected two 16 bit device, 8 bit interleaved(2)\n");#endif	    }	else	    {	    vol.interleaving =1;#ifdef DEBUG_PRINT	    DEBUG_PRINT ("Debug: detected a 32 bit device in 8 bit mode\n");#endif	    }       	thisCFI->multiplier = 4;	thisCFI->interleaveWidth = 1;	eightBitMode = TRUE;	goto getCFI;	}    /* Is it a single 32 bit device */    if (flashDPtr[0x10] == 'Q' &&        flashDPtr[0x11] == 'R' &&        flashDPtr[0x12] == 'Y')        {#ifdef DEBUG_PRINT        DEBUG_PRINT ("Debug: detected a 32 bit device in 32 bit mode\n");#endif	thisCFI->multiplier = 4;	thisCFI->interleaveWidth = 1;	vol.interleaving = 1;	goto getCFI;	}    /* Two 16 bit devices in 16 bit mode */

⌨️ 快捷键说明

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