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

📄 swsram.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 C
字号:
/*
 * 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:    swsram.c
 *
 * Purpose: ASIC embedded SRAM hardware accessing functions
 *
 * Author:  Tevin Chen
 *          Henry Lin
 *
 * Date:    Jan 08, 2002
 *          May 26, 2005
 *
 * Functions:
 *
 * Revision History:
 *
 */

#if !defined(__MACRO_H__)
#include "macro.h"
#endif
#if !defined(__PLATFORM_H__)
#include "platform.h"
#endif
#if !defined(__SWITCH_H__)
#include "switch.h"
#endif
#if !defined(__SWREG_H__)
#include "swreg.h"
#endif
#if !defined(__SWSRAM_H__)
#include "swsram.h"
#endif




/*---------------------  Static Definitions  ------------------------*/

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

/*---------------------  Static Macros  -----------------------------*/

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

/*---------------------  Static Variables  --------------------------*/

/*---------------------  Static Functions  --------------------------*/
static BOOL s_bReadCommand(UINT32 u32Addr);
static BOOL s_bWriteCommand(UINT32 u32Addr);

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




static BOOL s_bReadCommand (UINT32 u32Addr)
{

    // Set sram address
    SWREG_vWriteU32(CPUIF_MEM_ADDR, u32Addr);
    // Wait for sram idle and issue read command
    if (!SWREG_bWaitStatus(CPUIF_MEM_STATUS, MEM_STATUS_BUSY, FALSE))
        return FALSE;

    // Trigger read
    SWREG_vBitsOnU8(CPUIF_MEM_CMD, MEM_CMD_READ);
    // Wait for sram reading done
    if (!SWREG_bWaitStatus(CPUIF_MEM_STATUS, MEM_STATUS_BUSY, FALSE))
        return FALSE;

    // Check command successful or failing
    if (SWREG_bIsBitsOnU8(CPUIF_MEM_STATUS, MEM_STATUS_FAIL))
        return FALSE;

    return TRUE;
}


static BOOL s_bWriteCommand (UINT32 u32Addr)
{

    // Set sram address
    SWREG_vWriteU32(CPUIF_MEM_ADDR, u32Addr);
    // Set byte enables
    SWREG_vWriteU16(CPUIF_WR_BYTE_EN, WR_BYTE_EN_ALL_BITS);
    // Wait for sram idle and issue write command
    if (!SWREG_bWaitStatus(CPUIF_MEM_STATUS, MEM_STATUS_BUSY, FALSE))
        return FALSE;

    // Trigger write operation
    SWREG_vBitsOnU8(CPUIF_MEM_CMD, MEM_CMD_WRITE);
    // Wait for sram writing done
    if (!SWREG_bWaitStatus(CPUIF_MEM_STATUS, MEM_STATUS_BUSY, FALSE))
        return FALSE;

    // Check command successful or failing
    if (SWREG_bIsBitsOnU8(CPUIF_MEM_STATUS, MEM_STATUS_FAIL))
        return FALSE;

    return TRUE;
}


BOOL SWSRAM_bReadEntry (UINT32 u32Addr, PUINT8 au8Data)
{
#if defined(__BIG_ENDIAN)
    UINT    uu;
#endif


    // protect sram data reg from being ruined before using it
    PLAT_vCpuCriticalEnter();

    if (!s_bReadCommand(u32Addr)) {
        PLAT_vCpuCriticalExit();
        return FALSE;
    }

    //
    // Read sram data
    //
    // If 32 bits width memory
    if ((u32Addr >= SRAM_SGMNT_LNK_BASE_ADDR && u32Addr <= SRAM_SGMNT_LNK_END_ADDR) ||
        (u32Addr >= SRAM_PTMSK_TBL_BASE_ADDR && u32Addr <= SRAM_MCAST_CNTR_TBL_END_ADDR)) {
        SWREG_vReadU32(CPUIF_MEM_DATA0, (PUINT32)au8Data);
#if defined(__BIG_ENDIAN)
        SWSRAM_vEndianConvert(au8Data, SRAM_ENTRY_SIZE_4Byte);
#endif
    }
    // If 64 bits width memory
    else if ((u32Addr >= SRAM_RULE_ACT_CODE_BASE_ADDR && u32Addr <= SRAM_SECOND_MAC_TBL_END_ADDR)) {
        SWREG_vReadU64(CPUIF_MEM_DATA0, au8Data);
#if defined(__BIG_ENDIAN)
        for (uu = 0; uu < 2; uu++)
            SWSRAM_vEndianConvert(au8Data + (uu * 4), SRAM_ENTRY_SIZE_4Byte);
#endif
    }
    // If 128 bits width memory
    else {
        SWREG_vReadU128(CPUIF_MEM_DATA0, au8Data);
#if defined(__BIG_ENDIAN)
        for (uu = 0; uu < 4; uu++)
            SWSRAM_vEndianConvert(au8Data + (uu * 4), SRAM_ENTRY_SIZE_4Byte);
#endif
    }

    PLAT_vCpuCriticalExit();

    return TRUE;
}


BOOL SWSRAM_bWriteEntry (UINT32 u32Addr, PUINT8 au8Data)
{
#if defined(__BIG_ENDIAN)
    UINT    uu;
#endif

    // protect sram data reg from being ruined before using it
    PLAT_vCpuCriticalEnter();

    //
    // Write sram data
    //
    // If 32 bits width memory
    if ((u32Addr >= SRAM_SGMNT_LNK_BASE_ADDR && u32Addr <= SRAM_SGMNT_LNK_END_ADDR) ||
         (u32Addr >= SRAM_PTMSK_TBL_BASE_ADDR && u32Addr <= SRAM_MCAST_CNTR_TBL_END_ADDR) ) {
#if defined(__BIG_ENDIAN)
        SWSRAM_vEndianConvert(au8Data, SRAM_ENTRY_SIZE_4Byte);
#endif
        SWREG_vWriteU32(CPUIF_MEM_DATA0, *((PUINT32)au8Data));
    }
    // If 64 bits width memory
    else if ((u32Addr >= SRAM_RULE_ACT_CODE_BASE_ADDR && u32Addr <= SRAM_SECOND_MAC_TBL_END_ADDR) ) {
#if defined(__BIG_ENDIAN)
        for (uu = 0; uu < 2; uu++)
            SWSRAM_vEndianConvert(au8Data + (uu * 4), SRAM_ENTRY_SIZE_4Byte);
#endif
        SWREG_vWriteU64(CPUIF_MEM_DATA0, au8Data);
    }
    // If 128 bits width memory
    else {
#if defined(__BIG_ENDIAN)
        for (uu = 0; uu < 4; uu++)
            SWSRAM_vEndianConvert(au8Data + (uu * 4), SRAM_ENTRY_SIZE_4Byte);
#endif
        SWREG_vWriteU128(CPUIF_MEM_DATA0, au8Data);
    }

    if (!s_bWriteCommand(u32Addr)) {
        PLAT_vCpuCriticalExit();
        return FALSE;
    }

    PLAT_vCpuCriticalExit();

    return TRUE;
}


//only use for V3268 mib counter and PMAC.
void SWSRAM_vReadBlock(UINT32 u32Addr, UINT8 u8BlockNumPerSlot, UINT8 u8BlockId, PUINT8 au8BlockBuf)
{
    UINT8   au8EntryBuf[SRAM_ENTRY_MAX_SIZE];


    SWSRAM_bReadEntry(u32Addr, au8EntryBuf);

    SWSRAM_vExtractBits( au8EntryBuf,
                     (UINT8)((SRAM_ENTRY_MAX_BIT_NUM / u8BlockNumPerSlot) * u8BlockId),
                     (UINT8)((SRAM_ENTRY_MAX_BIT_NUM / u8BlockNumPerSlot) * (u8BlockId + 1) - 1),
                     au8BlockBuf );
}


//only use for V3268 mib counter and PMAC.
void SWSRAM_vWriteBlock(UINT32 u32Addr, UINT8 u8BlockNumPerSlot, UINT8 u8BlockId, PUINT8 au8ValueBuf)
{
    UINT8   au8EntryBuf[SRAM_ENTRY_MAX_SIZE];

    SWSRAM_bReadEntry(u32Addr, au8EntryBuf);
    SWSRAM_vModifyBits( au8EntryBuf,
                    (UINT8)((SRAM_ENTRY_MAX_BIT_NUM / u8BlockNumPerSlot) * u8BlockId),
                    (UINT8)((SRAM_ENTRY_MAX_BIT_NUM / u8BlockNumPerSlot) * (u8BlockId + 1) - 1),
                    au8ValueBuf );
    SWSRAM_bWriteEntry(u32Addr, au8EntryBuf);
}


//only use for V3268 mib counter and PMAC.
void SWSRAM_vSetBlockEmpty(UINT32 u32Addr, UINT8 u8BlockNumPerSlot, UINT8 u8BlockId)
{
    UINT8   au8EntryBuf[SRAM_ENTRY_MAX_SIZE], uu;

    for (uu = 0; uu < SRAM_ENTRY_MAX_SIZE; uu++)
        au8EntryBuf[uu] = 0;
    SWSRAM_vWriteBlock(u32Addr, u8BlockNumPerSlot, u8BlockId, au8EntryBuf);
}


//only use for V3268 mib counter and PMAC.
BOOL SWSRAM_bIsBlockEmpty(UINT32 u32Addr, UINT8 u8BlockNumPerSlot, UINT8 u8BlockId)
{
    UINT8   au8EntryBuf[SRAM_ENTRY_MAX_SIZE], uu;

    SWSRAM_vReadBlock(u32Addr, u8BlockNumPerSlot, u8BlockId, au8EntryBuf);
    for (uu = 0; uu < (SRAM_ENTRY_MAX_SIZE / u8BlockNumPerSlot); uu++) {
        if (au8EntryBuf[uu] != 0)
            return FALSE;
    }
    return TRUE;
}


void SWSRAM_vSetMemEntryEmpty(UINT32 u32Addr)
{
    UINT8   au8EntryBuf[SRAM_ENTRY_MAX_SIZE], uu;


    for (uu = 0; uu < SRAM_ENTRY_MAX_SIZE; uu++)
        au8EntryBuf[uu] = 0;

    SWSRAM_bWriteEntry(u32Addr, au8EntryBuf);
}


BOOL SWSRAM_bIsMemEntryEmpty(UINT32 u32Addr)
{
    UINT8   au8EntryBuf[SRAM_ENTRY_SIZE_16Byte], uu;


    // read entry
    SWSRAM_bReadEntry(u32Addr, au8EntryBuf);

    // If 32 bits width memory
    if ((u32Addr >= SRAM_SGMNT_LNK_BASE_ADDR && u32Addr <= SRAM_SGMNT_LNK_END_ADDR) ||
         (u32Addr >= SRAM_PTMSK_TBL_BASE_ADDR && u32Addr <= SRAM_MCAST_CNTR_TBL_END_ADDR) )
    {
        for (uu = 0; uu < SRAM_ENTRY_SIZE_4Byte; uu++)
            if (au8EntryBuf[uu] != 0)
                return FALSE;
    }
    // If 64 bits width memory
    else if ((u32Addr >= SRAM_RULE_ACT_CODE_BASE_ADDR && u32Addr <= SRAM_SECOND_MAC_TBL_END_ADDR) )
    {
        for (uu = 0; uu < SRAM_ENTRY_SIZE_8Byte; uu++)
            if (au8EntryBuf[uu] != 0)
                return FALSE;
    }

    // If 128 bits width memory
    else {
        for (uu = 0; uu < SRAM_ENTRY_SIZE_16Byte; uu++)
            if (au8EntryBuf[uu] != 0)
                return FALSE;
    }

    return TRUE;
}



void SWSRAM_vExtractBits(PUINT8 au8Data, UINT8 u8StartBit, UINT8 u8EndBit, PUINT8 au8Result)
{
#if defined(__BIG_ENDIAN)
    UINT8   u8ByteCount;
#endif



    // Extract operation
    SWSRAM_vExtractBitsLtl(au8Data, u8StartBit, u8EndBit, au8Result);

#if defined(__BIG_ENDIAN)
    // Decide how many bytes to perform endian convertion, ceiling value
    u8ByteCount = (u8EndBit - u8StartBit + 1) / 8 + (((u8EndBit - u8StartBit + 1) % 8) != 0);
    // No 3 byte data type => must be double word
    if (u8ByteCount == 3)
        u8ByteCount = 4;

    // Swap au8Result for big-endian platforms
    SWSRAM_vEndianConvert(au8Result, u8ByteCount);
#endif
}


void SWSRAM_vModifyBits(PUINT8 au8DataBuf, UINT8 u8StartBit, UINT8 u8EndBit, PUINT8 au8ModiPtn)
{
#if defined(__BIG_ENDIAN)
    UINT8   u8ByteCount;



    // Decide how many bytes to perform endian convertion, ceiling value
    u8ByteCount = (u8EndBit - u8StartBit + 1) / 8 + (((u8EndBit - u8StartBit + 1) % 8) != 0);
    // No 3 byte data type => must be double word
    if (u8ByteCount == 3)
        u8ByteCount = 4;

    // Swap au8ModiPtn for big-endian platforms
    SWSRAM_vEndianConvert(au8ModiPtn, u8ByteCount);
#endif

    // Modify operation
    SWSRAM_vModifyBitsLtl(au8DataBuf, u8StartBit, u8EndBit, au8ModiPtn);

#if defined(__BIG_ENDIAN)
    // Swap back au8ModiPtn for big-endian platforms
    SWSRAM_vEndianConvert(au8ModiPtn, u8ByteCount);
#endif
}


void SWSRAM_vExtractBitsByBool (PUINT8 au8Data, UINT8 u8StartBit, UINT8 u8EndBit, PBOOL pbResult)
{
    UINT8   u8BoolValue;

    // Extract operation
    SWSRAM_vExtractBitsLtl(au8Data, u8StartBit, u8EndBit, &u8BoolValue);
    if (u8BoolValue != 0)
        *pbResult = TRUE;
    else
        *pbResult = FALSE;
}


void SWSRAM_vModifyBitsByBool (PUINT8 au8DataBuf, UINT8 u8StartBit, UINT8 u8EndBit, PBOOL pbModiPtn)
{
    UINT8   u8BoolValue;

    if (*pbModiPtn)
        u8BoolValue = 0x01;
    else
        u8BoolValue = 0;
    // Modify operation
    SWSRAM_vModifyBitsLtl(au8DataBuf, u8StartBit, u8EndBit, &u8BoolValue);
}


void SWSRAM_vExtractBitsLtl(PUINT8 au8Data, UINT8 u8StartBit, UINT8 u8EndBit, PUINT8 au8Result)
{
    UINT8   u8ByteCount;
    UINT8   uu, u8BitMask = 0xFF;



    // Decide how many bytes, ceiling value
    u8ByteCount = (u8EndBit - u8StartBit + 1) / 8 + (((u8EndBit - u8StartBit + 1) % 8) != 0);
    // Clear result buffer
    for (uu = 0; uu < u8ByteCount; uu++)
        au8Result[uu] = 0;

    uu = 0;
    while (1) {
        // Extract 8 succesive bits from StartBit to result
        au8Result[uu] = ( (au8Data[u8StartBit / 8 + 1] << (8 - u8StartBit % 8)) |
                          (au8Data[u8StartBit / 8]     >> (u8StartBit % 8))  );
        // Adjust bit pattern in highest byte
        if (u8EndBit - u8StartBit < 8) {
            u8BitMask >>= 8 - (u8EndBit - u8StartBit + 1);
            au8Result[uu] &= u8BitMask;
            break;
        }
        // Adjust start bit and array pointer
        u8StartBit += 8;
        uu++;
    }
}


void SWSRAM_vModifyBitsLtl(PUINT8 au8DataBuf, UINT8 u8StartBit, UINT8 u8EndBit, PUINT8 au8ModiPtn)
{
    UINT8   u8BitOffset, u8BufIndx, u8PtnIndx = 0, u8BitMask = 0xFF;



    // Initial config
    u8BufIndx = u8StartBit / 8;
    u8BitOffset = u8StartBit % 8;

    // Handle first byte of DataBuf
    if ((u8EndBit / 8) == (u8StartBit / 8)) {
        // Clear modified bits of data buffer
        au8DataBuf[u8BufIndx] &= ~( (u8BitMask >> (7 - u8EndBit + u8StartBit))
                                    << u8BitOffset);
        // Write modified pattern into data buffer
        au8DataBuf[u8BufIndx] |= ( (au8ModiPtn[u8PtnIndx] &
                                    (u8BitMask >> (7 - u8EndBit + u8StartBit)))
                                   << u8BitOffset );
        return;
    }
    else {
        // Clear modified bits of data buffer
        au8DataBuf[u8BufIndx] &= ~(u8BitMask << u8BitOffset);
        // Write modified pattern into data buffer
        au8DataBuf[u8BufIndx] |= (au8ModiPtn[u8PtnIndx] << u8BitOffset);
        // Adjust indexs
        u8StartBit += 8 - u8BitOffset;
        u8BufIndx++;
    }

    while (1) {
        // Check new byte position
        if (u8StartBit > u8EndBit) {
            return;
        }
        // Handle highest byte of DataBuf
        else if ((u8EndBit - u8StartBit) < 8) {
            // Clear modified bits of data buffer
            au8DataBuf[u8BufIndx] &= (u8BitMask << (u8EndBit % 8 + 1));
            // Write modified pattern into data buffer
            au8DataBuf[u8BufIndx] |= ( (au8ModiPtn[u8PtnIndx] >> (8 - u8BitOffset)) |
                                       (au8ModiPtn[u8PtnIndx + 1] << u8BitOffset) )
                                     & ~(u8BitMask << (u8EndBit % 8 + 1));
            return;
        }
        // Handle middle bytes of DataBuf
        else {
            // Clear modified bits of data buffer
            au8DataBuf[u8BufIndx] = 0;
            // Write modified pattern into data buffer
            au8DataBuf[u8BufIndx] |= ((au8ModiPtn[u8PtnIndx] >> (8 - u8BitOffset)) |
                                      (au8ModiPtn[u8PtnIndx + 1] << u8BitOffset));

            // Adjust start bit and byte index
            u8PtnIndx++;
            u8BufIndx++;
            u8StartBit += 8;
        }
    }
}


void SWSRAM_vEndianConvert (PUINT8 pu8DataBuf, UINT8 u8BufSize)
{
    UINT8   u8SwapTmp, uu;

    // u8BufSize must be even, cannot be odd
    for (uu = 0; uu < (u8BufSize / 2); uu++) {
        u8SwapTmp = pu8DataBuf[uu];
        pu8DataBuf[uu] = pu8DataBuf[u8BufSize - 1 - uu];
        pu8DataBuf[u8BufSize - 1 - uu] = u8SwapTmp;
    }
}


⌨️ 快捷键说明

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