43#include "debug/EthernetAll.hh"
47#include "params/NSGigE.hh"
52using std::make_shared;
91using namespace networking;
99 txFifo(
p.tx_fifo_size), rxFifo(
p.rx_fifo_size),
100 txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
101 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
102 txState(txIdle), txEnable(false), CTDD(false), txHalt(false),
103 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
104 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
105 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
106 eepromState(eepromStart), eepromClk(false), eepromBitsToRx(0),
107 eepromOpcode(0), eepromAddress(0), eepromData(0),
108 dmaReadDelay(
p.dma_read_delay), dmaWriteDelay(
p.dma_write_delay),
109 dmaReadFactor(
p.dma_read_factor), dmaWriteFactor(
p.dma_write_factor),
110 rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0),
111 txDmaData(NULL), txDmaAddr(0), txDmaLen(0),
113 rxDmaWriteEvent([
this]{ rxDmaWriteDone(); },
name()),
114 txDmaReadEvent([
this]{ txDmaReadDone(); },
name()),
115 txDmaWriteEvent([
this]{ txDmaWriteDone(); },
name()),
116 dmaDescFree(
p.dma_desc_free), dmaDataFree(
p.dma_data_free),
117 txDelay(
p.tx_delay), rxDelay(
p.rx_delay),
119 rxKickEvent([
this]{ rxKick(); },
name()),
121 txKickEvent([
this]{ txKick(); },
name()),
122 txEvent([
this]{ txEventTransmit(); },
name()),
123 rxFilterEnable(
p.rx_filter),
124 acceptBroadcast(
false), acceptMulticast(
false), acceptUnicast(
false),
125 acceptPerfect(
false), acceptArp(
false), multicastHashEnable(
false),
126 intrDelay(
p.intr_delay), intrTick(0), cpuPendingIntr(
false),
127 intrEvent(0), interface(0)
131 interface = new NSGigEInt(
name() +
".int0", this);
134 memcpy(&rom.perfectMatch,
p.hardware_address.bytes(), ETH_ADDR_LEN);
136 memset(&rxDesc32, 0,
sizeof(rxDesc32));
137 memset(&txDesc32, 0,
sizeof(txDesc32));
138 memset(&rxDesc64, 0,
sizeof(rxDesc64));
139 memset(&txDesc64, 0,
sizeof(txDesc64));
157 panic(
"Device specific PCI config space not implemented!\n");
177 if (if_name ==
"interface")
193 DPRINTF(EthernetPIO,
"read da=%#x pa=%#x size=%d\n",
200 panic(
"Accessing reserved register");
201 }
else if (daddr >
RESERVED && daddr <= 0x3FC) {
207 pkt->
setLE<uint32_t>(0);
210 }
else if (daddr > 0x3FC)
211 panic(
"Something is messed up!\n");
213 assert(pkt->
getSize() ==
sizeof(uint32_t));
214 uint32_t &
reg = *pkt->
getPtr<uint32_t>();
326 panic(
"unaligned read from filter hash table!");
333 panic(
"reading RFDR for something other than pattern"
334 " matching or hashing! %#x\n", rfaddr);
398 panic(
"reading unimplemented register: addr=%#x", daddr);
401 DPRINTF(EthernetPIO,
"read from %#x: data=%d data=%#x\n",
414 DPRINTF(EthernetPIO,
"write da=%#x pa=%#x size=%d\n",
418 panic(
"Accessing reserved register");
419 }
else if (daddr >
RESERVED && daddr <= 0x3FC) {
421 }
else if (daddr > 0x3FC)
422 panic(
"Something is messed up!\n");
424 if (pkt->
getSize() ==
sizeof(uint32_t)) {
425 uint32_t
reg = pkt->
getLE<uint32_t>();
487 panic(
"CFGR_AUTO_1000 not implemented!\n");
490 panic(
"CFGR_PCI64_DET is read only register!\n");
534 panic(
"ISR is a read only register!\n");
619 panic(
"Unicast hash filtering not used by drivers!\n");
622 panic(
"RFCR_ULM not implemented!\n");
648 panic(
"unaligned write to filter hash table!");
652 = (uint8_t)(
reg >> 8);
655 panic(
"writing RFDR for something other than pattern matching "
656 "or hashing! %#x\n", rfaddr);
665 panic(
"the driver never uses BRDR, something is wrong!\n");
668 panic(
"SRR is read only register!\n");
671 panic(
"the driver never uses MIBC, something is wrong!\n");
682 panic(
"the driver never uses VDR, something is wrong!\n");
692 panic(
"TBICR_MR_LOOPBACK never used, something wrong!\n");
702 panic(
"TBISR is read only register!\n");
713 panic(
"this should only be written to by the fake phy!\n");
716 panic(
"TANER is read only register!\n");
723 panic(
"invalid register access daddr=%#x", daddr);
726 panic(
"Invalid Request Size");
736 panic(
"Cannot set a reserved interrupt");
739 warn(
"interrupt not implemented %#x\n", interrupts);
772 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
793 panic(
"Cannot clear a reserved interrupt");
820 interrupts &= ~ISR_NOIMPL;
824 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
834 DPRINTF(EthernetIntr,
"interrupt mask changed: isr=%x imr=%x masked=%x\n",
858 DPRINTF(EthernetIntr,
"don't need to schedule event...intrTick=%d\n",
868 DPRINTF(EthernetIntr,
"going to schedule an interrupt for intrTick=%d\n",
892 "would send an interrupt now, but there's already pending\n");
897 DPRINTF(EthernetIntr,
"posting interrupt\n");
917 DPRINTF(EthernetIntr,
"clearing interrupt\n");
929 DPRINTF(Ethernet,
"transmit reset\n");
943 DPRINTF(Ethernet,
"receive reset\n");
998 DPRINTF(EthernetDMA,
"rx dma read paddr=%#x len=%d\n",
1028 DPRINTF(EthernetDMA,
"rx dma write paddr=%#x len=%d\n",
1045 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n",
1054 DPRINTF(EthernetSM,
"receive kick exiting, can't run till %d\n",
1089 DPRINTF(EthernetSM,
"Receive Disabled! Nothing to do.\n");
1134 DPRINTF(EthernetDesc,
"rxDesc: addr=%08x read descriptor\n",
1137 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1138 link, bufptr, cmdsts, extsts);
1161 DPRINTF(EthernetSM,
"****processing receive of new packet****\n");
1169 if (debug::Ethernet) {
1172 DPRINTF(Ethernet,
"ID is %d\n", ip->id());
1176 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1177 tcp->sport(), tcp->dport(), tcp->seq(),
1211 DPRINTF(EthernetSM,
"done with receiving packet\n");
1214 cmdsts &= ~CMDSTS_MORE;
1216 cmdsts &= 0xffff0000;
1223 if (
cksum(ip) != 0) {
1224 DPRINTF(EthernetCksum,
"Rx IP Checksum Error\n");
1232 if (
cksum(tcp) != 0) {
1233 DPRINTF(EthernetCksum,
"Rx TCP Checksum Error\n");
1240 if (
cksum(udp) != 0) {
1241 DPRINTF(EthernetCksum,
"Rx UDP Checksum Error\n");
1256 "rxDesc: addr=%08x writeback cmdsts extsts\n",
1259 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n",
1260 link, bufptr, cmdsts, extsts);
1305 DPRINTF(EthernetSM,
"Halting the RX state machine\n");
1336 panic(
"Invalid rxState!");
1339 DPRINTF(EthernetSM,
"entering next rxState=%s\n",
1347 DPRINTF(EthernetSM,
"rx state machine exited rxState=%s\n",
1358 DPRINTF(Ethernet,
"nothing to transmit\n");
1362 DPRINTF(Ethernet,
"Attempt Pkt Transmit: txFifo length=%d\n",
1366 if (debug::Ethernet) {
1369 DPRINTF(Ethernet,
"ID is %d\n", ip->id());
1373 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
1374 tcp->sport(), tcp->dport(), tcp->seq(),
1385 DPRINTF(Ethernet,
"Successful Xmit! now txFifoAvail is %d\n",
1400 DPRINTF(Ethernet,
"reschedule transmit\n");
1425 DPRINTF(EthernetDMA,
"tx dma read paddr=%#x len=%d\n",
1455 DPRINTF(EthernetDMA,
"tx dma write paddr=%#x len=%d\n",
1471 DPRINTF(EthernetSM,
"transmit kick txState=%s %d-bit\n",
1480 DPRINTF(EthernetSM,
"transmit kick exiting, can't run till %d\n",
1506 DPRINTF(EthernetSM,
"Transmit disabled. Nothing to do.\n");
1552 DPRINTF(EthernetDesc,
"txDesc: addr=%08x read descriptor\n",
1555 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n",
1556 link, bufptr, cmdsts, extsts);
1571 DPRINTF(EthernetSM,
"****starting the tx of a new packet****\n");
1572 txPacket = make_shared<EthPacketData>(16384);
1577 DPRINTF(EthernetSM,
"the txDescCnt == 0, done with descriptor\n");
1579 DPRINTF(EthernetSM,
"there are more descriptors to come\n");
1582 cmdsts &= ~CMDSTS_OWN;
1599 DPRINTF(EthernetSM,
"This packet is done, let's wrap it up\n");
1611 warn_once(
"UDPPKT set, but not UDP!\n");
1617 tcp->sum(
cksum(tcp));
1620 warn_once(
"TCPPKT set, but not UDP!\n");
1639 panic(
"transmit packet too large, %s > 1514\n",
1660 cmdsts &= ~CMDSTS_OWN;
1664 "txDesc writeback: cmdsts=%08x extsts=%08x\n",
1687 DPRINTF(EthernetSM,
"halting TX state machine\n");
1697 DPRINTF(EthernetSM,
"this descriptor isn't done yet\n");
1746 DPRINTF(EthernetSM,
"halting TX state machine\n");
1776 panic(
"invalid state");
1779 DPRINTF(EthernetSM,
"entering next txState=%s\n",
1787 DPRINTF(EthernetSM,
"tx state machine exited txState=%s\n",
1822 panic(
"only EEPROM reads are implemented!");
1840 panic(
"EEPROM read access out of range!");
1863 panic(
"FreeBSD driver only uses EEPROM to read PMATCH!");
1890 panic(
"invalid EEPROM state");
1899 DPRINTF(Ethernet,
"transfer complete: txFifo empty...nothing to do\n");
1903 DPRINTF(Ethernet,
"transfer complete: data in txFifo...schedule xmit\n");
1944 DPRINTF(Ethernet,
"rxFilter drop\n");
1945 DDUMP(EthernetData, packet->data, packet->length);
1957 DPRINTF(Ethernet,
"Receiving packet from wire, rxFifoAvail=%d\n",
1961 DPRINTF(Ethernet,
"receive disabled...packet dropped\n");
1967 "receive packet filtering disabled . . . packet dropped\n");
1972 DPRINTF(Ethernet,
"packet filtered...dropped\n");
1982 "packet won't fit in receive buffer...pkt ID %d dropped\n",
1985 DPRINTF(Ethernet,
"Seq=%d\n", tcp->seq());
2080 bool txPacketExists =
txPacket !=
nullptr;
2082 if (txPacketExists) {
2085 txPacket->serialize(
"txPacket", cp);
2090 bool rxPacketExists =
rxPacket !=
nullptr;
2092 if (rxPacketExists) {
2093 rxPacket->serialize(
"rxPacket", cp);
2183 Tick intrEventTick = 0;
2245 bool txPacketExists;
2247 if (txPacketExists) {
2248 txPacket = make_shared<EthPacketData>(16384);
2249 txPacket->unserialize(
"txPacket", cp);
2250 uint32_t txPktBufPtr;
2256 bool rxPacketExists;
2259 if (rxPacketExists) {
2260 rxPacket = make_shared<EthPacketData>();
2261 rxPacket->unserialize(
"rxPacket", cp);
2262 uint32_t rxPktBufPtr;
2365 if (intrEventTick) {
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles is a wrapper class for representing cycle counts, i.e.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
Dummy class to keep the Python class hierarchy in sync with the C++ object hierarchy.
EtherDevBaseParams Params
gem5::EtherDevice::EtherDeviceStats etherDeviceStats
bool sendPacket(EthPacketPtr packet)
uint32_t txDescCnt
count of bytes remaining in the current descriptor
uint32_t rxPktBytes
num of bytes in the current packet being drained from rxDataFifo
void eepromKick()
Advance the EEPROM state machine Called on rising edge of EEPROM clock bit in MEAR.
bool CRDD
Current Receive Descriptor Done.
EEPROMState eepromState
EEPROM State Machine.
bool rxFilterEnable
receive address filter
EventFunctionWrapper rxDmaWriteEvent
RxState rxState
rx State Machine
void devIntrClear(uint32_t interrupts)
void drainResume() override
Resume execution after a successful drain.
Tick writeConfig(PacketPtr pkt) override
This is to write to the PCI general configuration registers.
EventFunctionWrapper txDmaReadEvent
ns_desc32 txDesc32
DescCaches.
EventFunctionWrapper txEvent
void transmit()
Retransmit event.
void cpuIntrPost(Tick when)
EventFunctionWrapper * intrEvent
Tick read(PacketPtr pkt) override
This reads the device registers, which are detailed in the NS83820 spec sheet.
EventFunctionWrapper txDmaWriteEvent
EEPROMState
EEPROM State Machine States.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool CTDD
Current Transmit Descriptor Done.
bool recvPacket(EthPacketPtr packet)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool ioEnable
pci settings
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
EventFunctionWrapper rxDmaReadEvent
void devIntrPost(uint32_t interrupts)
Interrupt management.
EventFunctionWrapper rxKickEvent
Addr rxFragPtr
ptr to the next byte in current fragment
Addr txFragPtr
ptr to the next byte in the current fragment
dp_regs regs
device register file
bool rxFilter(const EthPacketPtr &packet)
void serialize(CheckpointOut &cp) const override
Serialize an object.
uint32_t rxDescCnt
count of bytes remaining in the current descriptor
TxState
Transmit State Machine states.
RxState
Receive State Machine States.
bool cpuIntrPending() const
NSGigE(const Params ¶ms)
EthPacketPtr txPacket
various helper vars
EventFunctionWrapper txKickEvent
void serialize(const std::string &base, CheckpointOut &cp) const
Serialization stuff.
unsigned reserve(unsigned len=0)
void unserialize(const std::string &base, CheckpointIn &cp)
bool push(EthPacketPtr ptr)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setLE(T v)
Set the value in the data pointer to v as little endian.
T * getPtr()
get a pointer to the data ptr.
void makeAtomicResponse()
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
PCIConfig config
The current config space.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
Ports are used to interface objects to each other.
virtual void drainResume()
Resume execution after a successful drain.
DrainState drainState() const
Return the current drain state of an object.
@ Running
Running normally.
bool scheduled() const
Determine if the current event is scheduled.
void squash()
Squash the current event.
void schedule(Event &event, Tick when)
void reschedule(Event &event, Tick when, bool always=false)
Tick when() const
Get the time that the event is scheduled.
uint16_t cksum(const IpPtr &ptr)
#define panic(...)
This implements a cprintf based panic() function.
#define UNSERIALIZE_ARRAY(member, size)
#define SERIALIZE_ARRAY(member, size)
const Params & params() const
const uint8_t EEPROM_SIZE
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
const char * NsRxStateStrings[]
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
uint64_t Tick
Tick count type.
const uint16_t FHASH_SIZE
const uint16_t FHASH_ADDR
const char * NsDmaState[]
const uint8_t EEPROM_PMATCH2_ADDR
const uint8_t EEPROM_PMATCH0_ADDR
const uint8_t EEPROM_READ
const char * NsTxStateStrings[]
const uint8_t EEPROM_PMATCH1_ADDR
std::shared_ptr< EthPacketData > EthPacketPtr
Device module for modelling the National Semiconductor DP83820 ethernet controller.
Declaration of the Packet class.
#define PCI_DEVICE_SPECIFIC
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)
statistics::Scalar postedTxOk
statistics::Scalar txPackets
statistics::Scalar postedRxIdle
statistics::Scalar postedTxIdle
statistics::Scalar txIpChecksums
statistics::Scalar txBytes
statistics::Scalar postedTxDesc
statistics::Scalar totalSwi
statistics::Scalar rxTcpChecksums
statistics::Scalar rxPackets
statistics::Scalar totalRxDesc
statistics::Scalar txUdpChecksums
statistics::Scalar postedRxDesc
statistics::Scalar rxUdpChecksums
statistics::Scalar totalTxOk
statistics::Scalar rxIpChecksums
statistics::Scalar txTcpChecksums
statistics::Scalar droppedPackets
statistics::Scalar totalRxIdle
statistics::Scalar totalTxDesc
statistics::Scalar descDmaWrBytes
statistics::Scalar postedRxOrn
statistics::Scalar postedSwi
statistics::Scalar totalRxOrn
statistics::Scalar totalRxOk
statistics::Scalar descDmaRdBytes
statistics::Scalar postedRxOk
statistics::Scalar postedInterrupts
statistics::Scalar totalTxIdle
statistics::Scalar descDmaWrites
statistics::Scalar rxBytes
statistics::Scalar descDmaReads
uint8_t perfectMatch[ETH_ADDR_LEN]
for perfect match memory.
uint8_t filterHash[FHASH_SIZE]
for hash table memory.
const EthAddr & dst() const
const std::string & name()