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

📄 am29lv64xdmtd.c

📁 Freescale MPC85xx BSP (8555/8541)。绝对可用的。
💻 C
📖 第 1 页 / 共 2 页
字号:
            while ((wFlashPtr[0] != tmpWord.ushort) &&                    (flMsecCounter < writeTimeout))                {                if (((wFlashPtr[0] & AMD_D5) &&                      ((wFlashPtr[0] ^ tmpWord.ushort) &   0xff)))                    {                    wFlashPtr[0] = read_array;#ifdef DEBUG_PRINT                    DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif                    return flWriteFault;                    }                }            cAddr += cLength;            buffer = (const void FAR1 *)((UINT32)buffer + cLength);            flashPtr = 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;    }/******************************************************************************** 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.*							* RETURNS:                                                   *	FLStatus	: 0 on success, failed otherwise** ERRNO*/LOCAL  FLStatus cfiAmdErase(    FLFlash vol,                 /* Pointer identifying drive      */    int firstErasableBlock,      /* Number of first block to erase */    int numOfErasableBlocks      /* Number of blocks to erase      */    )    {    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;    /* 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;#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));        *(UINT16 *)unlockAddr1 = unlock1;        *(UINT16 *)unlockAddr2 = unlock2;        *(UINT16 *)unlockAddr1 = erase_setup;        *(UINT16 *)unlockAddr1 = unlock1;        *(UINT16 *)unlockAddr2 = unlock2;        *(UINT16 *)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. ** RETURNS:*      FLStatus        : 0 on positive identification, failed otherwise ** ERRNO** http://www.amd.com/us-en/FlashMemory/ProductInformation/0,,37_1447_1451_1780%5E1834%5E1955,00.html** \NOMANUAL*/FLStatus cfiAmdIdentify    (    FLFlash vol              /* Pointer identifying drive */    )    {    FlashPTR flashPtr = (FlashPTR) flMap(vol.socket, 0);    FlashWPTR flashWPtr = (FlashWPTR) flashPtr;    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");    DEBUG_PRINT("Debug: flash base addr = 0x%x\n", (UINT32)flashPtr);#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;        }#ifdef DEBUG_PRINT    DEBUG_PRINT ("Debug: No flash media detected!\n");#endif    return flUnknownMedia;    getCFI:    if (!eightBitMode)        {        thisCFI->wordMode = TRUE; /* limiting ourselves to 8 an 16 bit devs */        thisCFI->unlockAddr1 = AMD_WW_UNLOCK_ADDR1;        thisCFI->unlockAddr2 = AMD_WW_UNLOCK_ADDR2;#ifdef DEBUG_PRINT        DEBUG_PRINT("WORD MODE !!\n");#endif        }    else        {        thisCFI->wordMode = FALSE;        thisCFI->unlockAddr1 = AMD_BW_UNLOCK_ADDR1;        thisCFI->unlockAddr2 = AMD_BW_UNLOCK_ADDR2;#ifdef DEBUG_PRINT        DEBUG_PRINT("WORD MODE !!\n");#endif        }    /* check the command set ID */    /* NOTE: Not swapped */    thisCFI->commandSetId = *(USHORT *)(&flashPtr[0x13 * thisCFI->multiplier]);#ifdef DEBUG_PRINT    DEBUG_PRINT ("Debug: Commandset ID is 0x%x\n", thisCFI->commandSetId);#endif    /* Only support the AMD/Fujitsu Command set */    if ( thisCFI->commandSetId != AMDFUJ_COMMAND_SET)        {#ifdef DEBUG_PRINT        DEBUG_PRINT("Debug: did not recognize command set.\n");#endif        return flUnknownMedia;        }    /* get address for primary algorithm extended table. */    primaryTable = CFI_WORD_READ(&flashPtr[0x15 * thisCFI->multiplier]);    /* check alternate command set ID. */    /* NOTE: not swapped */    thisCFI->altCommandSetId = *(USHORT *)                               (&flashPtr[0x17 * thisCFI->multiplier]);    if (thisCFI->altCommandSetId != AMDFUJ_ALT_COMMAND_SET &&        thisCFI->altCommandSetId != ALT_NOT_SUPPORTED)        return flUnknownMedia;    /* get address for secondary algorithm extended table. */    secondaryTable = CFI_WORD_READ(&flashPtr[0x19 * thisCFI->multiplier]);    thisCFI->vpp = flashPtr[0x1d * thisCFI->multiplier];    /*Get the number of erase block descriptions for the CFI*/    if (eightBitMode)        thisCFI->sectorDefs = (int) (*(UCHAR *)                                      (&flashPtr[0x2c * thisCFI->multiplier]));    else        thisCFI->sectorDefs = (int) (*(USHORT *)                                     (&flashPtr[0x2c * thisCFI->multiplier]));    /* We should bail out if this is greater than 8 */#ifdef DEBUG_PRINT    DEBUG_PRINT ("Debug: Number of erase block descriptions is 0x%x\n",                  thisCFI->sectorDefs);#endif    vol.erasableBlockSize = 0;    thisCFI->sectorsInCFI = 0;    for ( ix = 0; ix < thisCFI->sectorDefs; ix++)        {        thisCFI->secDesc[ix].numSecs = (int) (*(USHORT *)                                              (&flashPtr[(0x2d + (ix * 4)) * thisCFI->multiplier]));        thisCFI->secDesc[ix].numSecs++;#ifdef DEBUG_PRINT        DEBUG_PRINT ("Debug: Num sectors in %d - %d\n", ix, thisCFI->secDesc[ix].numSecs);#endif        thisCFI->secDesc[ix].secSize = (long) ((*(USHORT *)                                                (&flashPtr[(0x2f + (ix * 4)) * thisCFI->multiplier])) +                                               (*(USHORT *)(&flashPtr[(0x30 + (ix * 4)) *                                                                       thisCFI->multiplier])) * 0x100L);#ifdef DEBUG_PRINT        DEBUG_PRINT ("Debug: Sector size is 0x%x\n",                     (UINT32) thisCFI->secDesc[ix].secSize);#endif        /* TrueFFS does not support the flexible sector architecture so we          * take the largest sector size to be the erase block size.         */         if (vol.erasableBlockSize < thisCFI->secDesc[ix].secSize)            vol.erasableBlockSize = thisCFI->secDesc[ix].secSize;        /* Also track the number of sector on this device */        thisCFI->sectorsInCFI += thisCFI->secDesc[ix].numSecs;        }    if (vol.erasableBlockSize == 0x00)        vol.erasableBlockSize = 0x80L;    else        vol.erasableBlockSize *= 256;    /* Get Device Size */       if (eightBitMode)        vol.chipSize = (1L << flashPtr[0x27 * thisCFI->multiplier]);    else        vol.chipSize = (1L << *(USHORT*)(&flashPtr[0x27 * thisCFI->multiplier]));    vol.erasableBlockSize *= vol.interleaving;    vol.chipSize -= CDS85XX_FLASH_RESERVED_SIZE;#ifdef SAVE_NVRAM_REGION    /* Top boot block devices will loose their entire boot block to NVRAM. Since      * TrueFFS cares not about the subdivisions we reserve an entire erase block     * on each of the interleaved devices.      */    vol.chipSize -= vol.erasableBlockSize;#endif#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: %d sectors on device\n", thisCFI->sectorsInCFI);    DEBUG_PRINT("Debug: Erasable block size is 0x%lx\n", vol.erasableBlockSize);    DEBUG_PRINT("Debug: Chip size is 0x%lx\n", vol.chipSize);#endif    thisCFI->bootBlockType = BOOTBLOCK_NONE;    /* Simplest case is the uniform sector device. Has only one      * sector desc.      */    for (; thisSector < thisCFI->secDesc[0].numSecs; thisSector++)        {        thisCFI->secInfo[thisSector].sectorSize = vol.erasableBlockSize;        thisCFI->secInfo[thisSector].sectorBaseAdrs = sectorBaseAdrs;        sectorBaseAdrs += (CardAddress) vol.erasableBlockSize;        }#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: Number of boot block sectors is %d\n", thisCFI->bootBlockSectors);#endif    /* Make sure this comes at the end since the device is set to READ_ARRAY     * mode prior to the return     */    if (cfiAmdChipCountGet(&vol) != flOK)        return flUnknownMedia;#ifdef DEBUG_PRINT    DEBUG_PRINT ("Debug: No of chips detected is %d\n", vol.noOfChips);#if 0    for (ix = 0; ix < thisCFI->sectorsInCFI; ix++)        DEBUG_PRINT ("%2d:0x%x	---  0x%lx\n", ix,                     thisCFI->secInfo[ix].sectorBaseAdrs,                      thisCFI->secInfo[ix].sectorSize);#endif#endif    vol.erase = cfiAmdErase;    vol.write = cfiAmdWrite;    /* Might have to do this on a bus width basis but for now it seems to     * work with Intel devices.     */    flashPtr[0] = AMD_READ_ARRAY;    flashPtr[1] = AMD_READ_ARRAY;    flashPtr[2] = AMD_READ_ARRAY;    flashPtr[3] = AMD_READ_ARRAY;    return flOK;    }

⌨️ 快捷键说明

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