receive3.c
来自「在接入服务器测试在收发链路层数据包」· C语言 代码 · 共 236 行
C
236 行
//------------------------------------------------------------------------------------
//
// I N T E L P R O P R I E T A R Y
//
// COPYRIGHT (c) 2001 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
//
//------------------------------------------------------------------------------------
//////////////////////////////////////////////////////
// Include libraries
//////////////////////////////////////////////////////
#include "ixp.h"
#include "rtl.c"
#include "mem_map3.h"
#define UINT unsigned int
//////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////
#define MAX_PACKETS 5 //number of packets to receive
#define MYCONTEXT 0 //absolute context number (0-23)
#define CURRENT_PORT 1 //MAC port number to check for packets
//; RCV_REQ FORMAT
//; +--------+-----+----+-----+-----+-----+----+-----+------+-------+-----+------+
//; | fetch 9| msg |stat| elem| elem|seq# |1or2|misc | sig | thread| mac | port |
//; | | pkt | | #2 | #1 | | | | sched| | | |
//; | 29 |28:27| 26 |25:22|21:18|17:16| 15 |14:12| 11 | 10:6 | 5:3 | 2:0 |
//; +--------+-----+----+-----+-----+-----+----+-----+------+-------+-----+------+
#define THIS_RR ((CURRENT_PORT<<18)|(MYCONTEXT<<6)|(CURRENT_PORT))
/******************************************************/
void main(void)
{
__declspec(dram) long long *packet; //address for packet storage in DRAM
__declspec(sram) UINT *p_descriptor; //address for descriptor in SRAM
__declspec(sram) UINT *p_led; //address of led
UINT rcv_rdy; //contains ready flags
UINT rcv_cmd; //holds RCV_CNTL register info after a packet receive
UINT rfifo_entry; //extract rfifo element # from RCV_CNTL
UINT packet_count; //tracks the number of packets received so far
UINT current_rr; //hold formatted receive request
UINT port_mask; //bitmask to check RCV_RDY_LO register
__declspec(sram_read_reg) UINT temp_csr; //temp register used to read CSR's
UINT temp_desc; //temporary storage while formatting descriptor
fifo_read_write_ind_t dram_rfifo_read_ind; //used for formatting indirect ref
//////////////////////////////////////////////////////
// Check Context Number
//
// Run only one receive thread on context 0; if we are
// not running as context 0,then permanently swap out.
//
//////////////////////////////////////////////////////
if(ctx() == 0)
{
p_led = (__declspec(sram) UINT *)0x00742000;
*p_led = 0;
//get addresses from mem_map
packet = (__declspec(dram) long long *)DATA_ADDR;
p_descriptor = (__declspec(sram) UINT *)DESCRIPTOR_ADDR;
current_rr = THIS_RR;
port_mask = 1<<CURRENT_PORT;
//for this project, all packets are 64bytes
dram_rfifo_read_ind.ov_ref_count = 1;
dram_rfifo_read_ind.ref_count = 0x08;
packet_count = 0;
//////////////////////////////////////////////////////
// Start of Loop
//
// If we have received the number of packets contained
// in the GPR max_packets, then stop processing.
//
//////////////////////////////////////////////////////
// while(packet_count < MAX_PACKETS)
while(1) //receive packets forever!
{
//////////////////////////////////////////////////////
// Read Receive Ready Flags until our port has data
//
// In RCV_RDY_LO, bit 1 corresponds to port 1,
// so we can see if our port is ready by checking
// if bit 1 is set (by ANDING WITH PORTMASK)
//////////////////////////////////////////////////////
rcv_rdy = 0;
while(!(rcv_rdy & port_mask))
{
//just keep reading RCV_RDY_LO
//until our port has data
csr_read(&temp_csr, rcv_rdy_lo, 1, ctx_swap);
rcv_rdy = temp_csr;
//note the use of a temporary register above:
// this is done b/c when using the intrinsics
// to access CSR's, transfer registers are used
// and hence the parameter to the csr_read,
// "temp_csr" will have all the restrictions
// of a normal transfer register..
}
*p_led = 1;
//////////////////////////////////////////////////////
// Write the Receive Request
//////////////////////////////////////////////////////
csr_write(current_rr, rcv_req, no_signal);
//////////////////////////////////////////////////////
// Swap out and wait for a signal from the IX Bus Unit
// that the packet data is in the Receive FIFO Element
//////////////////////////////////////////////////////
ctx_wait(start_receive);
*p_led = 2;
//////////////////////////////////////////////////////
// The packet is now in an RFIFO Element. Read the
// RVC_CNTL register to retrieve the control information
//
// Note the use of a temporary register to perform read
// due to transfer register issues.
//////////////////////////////////////////////////////
csr_read(&temp_csr, rcv_cntl, 1, ctx_swap);
rcv_cmd = temp_csr;
//; RCV_CNTL REGISTER FORMAT
//; +-----+-----+-----+------+----+-----+-----+----+----+-----------+---+---+
//; | msg |port |seq# |rxfail|err |elem2|elem1|1or2|seq | validbytes|EOP|SOP|
//; |31:30|29:24|23:20| 19 | 18 |17:14|13:10| 9 | 8 | 7:2 | 1 | 0 |
//; +-----+-----+-----+------+----+-----+-----+----+----+-----------+---+---+
*p_led = 3;
//////////////////////////////////////////////////////
// Move the packet from the RFIFO Element to the
// packet buffer in SDRAM
//////////////////////////////////////////////////////
////////////////////////////////////////////////////////
// Take the element number from the RCV_CNTL register,
// then multiply it by 8 (the number of quadwords per
// element) to get the address of the FIFO Element
////////////////////////////////////////////////////////
rfifo_entry = (rcv_cmd>>10) & 0xF;
dram_rfifo_read_ind.qword_addr = rfifo_entry * 8;
*p_led = 4;
// sdram_r_fifo_read_ind(packet, 4, dram_rfifo_read_ind, queue_default, ctx_swap);
*p_led = 5;
//////////////////////////////////////////////////////
// Format the packet descriptor
// - Take quadword count, byte count, EOP and SOP flags,
// and port number from the RCV_CNTL
// Write descriptor to SRAM
// Signal the Transmit thread to process the packet
// Increment the packet counter
//////////////////////////////////////////////////////
//; RCV_CNTL REGISTER FORMAT
//; +-----+-----+-----+------+----+-----+-----+----+----+-----------+---+---+
//; | msg |port |seq# |rxfail|err |elem2|elem1|1or2|seq | validbytes|EOP|SOP|
//; |31:30|29:24|23:20| 19 | 18 |17:14|13:10| 9 | 8 | 7:2 | 1 | 0 |
//; +-----+-----+-----+------+----+-----+-----+----+----+-----------+---+---+
//; DESCRIPTOR FORMAT
//; +-----+-------+---------+---+---+----+----+
//; | res | num qw|num bytes|EOP|SOP|skip|port|
//; | 31 | 15:13 | 12:10 | 9 | 8 | 7 |6:0 |
//; +-----+-------+---------+---+---+----+----+
temp_desc = rcv_cmd & 0xFF; // EOP/SOP and valid bytes
temp_desc = (temp_desc<<8) | ((rcv_cmd>>24)&0x3F); //add port info
(*p_descriptor) = temp_desc; //write descriptor to memory
*p_led = 6;
//At this point, signal transmit thread
csr_fast_write(inter_thd_sig, 0x4);
packet_count++; //increment packet count
//now wait for signal from transmit thread
//before getting another packet
ctx_wait(inter_thread);
} //while - go to start of receive loop
//////////////////////////////////////////////////////
// FINISHED PROCESSING ALL PACKETS /
//////////////////////////////////////////////////////
}
else //not context 0
{
ctx_wait(kill);
}
} //receive3 main
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?