📄 flflash.c
字号:
/* flflash.c - True Flash File System *//* Copyright 1984-2004 Wind River Systems, Inc. */#include "copyright_wrs.h"/* FAT-FTL Lite Software Development Kit * Copyright (C) M-Systems Ltd. 1995-1997 *//*modification history--------------------01b,29jul04,alr added read after initial chip reset (delay, sync)01a,29jul04,alr modified file header, restarted history*/#include "flflash.h"#define READ_ID 0x90#define INTEL_READ_ARRAY 0xff#define AMD_READ_ARRAY 0xf0#if FALSE/* MTD registration information */extern int noOfMTDs;extern MTDidentifyRoutine mtdTable[];#endif /* FALSE *//*----------------------------------------------------------------------*//* f l a s h M a p *//* *//* Default flash map method: Map through socket window. *//* This method is applicable for all NOR Flash *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : Card address to map *//* length : Length to map (irrelevant here) *//* *//* Returns: *//* Pointer to required card address *//*----------------------------------------------------------------------*/static void FAR0 *flashMap(FLFlash vol, CardAddress address, int length){ return flMap(vol.socket,address);}/*----------------------------------------------------------------------*//* f l a s h R e a d *//* *//* Default flash read method: Read by copying from mapped address *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : Card address to read *//* buffer : Area to read into *//* length : Length to read *//* *//*----------------------------------------------------------------------*/static FLStatus flashRead(FLFlash vol, CardAddress address, void FAR1 *buffer, int length, int mode){ tffscpy(buffer,vol.map(&vol,address,length),length); return flOK;}/*----------------------------------------------------------------------*//* f l a s h N o W r i t e *//* *//* Default flash write method: Write not allowed (read-only mode) *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : Card address to write *//* buffer : Area to write from *//* length : Length to write *//* *//* Returns: *//* Write-protect error *//*----------------------------------------------------------------------*/static FLStatus flashNoWrite(FLFlash vol, CardAddress address, const void FAR1 *from, int length, int mode){ return flWriteProtect;}/*----------------------------------------------------------------------*//* f l a s h N o E r a s e *//* *//* Default flash erase method: Erase not allowed (read-only mode) *//* *//* Parameters: *//* vol : Pointer identifying drive *//* firstBlock : No. of first erase block *//* noOfBlocks : No. of contiguous blocks to erase *//* *//* Returns: *//* Write-protect error *//*----------------------------------------------------------------------*/static FLStatus flashNoErase(FLFlash vol, int firstBlock, int noOfBlocks){ return flWriteProtect;}/*----------------------------------------------------------------------*//* s e t N o C a l l b a c k *//* *//* Register power on callback routine. Default: no routine is *//* registered. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//*----------------------------------------------------------------------*/static void setNoCallback(FLFlash vol){ flSetPowerOnCallback(vol.socket,NULL,NULL);}/*----------------------------------------------------------------------*//* f l I n t e l I d e n t i f y *//* *//* Identify the Flash type and interleaving for Intel-style Flash. *//* Sets the value of vol.type (JEDEC id) & vol.interleaving. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at *//* a specific location. If null, Intel procedure *//* is used. *//* idOffset : Chip offset to use for identification *//* *//* Returns: *//* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*//*----------------------------------------------------------------------*/void flIntelIdentify(FLFlash vol, void (*amdCmdRoutine)(FLFlash vol, CardAddress, unsigned char, FlashPTR), CardAddress idOffset){ int inlv; int tmp; FlashPTR flashPtr; unsigned char vendorId = 0; unsigned char firstByte = 0; unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY; flNeedVpp (vol.socket); /* ADDED, first thing to do */ flashPtr = (FlashPTR) flMap(vol.socket,idOffset); for (inlv = 0; inlv < 15; inlv++) { /* Increase interleaving until failure */ flashPtr[inlv] = resetCmd; /* Reset the chip */ tmp = flashPtr[inlv]; flashPtr[inlv] = resetCmd; /* Once again for luck */ tmp = flashPtr[inlv]; if (inlv == 0) firstByte = flashPtr[0]; /* Remember byte on 1st chip */ if (amdCmdRoutine) /* AMD: use unlock sequence */ amdCmdRoutine(&vol,idOffset + inlv, READ_ID, flashPtr); else flashPtr[inlv] = READ_ID; /* Read chip id */ flDelayLoop(2); /* HOOK for VME-177 */ if (inlv == 0) vendorId = flashPtr[0]; /* Assume first chip responded */ else if (flashPtr[inlv] != vendorId || firstByte != flashPtr[0]) { /* All chips should respond in the same way. We know interleaving = n */ /* when writing to chip n affects chip 0. */ /* Get full JEDEC id signature */ vol.type = (FlashType) ((vendorId << 8) | flashPtr[inlv]); flashPtr[inlv] = resetCmd; break; } flashPtr[inlv] = resetCmd; } if (inlv & (inlv - 1)) vol.type = NOT_FLASH; /* not a power of 2, no way ! */ else vol.interleaving = inlv; flDontNeedVpp (vol.socket); /* ADDED, last thing to do */}/*----------------------------------------------------------------------*//* i n t e l S i z e *//* *//* Identify the card size for Intel-style Flash. *//* Sets the value of vol.noOfChips. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at *//* a specific location. If null, Intel procedure *//* is used. *//* idOffset : Chip offset to use for identification *//* *//* Returns: *//* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*//*----------------------------------------------------------------------*/FLStatus flIntelSize(FLFlash vol, void (*amdCmdRoutine)(FLFlash vol, CardAddress, unsigned char, FlashPTR), CardAddress idOffset){ unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY; FlashPTR flashPtr; flNeedVpp (vol.socket); /* ADDED, first thing to do */ flashPtr = (FlashPTR) vol.map(&vol,idOffset,0); if (amdCmdRoutine) /* AMD: use unlock sequence */ amdCmdRoutine(&vol,0,READ_ID, flashPtr); else flashPtr[0] = READ_ID; /* We leave the first chip in Read ID mode, so that we can */ /* discover an address wraparound. */ for (vol.noOfChips = 0; /* Scan the chips */ vol.noOfChips < 2000; /* Big enough ? */ vol.noOfChips += vol.interleaving) { int i; flashPtr = (FlashPTR) vol.map(&vol,vol.noOfChips * vol.chipSize + idOffset,0); /* Check for address wraparound to the first chip */ if (vol.noOfChips > 0 && (FlashType) ((flashPtr[0] << 8) | flashPtr[vol.interleaving]) == vol.type) goto noMoreChips; /* wraparound */ /* Check if chip displays the same JEDEC id and interleaving */ for (i = (vol.noOfChips ? 0 : 1); i < vol.interleaving; i++) { if (amdCmdRoutine) /* AMD: use unlock sequence */ amdCmdRoutine(&vol,vol.noOfChips * vol.chipSize + idOffset + i, READ_ID, flashPtr); else flashPtr[i] = READ_ID; if ((FlashType) ((flashPtr[i] << 8) | flashPtr[i + vol.interleaving]) != vol.type) goto noMoreChips; /* This "chip" doesn't respond correctly, so we're done */ flashPtr[i] = resetCmd; } }noMoreChips: flashPtr = (FlashPTR) vol.map(&vol,idOffset,0); flashPtr[0] = resetCmd; /* reset the original chip */ flDontNeedVpp (vol.socket); /* ADDED, last thing to do */ return (vol.noOfChips == 0) ? flUnknownMedia : flOK;}/*----------------------------------------------------------------------*//* i s R A M *//* *//* Checks if the card memory behaves like RAM *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* 0 = not RAM-like, other = memory is apparently RAM *//*----------------------------------------------------------------------*/static FLBoolean isRAM(FLFlash vol){ volatile unsigned int FAR0 * flashIPtr; unsigned int firstInt; unsigned int writeInt; flNeedVpp (vol.socket); /* ADDED, first thing to do */ flashIPtr = (volatile unsigned int FAR0 *) flMap(vol.socket,0); firstInt = flashIPtr[0]; writeInt = (firstInt != 0x0) ? 0x0 : (unsigned int) -1; ISRAM_WRITE(writeInt, &flashIPtr[0]); /* write something else safe */ flDelayLoop(2); /* HOOK for VME-177 */ if (flashIPtr[0] == writeInt) { /* Was it written ? */ flashIPtr[0] = firstInt; /* must be RAM, undo the damage */ flDontNeedVpp (vol.socket); /* ADDED, last thing to do */#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: error, socket window looks like RAM.\n");#endif return TRUE; } flDontNeedVpp (vol.socket); /* ADDED, last thing to do */ return FALSE;}/*----------------------------------------------------------------------*//* f l I d e n t i f y F l a s h *//* *//* Identify the current Flash medium and select an MTD for it *//* *//* Parameters: *//* socket : Socket of flash *//* vol : New volume pointer *//* *//* Returns: *//* FLStatus : 0 = Flash was identified *//* other = identification failed *//*----------------------------------------------------------------------*/FLStatus flIdentifyFlash(FLSocket *socket, FLFlash vol){ FLStatus status = flUnknownMedia; int iMTD; vol.socket = socket;#ifndef FIXED_MEDIA /* Check that we have a media */ flResetCardChanged(vol.socket); /* we're mounting anyway */ checkStatus(flMediaCheck(vol.socket));#endif if (isRAM(&vol)) return flUnknownMedia; /* if it looks like RAM, leave immediately */ /* Install default methods */ vol.type = NOT_FLASH; vol.flags = 0; vol.map = flashMap; vol.read = flashRead; vol.write = flashNoWrite; vol.erase = flashNoErase; vol.setPowerOnCallback = setNoCallback; /* Attempt all MTD's */ for (iMTD = 0; iMTD < noOfMTDs && status != flOK; iMTD++) status = mtdTable[iMTD](&vol); if (status != flOK) { /* No MTD recognition */ /* Setup arbitrary parameters for read-only mount */ vol.chipSize = 0x100000L; vol.erasableBlockSize = 0x1000; vol.noOfChips = 1; vol.interleaving = 1; #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: did not identify flash media.\n"); #endif return flUnknownMedia; } return flOK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -