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

📄 flash.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This software is copyrighted by and is the sole property of
 * VIA Networking Technologies, Inc. This software may only be used
 * in accordance with the corresponding license agreement. Any unauthorized
 * use, duplication, transmission, distribution, or disclosure of this
 * software is expressly forbidden.
 *
 * This software is provided by VIA Networking Technologies, Inc. "as is"
 * and any express or implied warranties, including, but not limited to, the
 * implied warranties of merchantability and fitness for a particular purpose
 * are disclaimed. In no event shall VIA Networking Technologies, Inc.
 * be liable for any direct, indirect, incidental, special, exemplary, or
 * consequential damages.
 *
 *
 * File:    flash.c
 *
 * Purpose: FLASH hardware accessing functions
 *
 * Author:  Tevin Chen
 *
 * Date:    Jan 08, 2002
 *
 * Functions:
 *
 * Revision History:
 *
 */


#if !defined(__KERNEL_H__)
#include "kernel.h"
#endif
#if !defined(__UASSERT_H__)
#include "uassert.h"
#endif
#if !defined(__MACRO_H__)
#include "macro.h"
#endif
#if !defined(__DEVICE_H__)
#include "device.h"
#endif
#if !defined(__STR_H__)
#include "str.h"
#endif
#if !defined(__SOC_H__)
#include "soc.h"
#endif
#if !defined(__FLASH_H__)
#include "flash.h"
#endif




/*---------------------  Static Definitions  ------------------------*/
#define DEBUG_FLSH          0

#if DEBUG_FLSH
#define DBG_PRN_FLSH        DBG_PRN
#else
#define DBG_PRN_FLSH(...)   FUNC_NULL()
#endif

#define FLSH_BUFFER_SIZE    0x00010000  // 64k bytes

#define SST_MANU_ID         0xBFD7      // manufacturerID(BF << 8) | deviceID(D7)
#define AMD_MANU_ID         0x01F9      // manufacturerID(01 << 8) | deviceID(F9)

/*---------------------  Static Types  ------------------------------*/

/*---------------------  Static Macros  -----------------------------*/
// host to flash short int (WORD) endian convert
#if defined(__BIG_ENDIAN) && (defined(__SWITCH_CPUIF_PCI) || defined(__CPU_S3C2510A))
#define htofs(n)            REV_WORD(n)
#else
#define htofs(n)            (n)
#endif

// flash to host short int (WORD) endian convert
#if defined(__BIG_ENDIAN) && (defined(__SWITCH_CPUIF_PCI) || defined(__CPU_S3C2510A))
#define ftohs(n)            REV_WORD(n)
#else
#define ftohs(n)            (n)
#endif

/*---------------------  Static Classes  ----------------------------*/

/*---------------------  Static Variables  --------------------------*/
static UINT8  sg_abyBuf[FLSH_BUFFER_SIZE];
static UINT16 sg_wFlshID;
static UINT32 sg_u32FlshBase;

/*---------------------  Static Functions  --------------------------*/
static UINT16 s_u16ReadAmdId(UINT32 u32Addr);
static UINT16 s_u16ReadSstId(UINT32 u32Addr);
static void s_vConfigFlshIdAndBase(UINT32 u32Addr);
static void s_vEraseSect(UINT32 u32SectAddr);
static void s_vProgramSect(UINT32 u32SectAddr, UINT32 u32SectSize, BOOL bEndianConvt);
static BOOL s_bVerifyBlock(UINT32 u32Addr, PUINT8 pu8Data, UINT32 u32BlockSize, BOOL bEndianConvt);

/*---------------------  Export Variables  --------------------------*/




BOOL FLSH_bReadU8(UINT32 u32Addr, PUINT8 pu8Data)
{
    u32Addr |= ASIC_NON_CACHE_ADDR;          // For non-cache access
    *pu8Data = *(PUINT8)u32Addr;
    return TRUE;
}


BOOL FLSH_bWriteU8(UINT32 u32Addr, UINT8 u8Data)
{
    FLSH_bWriteBlock(u32Addr, &u8Data, 1, FALSE);
    return s_bVerifyBlock(u32Addr, &u8Data, 1, FALSE);
}


BOOL FLSH_bReadU16(UINT32 u32Addr, PUINT16 pu16Data)
{
    u32Addr |= ASIC_NON_CACHE_ADDR;          // For non-cache access
    *pu16Data = *(PUINT16)u32Addr;
    return TRUE;
}


BOOL FLSH_bWriteU16(UINT32 u32Addr, UINT16 u16Data)
{
    FLSH_bWriteBlock(u32Addr, (PUINT8)&u16Data, 2, FALSE);
    return s_bVerifyBlock(u32Addr, (PUINT8)&u16Data, 2, FALSE);
}


BOOL FLSH_bReadU32(UINT32 u32Addr, PUINT32 pu32Data)
{
    u32Addr |= ASIC_NON_CACHE_ADDR;          // For non-cache access
    *pu32Data = *(PUINT32)u32Addr;
    return TRUE;
}


BOOL FLSH_bWriteU32(UINT32 u32Addr, UINT32 u32Data)
{
    FLSH_bWriteBlock(u32Addr, (PUINT8)&u32Data, 4, FALSE);
    return s_bVerifyBlock(u32Addr, (PUINT8)&u32Data, 4, FALSE);
}


BOOL FLSH_bReadBlock (UINT32 u32Addr, PUINT8 pu8Data, UINT32 u32BlockSize)
{
    UINT32  u32Idx;

    for (u32Idx = 0; u32Idx < u32BlockSize; u32Idx++)
        FLSH_bReadU8(u32Addr + u32Idx, pu8Data + u32Idx);

    return TRUE;
}


BOOL FLSH_bWriteBlock (UINT32 u32Addr, PUINT8 pu8Data, UINT32 u32BlockSize, BOOL bEndianConvt)
{
    UINT32  u32CurSector = 0, u32CurIndex = 0, u32Rest = u32BlockSize;
    UINT32  u32SectSize, u32SecOffset;
    PUINT8  pu8OrgData = pu8Data;



    u32Addr |= ASIC_NON_CACHE_ADDR;          // For non-cache access

    // Read info to distinguish SST or AMD flash
    s_vConfigFlshIdAndBase(u32Addr);
    u32SecOffset = u32Addr - sg_u32FlshBase;

    if (sg_wFlshID == AMD_MANU_ID) {
        UINT8 bySectorNo;

        if ((u32SecOffset & 0xFFFF0000) == 0) {
            // sector 0~7, size is 8k bytes
            bySectorNo = (u32SecOffset & 0xE000) >> 13;
            u32CurSector = sg_u32FlshBase + (u32SecOffset & 0xE000);
            u32CurIndex = u32SecOffset & 0x1FFF;
        }
        else {
            // sector 8~70, size is 64k bytes
            bySectorNo = ((u32SecOffset & 0xFFFF0000) >> 16) + 7;
            u32CurSector = sg_u32FlshBase + (u32SecOffset & 0xFFFF0000);
            u32CurIndex = u32SecOffset & 0xFFFF;
        }

        do {
            if (bySectorNo < 8)
                u32SectSize = 0x2000;   // 8k bytes
            else
                u32SectSize = 0x10000;  // 64k bytes

            // Backup current sector to buffer
            FLSH_bReadBlock(u32CurSector, sg_abyBuf, u32SectSize);
            // Modify buffer
            u32SecOffset = (u32Rest <= (u32SectSize - u32CurIndex)) ? u32Rest : (u32SectSize - u32CurIndex);
            STR_pvMemcpy(sg_abyBuf + u32CurIndex, pu8OrgData, u32SecOffset);

            // protect flash erase/program address sequence from being interrupted
            INTR_vCriticalSectionEnter();
            s_vEraseSect(u32CurSector);                         //1. Erase the sector
            s_vProgramSect(u32CurSector, u32SectSize, bEndianConvt);    //2. Program the sector
            INTR_vCriticalSectionLeave();

            u32CurSector += u32SectSize;                        // The next sector address
            u32CurIndex = 0;                                    // Reset index to 0
            u32Rest -= u32SecOffset;                            // Sub. the writed block
            pu8OrgData += u32SecOffset;
            bySectorNo++;
        } while (u32Rest > 0);                                  // If u32Rest>0, continue write the next sector
    }
    else if (sg_wFlshID == SST_MANU_ID) {
        // account current sector and index
        u32CurSector = (sg_u32FlshBase | (u32SecOffset & 0x0FF000));
        u32CurIndex  = (u32SecOffset & 0x000FFF);
        u32SectSize  = 0x1000;          // 4k bytes

        do {
            // Backup current sector to buffer
            STR_pvMemset(sg_abyBuf, 0, u32SectSize);
            FLSH_bReadBlock(u32CurSector, sg_abyBuf, u32SectSize);
            // Modify buffer
            u32SecOffset = (u32Rest <= (u32SectSize - u32CurIndex)) ? u32Rest : (u32SectSize - u32CurIndex);
            STR_pvMemcpy(sg_abyBuf + u32CurIndex, pu8OrgData, u32SecOffset);

            // protect flash erase/program address sequence from being interrupted
            INTR_vCriticalSectionEnter();
            s_vEraseSect(u32CurSector);                         //1. Erase the sector
            s_vProgramSect(u32CurSector, u32SectSize, FALSE);   //2. Program the sector
            INTR_vCriticalSectionLeave();

            u32CurSector += u32SectSize;                        // The next sector address
            u32CurIndex = 0;                                    // Reset index to 0
            u32Rest -= u32SecOffset;                            // Sub. the writed block
            pu8OrgData += u32SecOffset;
        } while (u32Rest > 0);                                  // If u32Rest>0, continue write the next sector
    }


    if (sg_wFlshID == AMD_MANU_ID)
        return s_bVerifyBlock(u32Addr, pu8Data, u32BlockSize, bEndianConvt);
    else
        return s_bVerifyBlock(u32Addr, pu8Data, u32BlockSize, FALSE);
}


static UINT16 s_u16ReadAmdId (UINT32 u32Addr)
{
    volatile UINT16 *pu16OpA, *pu16OpB, *pu16OpC;
    UINT16  u16FlshID;
    UINT16  u16Tmp;


    u32Addr |= ASIC_NON_CACHE_ADDR;          // For non-cache access
    u16FlshID = 0;

    // AMD read manufacturer id procedure
    pu16OpA = (PUINT16)((u32Addr & 0xFFFF0000) | (0x555 << 1));
    pu16OpB = (PUINT16)((u32Addr & 0xFFFF0000) | (0x2AA << 1));
    pu16OpC = (PUINT16)(u32Addr & 0xFFFFFF00);

    // protect flash erase/program address sequence from being interrupted
    INTR_vCriticalSectionEnter();

    // enter autoselect mode
    *pu16OpA = htofs(0x00AA);
    *pu16OpB = htofs(0x0055);
    *pu16OpA = htofs(0x0090);

    // read manufacturer id

⌨️ 快捷键说明

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