📄 msf_cbus_tx.uc
字号:
/* msf_cbus_tx.uc
*
*---------------------------------------------------------------------------
*
* 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: IXP2400
* subsystem: DIAG
* author: dalsraja, March, 2002
* revisions:
*
*
* --------------------------------------------------------------------------
*/
#include "common_uc.h"
#define TX_ELEMENT_SIZE MSF_ELEMENTSIZE_128
#define TX_ENABLE_MASK 0x1
#define TX_MODE MSF_CSIX
#define TX_WIDTH MSF_WIDTH_1x32
#define TX_SINGLE_PHY MSF_SINGLE_PHY
#define CSIX_PAYLOAD_LENGTH 64
#define DRAM_BASE_SRC 0x1000000 // 16MB
#define SRAM_BASE_DEST 0x100000 // 1MB
.reg temp1 temp2 temp3
.reg pkt_count_tx pkt_count_rx
.reg MsfAddress MsfAddress0 MsfAddress1 tbuf_addr
.reg TxConfigData0
.reg $TxConfigData0
.reg $TxControlWord0 $TxControlWord1
.reg tbuf_element tbuf_offset
.reg dram_addr tbuf
.sig dram_sig msf_sig
.xfer_order $TxControlWord0 $TxControlWord1
br!=ctx[0, kill_thd#]
init#:
#ifdef WORKBENCH_SIM
.begin
.reg tmp_addr $tmp_data
.sig scratch_sig
immed[tmp_addr, 0x200]
wait_for_signal#:
scratch[read, $tmp_data, tmp_addr, 0, 1], ctx_swap[scratch_sig]
alu[--, $tmp_data, -, 0]
bne[wait_for_signal#]
.end
#endif
immed[tbuf_element, 0]
immed[dram_addr, (DRAM_BASE_SRC & MASK_16BIT)]
immed_w1[dram_addr, (DRAM_BASE_SRC >> 16)]
immed[tbuf, RBUF_TBUF]
//****************************************************
// 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) | (1 << 0))]
alu[$TxConfigData0, --, B, TxConfigData0]
msf[write, $TxConfigData0, MsfAddress, 0, 1], ctx_swap[msf_sig]
immed_w1[TxConfigData0, ((TX_ENABLE_MASK << 12) | (TX_ENABLE_MASK << 8) | (TX_MODE << 6) | (TX_WIDTH << 4) | (TX_SINGLE_PHY << 3) | (0 << 1) | (1 << 0))]
alu[$TxConfigData0, --, B, TxConfigData0]
msf[write, $TxConfigData0, MsfAddress, 0, 1], ctx_swap[msf_sig]
start#:
//****************************************************
// Move data to TBUF from DRAM - Use a 64 byte packet
//****************************************************
alu[tbuf_addr, --, B, tbuf_element, <<6]
alu[tbuf_addr, --, B, tbuf_addr, <<TX_ELEMENT_SIZE]
alu[tbuf_addr, tbuf_addr, +, tbuf]
alu[tbuf_addr, --, B, tbuf_addr, <<5]
alu[--, tbuf_addr, OR, 1, <<4] // set the overwrite bit for the TBUF addr
dram[tbuf_wr, --, dram_addr, 0, 8], indirect_ref, sig_done[dram_sig]
ctx_arb[dram_sig]
#ifdef MSF_WORKAROUND
alu[--, tbuf_addr, OR, 1, <<4] // set the overwrite bit for the TBUF addr
dram[tbuf_wr, --, dram_addr, 0, 2], indirect_ref, sig_done[dram_sig]
ctx_arb[dram_sig]
#endif
//*******************************************************
// Write the Transmit Control Word with appropriate data
//*******************************************************
immed[$TxControlWord1, 0] // No extension header for flow control packet
immed[temp1, CSIX_FLOWCONTROL]
alu[$TxControlWord0, temp1, OR, CSIX_PAYLOAD_LENGTH, <<24]
immed[MsfAddress, TBUF_ELEMENT_CONTROL_V]
msf[write, $TxControlWord0, MsfAddress, 0, 2], ctx_swap[msf_sig] // Write control word and validate
// CSIX Packet Format
// CSIX Base Header (2 bytes)
// +-------+----------+-----+-----+-----------------------+
// | Ready | Type | CR | P | Payload Length |
// | 2 bits| 4 bits |1 bit|1 bit| 7 bits |
// +-------+----------+-----+-----+-----------------------+
//
// CSIX Unicast CFrame Extension Header - 4 bytes
// CSIX Flow Control Frame - No extension header
.begin
.reg ctr temp type payload_length total_length offset sram_addr pci_base pci_offset
.reg $In1 $pci_rw
.sig sram_sig pci_sig
immed[MsfAddress, FCIFIFO]
immed[sram_addr, (SRAM_BASE_DEST & MASK_16BIT)]
immed_w1[sram_addr, ((SRAM_BASE_DEST >> 16) & MASK_16BIT)]
alu[sram_addr, sram_addr, OR, CHAN_NUMBER, <<SRAM_CHANNEL_NUMBER_FIELD]
immed[pci_base, (PCI_LOCAL_CSR_BASE & MASK_16BIT)]
immed_w1[pci_base, ((PCI_LOCAL_CSR_BASE >> 16) & MASK_16BIT)]
immed[pci_offset, MAILBOX1_OFFSET]
immed[ctr, 0] // to be used to count number of payload bytes read from FCIFIFO
// At this point, the code will poll on the FCIFIFO waiting for the state of the FCIFIFO
// to be not empty, i.e. new data has come into the FCIFIFO. After the fcififo_not_empty
// state is reached, the data is read from the FCIFIFO is read from it until the
// fcififo_not_empty state is not set any longer
wait_for_fcififo#:
br_!inp_state[fci_not_empty, wait_for_fcififo#] // Branch to label if FCIFIFO empty
msf[read, $In1, MsfAddress, 0, 1], ctx_swap[msf_sig] // Read FCIFIFO
alu[type, 0xF, AND, $In1, >>26] // Extract packet type, i.e. Flow control, etc
alu[payload_length, 0xFF, AND, $In1, >>16] // extract payload length
alu[total_length, payload_length, +, CSIX_BASE_HDR_LEN]
alu[total_length, total_length, +, CSIX_TAIL_LEN] // calculate total length expected
alu[$In1, --, B, $In1]
// sram[write, $In1, sram_addr, ctr, 1], ctx_swap[sram_sig] // write read data to SRAM
.local tmp_addr $tmp_data
immed[tmp_addr, 0x200]
alu[$tmp_data, --, B, $In1]
// alu[$tmp_data, sram_addr, +, ctr]
scratch[write, $tmp_data, tmp_addr, ctr, 1], ctx_swap[pci_sig]
.endlocal
alu[ctr, ctr, +, 4] // add 4 to count of bytes read from FCIFIFO
.if (ctr > total_length)
br[end#]
.endif
read_fcififo#:
br_!inp_state[fci_not_empty, wait_for_fcififo#] // Branch to label is FCIFIFO empty
msf[read, $In1, MsfAddress, 0, 1], ctx_swap[msf_sig] // Read FCIFIFO
alu[$In1, --, B, $In1]
// sram[write, $In1, sram_addr, ctr, 1], ctx_swap[sram_sig] // Write to SRAM
.local tmp_addr $tmp_data
immed[tmp_addr, 0x200]
alu[$tmp_data, --, B, $In1]
// alu[$tmp_data, sram_addr, +, ctr]
scratch[write, $tmp_data, tmp_addr, ctr, 1], ctx_swap[pci_sig]
.endlocal
alu[ctr, ctr, +, 4] // add 4 to count of bytes read from FCIFIFO
.if (ctr < total_length) // if received bytes is less than total bytes expected
br[read_fcififo#] // branch to label read_fcififo#
.endif
br_!inp_state[fci_not_empty, end#] // if FCIFIFO is empty, branch to label end#
// else oversized packet received, so continue
//***********************************************************************
// Write to MAILBOX1 register to indicate oversized packet was received
//***********************************************************************
immed[temp, 0]
immed_w1[temp, INCORRECT_SIZE]
alu[$pci_rw, --, B, temp]
pci[write, $pci_rw, pci_base, pci_offset, 1], ctx_swap[pci_sig] // Write to mailbox0
// This label will be reached is FCIFIFO is not empty even after
// all expected bytes have been received through FCIFIFO
empty_fcififo#:
msf[read, $In1, MsfAddress, 0, 1], ctx_swap[msf_sig] // read FCIFIFO
br_inp_state[fci_not_empty, empty_fcififo#] // if not empty, branch to label
br[kill_thd#]
end#:
//****************************************************************************
// Write to MAILBOX0 register to indicate incorrect packet type was received
//****************************************************************************
.if (type != CSIX_FLOWCONTROL) // if not a flow control packet
// write to mailbox register indicating error
immed[temp, 0]
immed_w1[temp, INCORRECT_TYPE]
alu[$pci_rw, --, B, temp]
pci[write, $pci_rw, pci_base, pci_offset, 1], ctx_swap[pci_sig] // Write to mailbox0
br[kill_thd#]
.endif
//*****************************************************************
// Write to MAILBOX0 register to signal completion to XScale code
//*****************************************************************
immed[temp, TEST_COMPLETE]
alu[temp, --, B, temp, <<16]
alu[temp, temp, OR, ctr]
alu[$pci_rw, --, B, temp]
pci[write, $pci_rw, pci_base, pci_offset, 1], ctx_swap[pci_sig] // Write to mailbox0
.end
kill_thd#:
ctx_arb[kill]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -