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

📄 sysflashmem.c

📁 vxworks MPC8541 BSP
💻 C
📖 第 1 页 / 共 3 页
字号:
/* sysFlashMem.c - Flash memory library */

/* Copyright 2003-2004 ZTE, Inc. */

/*
modification history
--------------------
01a,17jun03,lzq  created.
*/

/*
DESCRIPTION
This library contains routines to manipulate flash memory. Read, write and erase
routines are included.
*/

#include "vxWorks.h"
#include "intLib.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "semLib.h"
#include "taskLib.h"
#include "config.h"
#include "sysFlashMem.h"
#include "sysFlashDev.h"
#include "configFlashMem.h"

/* defines */

#define SYS_FLASH_HW_INIT() \
        if (sysFlashHwInit != NULL) \
           (sysFlashHwInit)()

#define SYS_FLASH_HW_ENABLE() \
        if (sysFlashHwEnable != NULL) \
           (sysFlashHwEnable)()

#define SYS_FLASH_HW_DISABLE() \
        if (sysFlashHwDisable != NULL) \
           (sysFlashHwDisable)()

#define SYS_FLASH_TIMER_RESET() \
        if (sysFlashTimerReset != NULL) \
           (sysFlashTimerReset)()

#define SYS_FLASH_IO_SYNC() \
        __asm__("eieio; isync; sync")

#define SYS_FLASH_BOARD_DELAY() \
        if (sysFlashBoardDelay != NULL) \
           (sysFlashBoardDelay)()

int flashInited = 0;

static FLASH_ID tempID, buffID;

static FLASH_UNIT flashUnit[FLASH_UNIT_NUM];

/* forward declarations */

static STATUS flashCfgRawGet(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS flashCmdRawSet(FLASH_DEV *dev, UINT32 pos, char *buf);

static void flashGetOctet1(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashSetOctet1(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashGetOctet2(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashSetOctet2(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashGetOctet4(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashSetOctet4(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashGetOctet8(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashSetOctet8(FLASH_DEV *dev, UINT32 pos, char *buf);

static void flashPartIdentify(FLASH_DEV *dev, FLASH_PART *unitPart, int partCnt);

static void amdFlashReset(FLASH_DEV *dev);
static STATUS amdFlashProbe(FLASH_DEV *dev);
static STATUS amdFlashErase(FLASH_DEV *dev, UINT32 pos);
static STATUS amdFlashWrite(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS amdFlashBWrite(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS amdFlashCheck(FLASH_DEV *dev, UINT32 pos, char *buf, int option);

static void intelFlashReset(FLASH_DEV *dev);
static STATUS intelFlashProbe(FLASH_DEV *dev);
static STATUS intelFlashUnlock(FLASH_DEV *dev, UINT32 pos);
static STATUS intelFlashUnlockAll(FLASH_DEV *dev);
static STATUS intelFlashErase(FLASH_DEV *dev, UINT32 pos);
static STATUS intelFlashWrite(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS intelFlashBWrite(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS intelFlashCheck(FLASH_DEV *dev, UINT32 pos, int option);

static STATUS flashCheck(FLASH_DEV *dev);

/*******************************************************************************
*
* flashCfgRawGet - 
*
*/
static STATUS flashCfgRawGet(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    pos *= dev->portSize;

    switch (dev->portSize)
        {
    case 8:
        *(UINT64 *)buf = *(volatile UINT64 *)(dev->devAddr + pos);
        break;

    case 4:
        *(UINT32 *)buf = *(volatile UINT32 *)(dev->devAddr + pos);
        break;

    case 2:
        *(UINT16 *)buf = *(volatile UINT16 *)(dev->devAddr + pos);
        break;

    case 1:
        *(UINT8 *)buf = *(volatile UINT8 *)(dev->devAddr + pos);
        break;

    default:
        return ERROR;
        }

    return OK;
    }

/*******************************************************************************
*
* flashCmdRawSet - 
*
*/
static STATUS flashCmdRawSet(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    pos *= dev->portSize;

    switch (dev->portSize)
        {
    case 8:
        *(volatile UINT64 *)(dev->devAddr + pos) = *(UINT64 *)buf;
        break;

    case 4:
        *(volatile UINT32 *)(dev->devAddr + pos) = *(UINT32 *)buf;
        break;

    case 2:
        *(volatile UINT16 *)(dev->devAddr + pos) = *(UINT16 *)buf;
        break;

    case 1:
        buf++;
        *(volatile UINT8 *)(dev->devAddr + pos) = *(UINT8 *)buf;
        break;

    default:
        return ERROR;
        }

    return OK;
    }

/*******************************************************************************
*
* flashGetOctet1 - 
*
*/
static void flashGetOctet1(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    *(UINT8 *)buf = *(volatile UINT8 *)(dev->devAddr + pos);
    }

/*******************************************************************************
*
* flashSetOctet1 - 
*
*/
static void flashSetOctet1(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    if ((buf >= (char *)&amdFlashCmd[0] &&
        buf < (char *)&amdFlashCmd[sizeof(amdFlashCmd) / sizeof(amdFlashCmd[0])]) ||
        (buf >= (char *)&intelFlashCmd[0] &&
        buf < (char *)&intelFlashCmd[sizeof(intelFlashCmd) / sizeof(intelFlashCmd[0])]))
        buf++;

    *(volatile UINT8 *)(dev->devAddr + pos) = *(UINT8 *)buf;
    }

/*******************************************************************************
*
* flashGetOctet2 - 
*
*/
static void flashGetOctet2(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    *(UINT16 *)buf = *(volatile UINT16 *)(dev->devAddr + pos);
    }

/*******************************************************************************
*
* flashSetOctet2 - 
*
*/
static void flashSetOctet2(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    *(volatile UINT16 *)(dev->devAddr + pos) = *(UINT16 *)buf;
    }

/*******************************************************************************
*
* flashGetOctet4 - 
*
*/
static void flashGetOctet4(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    *(UINT32 *)buf = *(volatile UINT32 *)(dev->devAddr + pos);
    }

/*******************************************************************************
*
* flashSetOctet4 - 
*
*/
static void flashSetOctet4(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    *(volatile UINT32 *)(dev->devAddr + pos) = *(UINT32 *)buf;
    }

/*******************************************************************************
*
* flashGetOctet8 - 
*
*/
static void flashGetOctet8(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    *(UINT64 *)buf = *(volatile UINT64 *)(dev->devAddr + pos);
    }

/*******************************************************************************
*
* flashSetOctet8 - 
*
*/
static void flashSetOctet8(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    *(volatile UINT64 *)(dev->devAddr + pos) = *(UINT64 *)buf;
    }

/*******************************************************************************
*
* flashPartIdentify - 
*
*/
static void flashPartIdentify(FLASH_DEV *dev, FLASH_PART *unitPart, int partCnt)
    {
    FLASH_PART *part, *devPart;
    FLASH_UNIT *unit = &flashUnit[dev->unitNo];
    UINT32 keyPos = unit->unitSize;
    UINT32 partPos = 0;
    UINT32 partCount = 0;
    int i;

    devPart = (FLASH_PART *)malloc(sizeof(FLASH_PART) * partCnt);
    if (devPart == NULL)
        {
        printf("malloc error!\n");
        return;
        }
    dev->devPart = devPart;
    part = unitPart;

    for (i = 0; i < partCnt; i++, part++)
        {
        partPos += dev->bankCount * part->blockSize * part->blockCount;
        if (partPos <= unit->unitSize)
            continue;

        if (dev->devSize + unit->unitSize <= partPos)
            {
            devPart->blockSize = part->blockSize;
            devPart->blockCount = (dev->devSize + unit->unitSize - keyPos) /
                                  (dev->bankCount * part->blockSize);
            dev->partCount = partCount + 1;
            unit->unitSize += dev->devSize;
            break;
            }

        devPart->blockSize = part->blockSize;
        devPart->blockCount = (partPos - keyPos) / (dev->bankCount * part->blockSize);
        devPart++;
        partCount++;
        keyPos = partPos;
        }
    }

/*******************************************************************************
*
* amdFlashReset - 
*
*/
static void amdFlashReset(FLASH_DEV *dev)
    {
    /*
    (*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
    (*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
    (*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[7]);
    */
    (*dev->set)(dev, 0x0, (char *)&amdFlashCmd[7]);
    }

/*******************************************************************************
*
* amdFlashProbe - 
*
*/
static STATUS amdFlashProbe(FLASH_DEV *dev)
    {
    FLASH_UNIT *unit = &flashUnit[dev->unitNo];
    FLASH_PHY *phy = flashPhy;
    UINT8 offset = dev->portSize > 1 ? 0 : 1;

    if (unit->inited && !unit->phy->isAmdType)
        return ERROR;

    if (!unit->inited)
        {
        unit->unitAddr = dev->devAddr;

        memset(&tempID, 0, sizeof(tempID));
        memset(&buffID, 0, sizeof(buffID));

        flashCmdRawSet(dev, 0x5555, (char *)&amdFlashCmd[0]);
        flashCmdRawSet(dev, 0x2AAA, (char *)&amdFlashCmd[1]);
        flashCmdRawSet(dev, 0x5555, (char *)&amdFlashCmd[6]);

        taskDelay(1);

        flashCfgRawGet(dev, 0x0, (char *)&tempID.vendorID);
        flashCfgRawGet(dev, 0x1, (char *)&tempID.deviceID);
        flashCfgRawGet(dev, 0xE, (char *)&tempID.subdevID1);
        flashCfgRawGet(dev, 0xF, (char *)&tempID.subdevID2);

        flashCmdRawSet(dev, 0x0, (char *)&amdFlashCmd[7]);

        if (*(char *)&tempID.vendorID != (char)0xFF)
            buffID = tempID;

        do
            {
            if ((memcmp((char *)&tempID.vendorID, (char *)&phy->flashID->vendorID + offset, dev->portSize) == OK) &&
                (memcmp((char *)&tempID.deviceID, (char *)&phy->flashID->deviceID + offset, dev->portSize) == OK) &&
                phy->isAmdType)
                {
                if ((phy->flashID->subdevID1 == (UINT64)0x0) ||
                    ((memcmp((char *)&tempID.subdevID1, (char *)&phy->flashID->subdevID1 + offset, dev->portSize) == OK) &&
                     (memcmp((char *)&tempID.subdevID2, (char *)&phy->flashID->subdevID2 + offset, dev->portSize) == OK)))
                    {
                    unit->phy = phy;
                    unit->inited = 1;
                    break;
                    }
                }
            phy++;
            } while (phy->flashID != (FLASH_ID *)-1);

        if (!unit->inited)
            return ERROR;
        }

    flashPartIdentify(dev, unit->phy->flashPart, unit->phy->partCount);

    unit->devCount++;

    switch (dev->portSize)
        {
    case 8:
        dev->get = flashGetOctet8;
        dev->set = flashSetOctet8;
        break;

    case 4:
        dev->get = flashGetOctet4;
        dev->set = flashSetOctet4;
        break;

    case 2:
        dev->get = flashGetOctet2;
        dev->set = flashSetOctet2;
        break;

    case 1:
        dev->get = flashGetOctet1;
        dev->set = flashSetOctet1;
        break;

    default:
        return ERROR;
        }

    if (dev->writeBufMod && unit->phy->writeBufMod)
        dev->write = amdFlashBWrite;
    else
        {
        dev->write = amdFlashWrite;
        dev->writeBufMod = 0;
        }

    dev->erase = amdFlashErase;

    if (!unit->unitSem)
        {
        unit->unitSem = semBCreate(SEM_Q_FIFO, SEM_FULL);
        if (unit->unitSem == NULL)
            return ERROR;
        }
    dev->devSem = unit->unitSem;

    dev->unit = unit;

    dev->inited = 1;

    return OK;
    }

/*******************************************************************************
*
* amdFlashErase - 
*
*/
static STATUS amdFlashErase(FLASH_DEV *dev, UINT32 pos)
    {
    UINT8 temp[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    (*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
    (*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
    (*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[3]);
    (*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
    (*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
    (*dev->set)(dev, pos, (char *)&amdFlashCmd[4]);

    return amdFlashCheck(dev, pos, temp, FLASH_POLL_ERASE);
    }

/*******************************************************************************
*
* amdFlashWrite - 
*
*/
static STATUS amdFlashWrite(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    (*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
    (*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
    (*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[2]);
    (*dev->set)(dev, pos, buf);

    return amdFlashCheck(dev, pos, buf, FLASH_POLL_WRITE);
    }

/*******************************************************************************
*
* amdFlashBWrite - 
*
*/
static STATUS amdFlashBWrite(FLASH_DEV *dev, UINT32 pos, char *buf)
    {
    UINT32 curPos = pos;
    char *tempBuf = buf;
    int intLevel;
    UINT32 i;

    (*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
    (*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
    (*dev->set)(dev, pos, (char *)&amdFlashCmd[8]);
    if (dev->portSize != 1)
        (*dev->set)(dev, pos, (char *)&amdFlashCmd[9]);
    else
        (*dev->set)(dev, pos, (char *)&amdFlashCmd[10]);

    intLevel = intLock();
    for (i = 0; i < WRITE_BUF_SIZE * dev->bankCount / dev->portSize; i++)
        {
        (*dev->set)(dev, curPos, tempBuf);
        curPos += dev->portSize;
        tempBuf += dev->portSize;
        }
    intUnlock(intLevel);

    (*dev->set)(dev, pos, (char *)&amdFlashCmd[11]);

    return amdFlashCheck(dev, pos, buf, FLASH_POLL_WRITE);
    }

/*******************************************************************************
*
* amdFlashCheck - 
*
*/
static STATUS amdFlashCheck(FLASH_DEV *dev, UINT32 pos, char *buf, int option)
    {
    UINT32 curPos = pos;
    char *tempBuf = buf;
    char stat[8];
    UINT32 dataSize;
    UINT32 polls;
    UINT32 i, j;

    if (option == FLASH_POLL_ERASE)
        {
        polls = FLASH_ERASE_TIMEOUT;
        dataSize = dev->portSize;
        }
    else
        {
        polls = FLASH_WRITE_TIMEOUT;
        dataSize = dev->writeBufMod ? WRITE_BUF_SIZE * dev->bankCount : dev->portSize;
        }

    for (i = 0; i < polls; i++)
        {
        if (option == FLASH_POLL_ERASE)
            {
            taskDelay(1);
            }

        SYS_FLASH_TIMER_RESET();

        curPos = pos;
        tempBuf = buf;
        for (j = 0; j < dataSize; j += dev->portSize)
            {
            (*dev->get)(dev, curPos, stat);
            if (memcmp(stat, tempBuf, dev->portSize) != OK)

⌨️ 快捷键说明

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