📄 cfiscs.c
字号:
/* cfiscs.c - MTD for devices that comply with CFI and the Intel SCS *//* Copyright 1984-2005 Wind River Systems, Inc. */#include "copyright_wrs.h"/* FAT-FTL Lite Software Development Kit * Copyright (C) M-Systems Ltd. 1995-2001 *//*modification history--------------------01l,29oct04,mdo Documentation fixes for apigen01k,13jul04,kab Cleanup01j,21oct03,dtr Fixing compiler warnings.01i,17sep03,dtr Fix 16 bit interleaved mode for PILOT rev ADS board.01h,24jun02,nrv fixing the condition where flashPtr[0x24] is checked twice01g,12dec01,yp removing assumption that the InterleavedWordWrite call might have to support 16 bit commands. reworked identification of two 16 bit devices and single 32 bit device. made erase routines mutually exclusive at compile time. removed dataWidth and deviceWidth members from CFI structure. removed unused MakeCmd function.01f,11dec01,nrv fixed build error01e,29oct01,yp Converting to WRS coding convention. Adding support for double word width devices. Converting identification process to byte offsets. Providing alternative write mechanism for none functional WRITE_TO_BUFFER paltforms.01d,.......,vf Added for debugging of this MTD.01c,06apr99,vf Try to make endian-safe. LONGSWAP and WORDSWAP are #define'd in vxWorks.h.01b,09jan99,an Added support for machines that require a full 32bit write to access fall correctly. Also fixed code to correctly compute total Flash size, virtual block size, and combined write buffer size when interleaved parts are detected.01a,27may97,msys original version from M-Systems*//* Original CVS history * $Log: cfiscs.c,v $ * Revision 1.1 2000/07/13 01:46:37 caluml * Added TFFS and bootParams stuff * * Revision 1.1.1.1 2000/05/31 00:09:33 caluml * T201 Arm Ugl2 * * Revision 1.1 2000/04/14 16:26:14 caluml * This version is for the Assabet board with 32Mb of StrataFlash memory * * * Rev 1.20 11 Nov 1997 15:26:00 ANDRY * get rid of compiler warnings * * Rev 1.19 06 Oct 1997 9:53:30 danig * VPP functions under #ifdef * * Rev 1.18 18 Sep 1997 10:05:40 danig * Warnings * * Rev 1.17 10 Sep 1997 16:31:16 danig * Got rid of generic names * * Rev 1.16 04 Sep 1997 18:19:34 danig * Debug messages * * Rev 1.15 31 Aug 1997 14:50:52 danig * Registration routine return status * * Rev 1.14 27 Jul 1997 15:00:38 danig * FAR -> FAR0 * * Rev 1.13 21 Jul 1997 19:58:24 danig * No watchDogTimer * * Rev 1.12 15 Jul 1997 19:18:32 danig * Ver 2.0 * * Rev 1.11 09 Jul 1997 10:58:52 danig * Fixed byte erase bug & changed identification routines * * Rev 1.10 20 May 1997 14:48:02 danig * Changed overwrite to mode in write routines * * Rev 1.9 18 May 1997 13:54:58 danig * JEDEC ID independent * * Rev 1.8 13 May 1997 16:43:10 danig * Added getMultiplier. * * Rev 1.7 08 May 1997 19:56:12 danig * Added cfiscsByteSize * * Rev 1.6 04 May 1997 14:01:16 danig * Changed cfiscsByteErase and added multiplier * * Rev 1.4 15 Apr 1997 11:38:52 danig * Changed word identification and IDs. * * Rev 1.3 15 Jan 1997 18:21:40 danig * Bigger ID string buffers and removed unused definitions. * * Rev 1.2 08 Jan 1997 14:54:06 danig * Changes in specification * * Rev 1.1 25 Dec 1996 18:21:44 danig * Initial revision *//*DESCRIPTIONThis library provides an MTD for devices that conform to the Common Flash Interface (CFI) and the Intel Scalable Command Set (SCS). The library provides identification, erase and write routines for 8, 16, and 32 bit devices in native or byte mode. Support is also added for word width devices interleaved in word width mode where bytes 0 and 1 would be on device one and bytes 2 and 3 would be on device two. Support is also present for configurations that only permit double word width writes.The identification process supports byte, word, and double word width devices as specified by the CFI query process. Vendor specific extensions are made available from an instance specific data structure, referred to in this file as this CFI. However, the driver remains vendor neutral in the hope that it will be applicable to a larger range of devices.In addition to supporting a boot code region this driver is also able to reserve the last erase block of each device in the array so the vxWorks mayuse this region as NVRAM if the macro SAVE_NVRAM_REGION is defined.Some hardware using word width interleaved devices permit only 32 bit writes.In these environments the macro INTERLEAVED_MODE_REQUIRES_32BIT_WRITES must be defined. The erase routine in particular and some of the write routines are impacted by this. BSPs tested:BSP Device Socket DefinesAssabet StrataFlash RFA 32_BIT_WRITES SAVE_NVRAMddb5476 StrataFlash RFA pcPentium3 StrataFlash PCMCIAads860 StrataFlash PCMCIAprpm800 StrataFlash RFA BUFFER_WRITE_BROKENintegrator StrataFlash RFA SAVE_NVRAM(720/920)INCLUDE FILES:\NOMANUAL*/#include <stdio.h>#include "tffs/flflash.h"#include "tffs/backgrnd.h"/* Instance specific CFI data so that a system may have more than one CFI * device. */typedef struct { unsigned commandSetId; /* id of a specific command set. */ unsigned altCommandSetId; /* id of alternate command set. */ FLBoolean wordMode; /* TRUE - word mode. */ /* FALSE - byte mode. */ int multiplier; /* the number of bytes in */ /* addressing scheme */ int interleaveFactor; /* Number of bytes interleaved */ unsigned maxBytesWrite; /* maximum number of bytes */ /* in multi-byte write. */ FLBoolean vpp; /* if = TRUE, need vpp. */ long optionalCommands; /* optional commands supported */ /* (1 = yes, 0 = no): */ /* bit 0 - chip erase. */ /* bit 1 - suspend erase. */ /* bit 2 - suspend write */ /* bit 3 - lock/unlock. */ /* bit 4 - queued erase. */ unsigned afterSuspend; /* functions supported after */ /* suspend (1 = yes, 0 = no): */ /* bit 0 - write after erase */ /* suspend. */} CFI;LOCAL CFI mtdVars[DRIVES];/* defines *//* * define the following if the target requires interleaves to be * full 32 bit write accesses when erasing blocks. The Assabet BSP * is the only one requiring this so far. */#undef INTERLEAVED_MODE_REQUIRES_32BIT_WRITES/* Save the last erase block on each device discovered in the array * for NVRAM */#define SAVE_NVRAM_REGION/* disable debugging */#undef CFI_DEBUG#ifdef CFI_DEBUG#define DEBUG_PRINT printf#else#undef DEBUG_PRINT#endif/* define the following if the WRITE_TO_BUFFER command does not work * The value of maxBytesWrite is then forced to 1, resulting in either * byte or word writes being used */#define BUFFERED_WRITE_BROKEN#ifndef _BYTE_ORDER#error "Error: _BYTE_ORDER needs to be #define'd. Try #include \"vxWorks.h\" "#endif#if (_BYTE_ORDER == _BIG_ENDIAN)#define CFI_LONGSWAP(x) LONGSWAP(x) /* swap everything in a long word */#define CFI_WORDSWAP(x) WORDSWAP(x) /* swap the shorts in a long */#define CFI_BYTESWAP(x) ( ( (x & 0xff) << 8) | ( (x >> 8) & 0xff) ) /* Swap bytes in a short */#else#define CFI_LONGSWAP(x) (x) /* pass it as is */#define CFI_WORDSWAP(x) (x) /* pass it as is */#define CFI_BYTESWAP(x) (x) /* pass it as is */#endif /* _BYTE_ORDER == _BIG_ENDIAN */#define CFI_LONG_WRITE(addr, data) (*(ULONG *)addr = (ULONG)(CFI_LONGSWAP(data)))#define CFI_WORD_WRITE(addr, data) (*(USHORT *)addr = (USHORT)(CFI_WORDSWAP(data)))#define CFI_WORD_READ(addr) (CFI_BYTESWAP(*(USHORT *)addr))#define CFI_LONG_READ(addr) (CFI_WORDSWAP(*(ULONG *)addr))/* JEDEC-IDs */#define VOYAGER_ID 0x8915#define KING_COBRA_ID 0xb0d0/* command set IDs */#define INTEL_COMMAND_SET 0x0001#define AMDFUJ_COMMAND_SET 0x0002#define INTEL_ALT_COMMAND_SET 0x0001#define AMDFUJ_ALT_COMMAND_SET 0x0004#define ALT_NOT_SUPPORTED 0x0000/* CFI identification strings */#define ID_STR_LENGTH 3#define QUERY_ID_STR "QRY"#define PRIMARY_ID_STR "PRI"#define ALTERNATE_ID_STR "ALT"/* commands */#define CONFIRM_SET_LOCK_BIT 0x01#define PROGRAM_WORD 0x10#define SETUP_BLOCK_ERASE 0x20#define SETUP_QUEUE_ERASE 0x28#define SETUP_CHIP_ERASE 0x30#define PROGRAM 0x40#define CLEAR_STATUS 0x50#define SET_LOCK_BIT 0x60#define CLEAR_LOCK_BIT 0x60#define READ_STATUS 0x70#define READ_ID 0x90#define QUERY 0x98#define SUSPEND_WRITE 0xb0#define SUSPEND_ERASE 0xb0#define CONFIG 0xb8#define CONFIRM_WRITE 0xd0#define RESUME_WRITE 0xd0#define CONFIRM_ERASE 0xd0#define RESUME_ERASE 0xd0#define CONFIRM_CLEAR_LOCK_BIT 0xd0#define WRITE_TO_BUFFER 0xe8#define READ_ARRAY 0xff/* status register bits */#define WSM_ERROR 0x3a#define SR_BLOCK_LOCK 0x02#define SR_WRITE_SUSPEND 0x04#define SR_VPP_ERROR 0x08#define SR_WRITE_ERROR 0x10#define SR_LOCK_SET_ERROR 0x10#define SR_ERASE_ERROR 0x20#define SR_LOCK_RESET_ERROR 0x20#define SR_ERASE_SUSPEND 0x40#define SR_READY 0x80/* optional commands support */#define CHIP_ERASE_SUPPORT 0x0001#define SUSPEND_ERASE_SUPPORT 0x0002#define SUSPEND_WRITE_SUPPORT 0x0004#define LOCK_SUPPORT 0x0008#define QUEUED_ERASE_SUPPORT 0x0010/* supported functions after suspend */#define WRITE_AFTER_SUSPEND_SUPPORT 0x0001#define thisCFI ((CFI *)vol.mtdVars)/******************************************************************************* cfiscsGetChipCount - return the number of chips in this array** Leave the first chip (or set of interleaved chips) in READ_ARRAY* mode and move forward by chip size (or interleaved chip size) until* address wrap around is detected. The chip count is updated in * vol.noOfChips.** RETURNS:** ERRNO*/LOCAL FLStatus cfiscsGetChipCount ( FLFlash vol ) { UINT32 cmdBuffer; int ix; char queryIdStr[ID_STR_LENGTH + 1] = QUERY_ID_STR; FlashPTR flashPtr = (FlashPTR) flMap(vol.socket, 0); /* Switch first (interleaved) chip set to QUERY mode */ cmdBuffer = 0x0; for (ix = 0; ix < thisCFI->multiplier; ix++) cmdBuffer |= QUERY << (8 * ix); flashPtr[0x55 * thisCFI->multiplier] = cmdBuffer; /* NOTE: The address wrap around technique used here works only if the flash * size was declared correctly in the socket driver. At some point the MTD * should be discovering flash size and exporting it to the socket driver. */ for (vol.noOfChips = 1 * vol.interleaving; /* Scan the chips */ vol.noOfChips < 2000; /* Big enough ? */ vol.noOfChips += vol.interleaving) {#ifdef SAVE_NVRAM_REGION /* Reinstate the NVRAM region */ flashPtr = (FlashPTR) flMap(vol.socket, vol.noOfChips * (vol.chipSize + (vol.erasableBlockSize / vol.interleaving)));#else flashPtr = (FlashPTR) flMap(vol.socket, vol.noOfChips * vol.chipSize);#endif#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Looking for Flash device at base 0x%x\n", (UINT32) flashPtr);#endif if ((flashPtr[0x10 * thisCFI->multiplier]) == (unsigned char)queryIdStr[0] && (flashPtr[0x11 * thisCFI->multiplier]) == (unsigned char)queryIdStr[1] && (flashPtr[0x12 * thisCFI->multiplier]) == (unsigned char)queryIdStr[2]) { goto noMoreChips; /* Wrapped around */ } /* Confirm this is also a CFI part */ *(UCHAR *)(flashPtr + (0x55 * thisCFI->multiplier)) = (UCHAR)(QUERY); if (flashPtr[0x10 * thisCFI->multiplier] != (unsigned char)queryIdStr[0] || flashPtr[0x11 * thisCFI->multiplier] != (unsigned char)queryIdStr[1] || flashPtr[0x12 * thisCFI->multiplier] != (unsigned char)queryIdStr[2]) { /* Should not happen !! */ goto noMoreChips; /* Not a CFI Flash part */ } flashPtr[0x55 * thisCFI->multiplier] = (UCHAR)(CLEAR_STATUS); flashPtr[0x55 * thisCFI->multiplier] = (UCHAR)(READ_ARRAY); } /* We should never get here. */#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Device count overflow\n");#endif /* DEBUG_PRINT */ return flGeneralFailure; noMoreChips: flashPtr = (FlashPTR) flMap(vol.socket, 0); /* Switch to READ_ARRAY mode */ cmdBuffer = 0x0; for (ix = 0; ix < thisCFI->multiplier; ix++) cmdBuffer |= READ_ARRAY << (8 * ix); flashPtr[0x55 * thisCFI->multiplier] = cmdBuffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -