📄 msf.uc
字号:
// MSF address map.
#define MSF_Rx_Control 0x0000
#define Rx_Thread_Freelist_0 0x0030
#define Rx_Port_Map 0x0040
#define RBUF_Element_Done 0x0044
#define Rx_Thread_Freelist_Timeout_0 0x0050
#define Rx_Up_Control_0 0x0080
//----------------------------------------------------------------------
// _msf_init()
//
// Description: Initialize MSF settings to enable packet reception.
//
// Parameters:
// Outputs:
// out_freelist_gpr:
// Register that contains information to add the thread to a
// freelist after it is done processing a received packet.
//
//----------------------------------------------------------------------
#macro _msf_init(out_freelist_gpr)
.begin
.reg $msf_data msf_data
.reg msf_addr
.sig msf_sig
// For details on each bit setting, refer to the MSF documentation (in the PRM).
// 1. Initialize MSF_Rx_Control.
#ifdef IXP2400
immed[$msf_data, 0x0]
immed[msf_addr, MSF_Rx_Control]
msf[write, $msf_data, 0, msf_addr, 1], ctx_swap[msf_sig]
#endif // IXP2400
// 2. Initialize Rx_Thread_Freelist_Timeout_0.
// Each thread waits the specified bus clock cycles for a packet
// before returning a null packet status.
immed[$msf_data, 1024]
immed[msf_addr, Rx_Thread_Freelist_Timeout_0]
msf[write, $msf_data, 0, msf_addr, 1], ctx_swap[msf_sig]
// 3. Free all available RBUF elements - we have (8192/64)=128 elements.
#ifdef IXP2400
immed[msf_addr, RBUF_Element_Done]
.reg rbuf_ele
immed[rbuf_ele, 0]
.while (rbuf_ele < 128)
// For msf[fast_wr] the most significant 16 bits contain data
// and least signification 16 bits contain the address.
alu[msf_data, --, b, rbuf_ele, <<16]
msf[fast_wr, --, msf_data, msf_addr]
alu[rbuf_ele, rbuf_ele, +, 1]
.endw
#endif // IXP2400
// 4. Initialize Rx_UP_Control_0.
#ifdef IXP2400
immed[$msf_data, 0x39]
immed[msf_addr, Rx_Up_Control_0]
msf[write, $msf_data, 0, msf_addr, 1], ctx_swap[msf_sig]
#endif // IXP2400
// 5. Configure Rx_Thread_Freelist_0
// Add current thread of the current ME to the list of threads
// available to receive packets.
// Get current thread and current ME.
.reg thread_me_num
local_csr_rd[active_ctx_sts]
immed[thread_me_num,0]
.reg thread_num
alu[thread_num, 0x7, and, thread_me_num]
#ifdef IXP2400
.reg cluster_num
alu[cluster_num, 0x1, and, thread_me_num, >>7]
.reg me_num
alu[me_num, 0x3, and, thread_me_num, >>3]
alu[me_num, cluster_num, +, me_num]
#endif // IXP2400
#ifdef IXP2800
.reg me_num
alu[me_num, 0x1f, and, thread_me_num, >>3]
#endif // IXP2800
alu[msf_data, --, b, &pkt_rx_sig, <<12]
alu[msf_data, msf_data, or, me_num, <<7]
alu[msf_data, msf_data, or, thread_num, <<4]
alu[msf_data, msf_data, or, &$rsw0]
alu[msf_data, --, b, msf_data, <<16]
immed[msf_addr, Rx_Thread_Freelist_0];
msf[fast_wr, --, msf_data, msf_addr]
alu[out_freelist_gpr, --, b, msf_data]
// 6. Configure RX_PORT_MAP
#ifdef IXP2800
alu[$msf_data, --, b, 0xff]
immed[msf_addr, Rx_Port_Map];
msf[write, $msf_data, 0, msf_addr, 1], ctx_swap[msf_sig]
#endif // IXP2800
// 7. Enable MSF_Rx_Control - allow packets to be received.
#ifdef IXP2400
immed[$msf_data, 0x1000, <<16]
#endif // IXP2400
#ifdef IXP2800
immed[$msf_data, 0x4000, <<16]
#endif // IXP2800
immed[msf_addr, MSF_Rx_Control]
msf[write, $msf_data, 0, msf_addr, 1], ctx_swap[msf_sig]
.end
#endm
//----------------------------------------------------------------------
// _msf_reset()
//
// Description: Frees resources used while processing the packet.
//
// Parameters:
// Inputs:
// in_rbuf_ele:
// RBUF element number to free.
// in_freelist_gpr:
// Register that contains information to add the thread to a
// freelist after it is done processing a received packet.
//
//----------------------------------------------------------------------
#macro _msf_reset(in_rbuf_ele, in_freelist_gpr)
.begin
// Free RBUF element.
alu[in_rbuf_ele, --, b, in_rbuf_ele, <<16]
msf[fast_wr, --, in_rbuf_ele, RBUF_Element_Done]
// Add thread to freelist.
msf[fast_wr, --, in_freelist_gpr, Rx_Thread_Freelist_0]
.end
#endm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -