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

📄 cfiscs.c

📁 MPC8560 for vxwork BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (flWriteProtected(vol.socket))        return flWriteProtect;    if ((length & 1) || (address & 1))  /* Only write whole words,                        only on word-boundary */        return flBadParameter;#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)        checkStatus(flNeedVpp(vol.socket));#endif    if (thisCFI->maxBytesWrite > 1) /* multi-byte write supported? */        maxWordsPerWrite = thisCFI->maxBytesWrite;    else        maxWordsPerWrite = 1;  /* Part can only handle single-byte writes. */    flashPtr = (FlashWPTR)flMap(vol.socket, address);    /* Now program the part: */    if (maxWordsPerWrite > 1)  /* Part can handle writes of multiple                   words to buffer */        {        wordsWritten = 0;        wordsRemaining = length / 2;  /* Number of words left to program into                      a part, convert bytes to words. */        while (wordsRemaining > 0)            {            /* Figure out how many words we need to write.  This will either              * be the max allowed (maxWordsPerWrite), or what's left over at              * the end (wordsRemaining).  Make it extra-cryptic with the             * ?: operator.             */            wordsThisWrite = (wordsRemaining > maxWordsPerWrite)                              ? maxWordsPerWrite : wordsRemaining;            /* if we don't have enough aligned data to use a buffered write              * we just use a normal write              */            if ( (wordsThisWrite <2 ) && (wordsThisWrite > 0))                {                /* 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 don't want to clear in our data */                data |= CFI_LONGSWAP(* (ULONG *) buffer);                CFI_LONG_WRITE(flashPtr, (ULONG) (PROGRAM<<16) |PROGRAM);                CFI_LONG_WRITE(flashPtr, (ULONG) data);                /* Flow diagram says to check that status register says                  * everything is copacetic.                  */                while ( (!(CFI_WORD_READ(flashPtr) & SR_READY)) ||                        (!(CFI_WORD_READ((flashPtr + 1)) & SR_READY)) );                  CFI_LONG_WRITE(flashPtr, (ULONG) (READ_ARRAY<<16) |READ_ARRAY); #ifdef DEBUG_PRINT                DEBUG_PRINT("Debug: mtd: Using NON-buffered write to program %ld"                            " words at addr 0x%lx\n",                             wordsThisWrite, (ULONG) flashPtr);#endif                }            else                {                CFI_LONG_WRITE(flashPtr, (ULONG) ((CLEAR_STATUS<<16)                                                  |CLEAR_STATUS));                CFI_LONG_WRITE(flashPtr, (ULONG) (WRITE_TO_BUFFER<<16)                                |WRITE_TO_BUFFER);  /* both parts */                /* At this point, we must wait for XSR to indicate a buffer is                  * available. We will spin on this, but only for a maximum of 5                  * seconds.  We do the timing by taking advantage of the                  * ever-incrementing flMsecCounter.                 */                while ((!(CFI_WORD_READ((FlashWPTR)(flashPtr)) & SR_READY)) ||                       (!(CFI_WORD_READ((FlashWPTR)(flashPtr + 1)) & SR_READY)))                    ;                /* Check to see if either part timed out: */                if ( (!(CFI_WORD_READ(&flashPtr[0x0])     & SR_READY)) ||                     (!(CFI_WORD_READ((&flashPtr[0x1])) & SR_READY)) )                    {                    /* Send read-array command to both parts, abort. */                    CFI_LONG_WRITE(flashPtr, (ULONG) (READ_ARRAY<<16) |READ_ARRAY);                    return(flWriteFault);                    }                /* Now we must write the count value (zero-based, so 0 => 1 word,                 * 1 => 2 words, etc.) for the number of words we intend to                  * write.  Note that this code always assumes an even number of                  * words > 0.  Half the words go in the even part, half go in the                  * odd part.                 */                CFI_LONG_WRITE(flashPtr, (ULONG)(((wordsThisWrite / 2)  - 1)                                         <<16) | ((wordsThisWrite / 2) - 1));  /* both parts */                /* Finally, write the data.  This is easy, because now the                  * flash parts are seen as memory addresses.                 */                /* FIXME: This is suboptimal.  It is only writing half the                  * maximum words that could be written to each part in buffered                  * write mode. If we double the assignments for wordsWritten &                  * wordsThisWrite, and halve the assignment for wordsRemaining                  * each iteration, we can probably make this work optimally.                 * Then we should probably rename some of the variables to                  * "longsxxx".                 */                /* last argument is expected in bytes */                tffscpyLongs(&((long *)flashPtr)[wordsWritten/2],                              &((long *)buffer)[wordsWritten/2], wordsThisWrite*2);                /* Now send CONFIRM_WRITE command. */                CFI_LONG_WRITE(flashPtr, (ULONG) (CONFIRM_WRITE<<16)                                | CONFIRM_WRITE);  /* both parts */                /* Flow diagram says to check that status register says                  * everything is copacetic.                  */                while ( (!(CFI_WORD_READ(flashPtr)     & SR_READY)) ||                        (!(CFI_WORD_READ((flashPtr + 1)) & SR_READY)) );                 /* Check to see if either part timed out: */                if ( (!(CFI_WORD_READ(flashPtr)     & SR_READY)) ||                     (!(CFI_WORD_READ((flashPtr + 1)) & SR_READY)) )                    {                    /* Send read-array command to both parts, abort. */                    CFI_LONG_WRITE(flashPtr, (ULONG)(READ_ARRAY<<16)                                    | READ_ARRAY);                    return(flWriteFault);                    }                else                    {                    CFI_LONG_WRITE(flashPtr, (ULONG)(READ_ARRAY<<16)                                    | READ_ARRAY);                    }                /* Now verify the write. */                if (tffscmpWords(&((long *)flashPtr)[wordsWritten/2],                                 &((long *)buffer)[wordsWritten/2], wordsThisWrite*2))                    {#ifdef DEBUG_PRINT                    DEBUG_PRINT("Debug: mtd: Buffer write verification failed "                                "(interleaved word mode)\n");#endif                    return flWriteFault;                    }                else                    {#ifdef DEBUG_PRINT                    DEBUG_PRINT("Debug: mtd: Buffer write verification passed "                                "(interleaved word mode) at addr 0x%lx\n",                                 (ULONG) flashPtr);#endif                    }                }            wordsRemaining  -= wordsThisWrite;  /* That many fewer words to go. */            wordsWritten    += wordsThisWrite;  /* That many more done. */            }        }    else   /* Part cannot handle writes to buffer, must write one byte at a time. */        {        }    /* Put both devices back into read mode: */    CFI_LONG_WRITE(flashPtr, (ULONG) (READ_ARRAY<<16) | READ_ARRAY);     return status;    }/**************************************************************************** cfiscsDWordWrite - Write routine for devices on 32 bit bus.** This routine is instrumented specifically for the large detachable flash* module on the wrSbc85xx board.  It contains implementation and* configuration specific code and is not meant for generic use.** RETURNS:** ERRNO:** \NOMANUAL*/LOCAL FLStatus cfiscsDWordWrite    (    FLFlash vol,                /* Pointer identifying drive     */    CardAddress address,        /* Card address to write to      */    const void FAR1 *buffer,    /* Address of data to write      */    int length,                 /* Number of bytes to write      */    int mode                    /* write mode (overwrite yes/no) */    )    {    FLStatus status = flOK;    FlashPTR flashPtr;    unsigned int from, eachWrite;    const char FAR1 *temp = (const char FAR1 *)buffer;    /* Set timeout to 5 seconds from now */    unsigned long writeTimeout = flMsecCounter + 5000;    int uaoffset = 0, padding = 0;    void FAR1 *newBuff = 0, *orgBuff = 0;    int newLength = 0, orgLength = 0;    printf ("CFISCS: writing %d bytes to flash offset 0x%x\n", length, address);    /* check for unaligned address and length */    flashPtr = (FlashPTR) flMap(vol.socket, address);    if ((uaoffset = ((UINT32)flashPtr & 0x3)) || (length & 0x3))        {        padding = 0x3 & (4 - ((uaoffset + length) & 0x3));        newLength = uaoffset + length + padding;        newBuff = (void FAR1 *) malloc(newLength+8);        memset((void*)newBuff, 'A', newLength+8);#ifdef DEBUG_PRINT        DEBUG_PRINT("Debug: flashPtr mapped to %x\n", (UINT32) flashPtr);        DEBUG_PRINT("Debug: uaoffset = %d, padding = %d\n", uaoffset, padding);        DEBUG_PRINT("Debug: newLength = %d, newBuff = 0x%x\n",                    newLength, newBuff);#endif        flashPtr = (FlashPTR) ((int)flashPtr & ~0x3);        *(FlashDPTR)flashPtr = (UINT32) ((READ_ARRAY << 24) |                                         (READ_ARRAY << 16) |                                         (READ_ARRAY << 8)  |                                         READ_ARRAY);        memcpy ((void*)newBuff, (void*)flashPtr, newLength);        memcpy ((void*)((int)newBuff+uaoffset), (void*)buffer, length);        orgBuff = (void FAR1 *)buffer;        orgLength = length;        temp = newBuff;        buffer = newBuff;        length = newLength;        }    if (flWriteProtected(vol.socket))        return flWriteProtect;#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)        checkStatus(flNeedVpp(vol.socket));#endif    if (thisCFI->maxBytesWrite > 1) /* multi-byte write supported */        eachWrite = thisCFI->maxBytesWrite * vol.interleaving;    else        eachWrite = 4;  /* Max bus width */    for (from = 0; (int)from < length && status == flOK; from += eachWrite)        {        int thisLength = length - from;        if (thisLength > (int)eachWrite)            thisLength = eachWrite;        flashPtr = (FlashPTR) flMap(vol.socket, address + from);        do             {            if ((thisCFI->maxBytesWrite > 1) &&                 ((thisCFI->maxBytesWrite & 0x3) == 0))                *(FlashDPTR)flashPtr = (UINT32) ((WRITE_TO_BUFFER << 24) |                                                 (WRITE_TO_BUFFER << 16) |                                                 (WRITE_TO_BUFFER << 8)  |                                                 WRITE_TO_BUFFER);            else                *(FlashDPTR)flashPtr = (UINT32) ((PROGRAM << 24) |                                                 (PROGRAM << 16) |                                                 (PROGRAM << 8)  |                                                 PROGRAM);            } while (!(*(FlashDPTR)flashPtr &                       (SR_READY<<24|SR_READY<<16|SR_READY<<8|SR_READY)) &&                     (flMsecCounter < writeTimeout));        if (!(*(FlashDPTR)flashPtr &              (SR_READY<<24|SR_READY<<16|SR_READY<<8|SR_READY)))            {#ifdef DEBUG_PRINT            DEBUG_PRINT("Debug: timeout error in CFISCS write.\n");#endif            status = flWriteFault;            }        /* If we are using the WRITE_TO_BUFFER command then we must program         * the buffer length         */        if ((thisCFI->maxBytesWrite > 1) &&             ((thisCFI->maxBytesWrite & 0x3) == 0))            *(FlashDPTR)flashPtr = (thisLength << 24 |                                    thisLength << 16 |                                    thisLength << 8 |                                    thisLength);        tffscpyLongs(flashPtr,temp + from,thisLength);#if FALSE        *(FlashDPTR)flashPtr = (UINT32) ((CONFIRM_WRITE << 24) |                                         (CONFIRM_WRITE << 16) |                                         (CONFIRM_WRITE << 8)  |                                         CONFIRM_WRITE);        *(FlashDPTR)flashPtr = (UINT32) ((CONFIRM_WRITE << 24) |                                         (CONFIRM_WRITE << 16) |                                         (CONFIRM_WRITE << 8)  |                                         CONFIRM_WRITE);#endif        while (!((*flashPtr & SR_READY) &&                 (*(flashPtr+1) & SR_READY) &&                 (*(flashPtr+2) & SR_READY) &&                 (*(flashPtr+3) & SR_READY)) &&               (flMsecCounter < writeTimeout))            ;        if (!(flMsecCounter < writeTimeout))            {#ifdef DEBUG_PRINT            DEBUG_PRINT("Debug: timeout error in CFISCS write.\n");#endif            status = flWriteFault;            }        if (*flashPtr & WSM_ERROR)            {#ifdef DEBUG_PRINT            DEBUG_PRINT("Debug: error in CFISCS write.\n");#endif            status = (*flashPtr & SR_VPP_ERROR) ? flVppFailure : flWriteFault;            *(FlashDPTR)flashPtr = (UINT32) ((CLEAR_STATUS << 24) |                                             (CLEAR_STATUS << 16) |                                             (CLEAR_STATUS << 8)  |                                             CLEAR_STATUS);            }        *(FlashDPTR)flashPtr = (UINT32) ((READ_ARRAY << 24) |                                         (READ_ARRAY << 16) |                                         (READ_ARRAY << 8)  |                                         READ_ARRAY);        }#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)        flDontNeedVpp(vol.socket);#endif    flashPtr = (FlashPTR) flMap(vol.socket, address);    /* verify the data */    if (status == flOK &&        tffscmpWords((void FAR0 *) flashPtr, (void FAR1 *) buffer,length))        {#ifdef DEBUG_PRINT        DEBUG_PRINT("Debug: CFISCS dword write failed in verification.\n");#endif        status = flWriteFault;        }    if ((uaoffset != 0) || (padding != 0))        {        free (newBuff);        buffer = orgBuff;        length = orgLength;

⌨️ 快捷键说明

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