📄 pl_media_loopback_tx.uc
字号:
/* pl_media_loopback_tx.uc
*
* This file transmits a POS packet which is stored in DRAM by the XScale.
* Once it has completed transmitting the packet, it signals the XScale by
* writing to the Mailbox register indicating that it has transmitted a
* packet.
*---------------------------------------------------------------------------
*
* I N T E L P R O P R I E T A R Y
*
* COPYRIGHT (c) 2002 BY INTEL CORPORATION. ALL RIGHTS
* RESERVED. NO PART OF THIS PROGRAM OR PUBLICATION MAY
* BE REPRODUCED, TRANSMITTED, TRANSCRIBED, STORED IN A
* RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER
* LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,
* MAGNETIC, OPTICAL, CHEMICAL, MANUAL, OR OTHERWISE, WITHOUT
* THE PRIOR WRITTEN PERMISSION OF :
*
* INTEL CORPORATION
*
* 2200 MISSION COLLEGE BLVD
*
* SANTA CLARA, CALIFORNIA 95052-8119
*
*---------------------------------------------------------------------------
*
*
* system: IXDP2400
* subsystem: DIAG
* author: dalsraja, April, 2002
* revisions: dalsraja, May 8, 2002
*
*
* --------------------------------------------------------------------------
*/
#include "common_uc.h"
#define_eval UP_CTRL_PARITY (MSF_PARITY_ODD << 2)
#define TX_ELEMENT_SIZE MSF_ELEMENTSIZE_128
#define TX_ENABLE_MASK 0xF
#define TX_MODE MSF_POS_UTOPIA
#define TX_WIDTH MSF_WIDTH_4x8
#define TX_SINGLE_PHY MSF_SINGLE_PHY
#define TBUF_ELEM_COUNT (1 << (7 - TX_ELEMENT_SIZE))
#define TBUF_ADDR_SHF (6 + TX_ELEMENT_SIZE)
#define TX_ELEMENTSIZE_BYTE (1 << TBUF_ADDR_SHF)
#define TBUF_ELEM_COUNT_4PORT (TBUF_ELEM_COUNT >> 2)
#define TBUF_ELEM_COUNT_4PORT_MASK (TBUF_ELEM_COUNT_4PORT - 1)
#define TX_CONTROL_EOP (1 << 8)
#define TX_CONTROL_SOP (1 << 9)
#define INTERTHD_SIG_NUM 15
#ifdef WORKBENCH_SIM
#define POS_PAYLOAD_LENGTH 288
#define DRAM_BASE_SRC 0x1000000
#endif
.reg MsfAddress MsfAddress0 MsfAddress1
.reg pci_base get_ring_num put_ring_num @packet_count
.reg port_count
.reg byte_count cur_ctx bytes_sent total_bytes sopeop
.reg TxConfigData0 TxSequenceAddr
.reg $TxConfigData0
.reg $TxControlWord0 $TxControlWord1
.reg tbuf_element tbuf_1st_element tbuf_mask
.reg dram_addr tbuf
.sig dram_sig msf_sig interthd_sig
.xfer_order $TxControlWord0 $TxControlWord1
.addr interthd_sig INTERTHD_SIG_NUM
.set_sig interthd_sig
Init_Value#:
br=ctx[0, init_all#]
br=ctx[1, init_all#]
br=ctx[2, init_all#]
br=ctx[3, init_all#]
ctx_arb[kill]
init_all#:
.local temp
local_csr_rd[ACTIVE_CTX_STS]
immed[temp, 0]
alu[cur_ctx, MASK_3BIT, AND, temp] // Extract the current context number
.endlocal
immed[tbuf, RBUF_TBUF]
immed[tbuf_mask, ((TBUF_ELEM_COUNT >> 2) - 1)]
immed[@packet_count, 0]
immed[port_count, 0]
alu[tbuf_1st_element, --, B, cur_ctx, <<4]
alu[get_ring_num , --, B, cur_ctx, <<2]
alu[put_ring_num , --, B, RING_4, <<2]
.if (cur_ctx == 0)
immed[TxSequenceAddr, TX_SEQUENCE_0]
.elif (cur_ctx == 1)
immed[TxSequenceAddr, TX_SEQUENCE_1]
.elif (cur_ctx == 2)
immed[TxSequenceAddr, TX_SEQUENCE_2]
.else
immed[TxSequenceAddr, TX_SEQUENCE_3]
.endif
.if (cur_ctx > 0)
ctx_arb[interthd_sig]
br[start#]
.endif
//****************************************************
// Configure TX Control
//****************************************************
immed[MsfAddress, MSF_TX_CONTROL]
immed[TxConfigData0, (TX_ELEMENT_SIZE << 2)] // put control and data into diff freelist
immed_w1[TxConfigData0, ((TX_ENABLE_MASK << 8) | (TX_MODE << 6) | (TX_WIDTH << 4) | (TX_SINGLE_PHY << 3) | (0<<1)|(0<<0))]
alu[$TxConfigData0, --, B, TxConfigData0]
msf[write, $TxConfigData0, MsfAddress, 0, 1], ctx_swap[msf_sig]
//****************************************************
// Configure TX_UP_Control_# (# = 0 - 3)
//****************************************************
immed[TxConfigData0, (UP_CTRL_CP_MODE | UP_CTRL_PARITY | UP_CTRL_CELLSIZE | UP_CTRL_DRTIME)]
alu[$TxConfigData0, --, B, TxConfigData0]
immed[MsfAddress, TX_UP_CONTROL_0]
msf[write, $TxConfigData0, MsfAddress, 0, 1], ctx_swap[msf_sig]
immed[MsfAddress, TX_UP_CONTROL_1]
msf[write, $TxConfigData0, MsfAddress, 0, 1], ctx_swap[msf_sig]
immed[MsfAddress, TX_UP_CONTROL_2]
msf[write, $TxConfigData0, MsfAddress, 0, 1], ctx_swap[msf_sig]
immed[MsfAddress, TX_UP_CONTROL_3]
msf[write, $TxConfigData0, MsfAddress, 0, 1], ctx_swap[msf_sig]
//****************************************************
// Configure TX Control
//****************************************************
immed[MsfAddress, MSF_TX_CONTROL]
immed[TxConfigData0, (TX_ELEMENT_SIZE << 2)] // put control and data into diff freelist
immed_w1[TxConfigData0, ((TX_ENABLE_MASK << 12) | (TX_ENABLE_MASK << 8) | (TX_MODE << 6) | (TX_WIDTH << 4) | (TX_SINGLE_PHY << 3) | (0<<1)|(0<<0))]
alu[$TxConfigData0, --, B, TxConfigData0]
msf[write, $TxConfigData0, MsfAddress, 0, 1], ctx_swap[msf_sig]
//**************************************************
// Configure Scratch Ring
//**************************************************
.begin
.reg $scratch_base $scratch_head $scratch_tail
.sig scratch_sig1 scratch_sig2 scratch_sig3
immed[$scratch_head,0]
immed[$scratch_tail,0]
alu[$scratch_base, --, B, 0] // Use ring size of 128 lw and base 0x0
cap[write,$scratch_base,SCRATCH_RING_BASE_0],sig_done[scratch_sig1]
cap[write,$scratch_head,SCRATCH_RING_HEAD_0],sig_done[scratch_sig2]
cap[write,$scratch_tail,SCRATCH_RING_TAIL_0],sig_done[scratch_sig3]
ctx_arb[scratch_sig1, scratch_sig2, scratch_sig3]
alu[$scratch_base, --, B, 1, <<9] // Use ring size of 128 lw and base 0x200
cap[write,$scratch_base,SCRATCH_RING_BASE_1],sig_done[scratch_sig1]
cap[write,$scratch_head,SCRATCH_RING_HEAD_1],sig_done[scratch_sig2]
cap[write,$scratch_tail,SCRATCH_RING_TAIL_1],sig_done[scratch_sig3]
ctx_arb[scratch_sig1, scratch_sig2, scratch_sig3]
alu[$scratch_base, --, B, 2, <<9] // Use ring size of 128 lw and base 0x400
cap[write,$scratch_base,SCRATCH_RING_BASE_2],sig_done[scratch_sig1]
cap[write,$scratch_head,SCRATCH_RING_HEAD_2],sig_done[scratch_sig2]
cap[write,$scratch_tail,SCRATCH_RING_TAIL_2],sig_done[scratch_sig3]
ctx_arb[scratch_sig1, scratch_sig2, scratch_sig3]
alu[$scratch_base, --, B, 3, <<9] // Use ring size of 128 lw and base 0x600
cap[write,$scratch_base,SCRATCH_RING_BASE_3],sig_done[scratch_sig1]
cap[write,$scratch_head,SCRATCH_RING_HEAD_3],sig_done[scratch_sig2]
cap[write,$scratch_tail,SCRATCH_RING_TAIL_3],sig_done[scratch_sig3]
ctx_arb[scratch_sig1, scratch_sig2, scratch_sig3]
alu[$scratch_base, --, B, 4, <<9] // Use ring size of 128 lw and base 0x800
cap[write,$scratch_base,SCRATCH_RING_BASE_4],sig_done[scratch_sig1]
cap[write,$scratch_head,SCRATCH_RING_HEAD_4],sig_done[scratch_sig2]
cap[write,$scratch_tail,SCRATCH_RING_TAIL_4],sig_done[scratch_sig3]
ctx_arb[scratch_sig1, scratch_sig2, scratch_sig3]
.end
start#:
next_packet#:
#ifndef WORKBENCH_SIM // This is because workbench does not simulate PCI
.begin
.reg $packet_info mask
.sig scratch_sig
immed[mask, MASK_16BIT]
wait_for_packet_data#:
scratch[get, $packet_info, get_ring_num, 0, 1], ctx_swap[scratch_sig]
alu[total_bytes, --, B, $packet_info]
beq[wait_for_packet_data#]
// beq[send_interthread_sig#]
.end
.begin
.reg dbase
immed[dbase,0]
immed_w1[dbase, 0x100]
alu[dram_addr, --, B, cur_ctx, <<14]
alu[dram_addr, dbase, +, dram_addr]
.end
#else
immed[total_bytes, POS_PAYLOAD_LENGTH]
immed[dram_addr, (DRAM_BASE_SRC & MASK_16BIT)]
immed_w1[dram_addr, ((DRAM_BASE_SRC >> 16) & MASK_16BIT)]
alu[dram_addr, dram_addr, OR, cur_ctx, <<12]
#endif
immed[bytes_sent, 0]
process_data#:
.begin
.reg remain_bytes
alu[remain_bytes, total_bytes, -, bytes_sent]
.if (remain_bytes <= TX_ELEMENTSIZE_BYTE)
.if (bytes_sent == 0)
alu[sopeop, --, B, SOP_EOP, <<8]
.else
alu[sopeop, --, B, NOSOP_EOP, <<8]
.endif
alu[byte_count, --, B, remain_bytes]
.else // (remain_bytes > TX_ELEMENTSIZE_BYTE)
.if (bytes_sent == 0)
alu[sopeop, --, B, SOP_NOEOP, <<8]
.else
alu[sopeop, --, B, MOP, <<8]
.endif
alu[byte_count, --, B, TX_ELEMENTSIZE_BYTE]
.endif
.end
//****************************************************
// Process to move data to TBUF from DRAM
//****************************************************
.begin
.reg tbuf_addr refcnt
alu[tbuf_element, tbuf_1st_element, +, port_count]
alu[port_count, port_count, +, 1]
alu[port_count, tbuf_mask, AND, port_count]
//*******************************************************
// Read the Transmit Sequence
//*******************************************************
.begin
.reg result tmp_val tmp_tbuf $TxSequenceData
read_tx_sequence_loop#:
msf[read, $TxSequenceData, TxSequenceAddr, 0, 1], ctx_swap[msf_sig]
alu[result, TBUF_ELEM_COUNT_4PORT_MASK, AND, $TxSequenceData] // get mpkts actually sent
alu[tmp_val, TBUF_ELEM_COUNT_4PORT_MASK, AND, tbuf_element]
alu[--, tmp_val, -, result]
bge[cont_comp_tbuf_tx_sequnce#], defer[1]
alu[tmp_tbuf, --, b, tmp_val]
alu[tmp_tbuf, tmp_tbuf, +, TBUF_ELEM_COUNT_4PORT] // wrap around, add tbuf element number
cont_comp_tbuf_tx_sequnce#:
alu[result, tmp_tbuf, -, result] // compare with totals in tbuf
alu[--, result, -, 8] // compare with threshold
bge[read_tx_sequence_loop#] // loop again
.end //result tmp_tbuf
alu[tbuf_addr, --, B, tbuf_element, <<TBUF_ADDR_SHF]
alu[tbuf_addr, tbuf, +, tbuf_addr]
alu[tbuf_addr, --, B, tbuf_addr, <<5]
alu[tbuf_addr, tbuf_addr, OR, 1, <<4] // set the overwrite bit for the TBUF addr
alu[refcnt, --, B, byte_count, >>3]
alu[--, byte_count, AND, 0x7]
bne[refcnt_calc_done#]
alu[refcnt, refcnt, -, 1] // Calculate the refcnt for indirect ref
refcnt_calc_done#:
alu[refcnt, --, B, refcnt, <<21] // Shift to appropriate bit
alu[refcnt, refcnt, OR, 1, <<25] // Set the overwrite bit for refcnt
alu[--, tbuf_addr, OR, refcnt] // indirect ref
dram[tbuf_wr, --, dram_addr, bytes_sent, 8], indirect_ref, sig_done[dram_sig]
ctx_arb[dram_sig]
.end
//*******************************************************
// Write the Transmit Control Word with appropriate data
//*******************************************************
.begin
.reg temp_byte_count
immed[MsfAddress, TBUF_ELEMENT_CONTROL_V]
alu[MsfAddress, MsfAddress, OR, tbuf_element, <<3]
alu[temp_byte_count, byte_count, AND, 0xFF]
alu[$TxControlWord0, sopeop, OR, temp_byte_count, <<24]
immed[$TxControlWord1, 0]
msf[write, $TxControlWord0, MsfAddress, 0, 2], ctx_swap[msf_sig]
.end
alu[bytes_sent, bytes_sent, +, byte_count]
.if (bytes_sent == total_bytes)
immed[total_bytes, 0]
.else
br[process_data#]
.endif
alu[@packet_count, @packet_count, +, 1]
//*****************************************************************************
// Write to scratch ring with the tx packet count
//*****************************************************************************
#ifndef WORKBENCH_SIM
.begin
.reg $scratch_data temp
.sig scratch_sig
// alu[temp, --, B, @packet_count]
// alu[$scratch_data, temp, OR, cur_ctx, <<16]
alu[$scratch_data, --, B, @packet_count]
scratch[put, $scratch_data, put_ring_num, 0, 1], ctx_swap[scratch_sig]
.end
#endif
send_interthread_sig#:
.if (cur_ctx == 0)
local_csr_wr[SAME_ME_SIGNAL, ((INTERTHD_SIG_NUM << 3) | 1)]
.elif (cur_ctx == 1)
local_csr_wr[SAME_ME_SIGNAL, ((INTERTHD_SIG_NUM << 3) | 2)]
.elif (cur_ctx == 2)
local_csr_wr[SAME_ME_SIGNAL, ((INTERTHD_SIG_NUM << 3) | 3)]
.else
local_csr_wr[SAME_ME_SIGNAL, ((INTERTHD_SIG_NUM << 3) | 0)]
.endif
.set_sig interthd_sig
ctx_arb[interthd_sig]
br[next_packet#]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -