📄 swsram.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 + -