Go to the documentation of this file.
39 #include "debug/EthernetAll.hh"
75 intrDelay(
p.intr_delay), intrTick(0), cpuIntrEnable(false),
76 cpuPendingIntr(false), intrEvent(0), interface(NULL)
81 :
Base(
p), rxUnique(0), txUnique(0),
82 virtualRegs(
p.virtual_count < 1 ? 1 :
p.virtual_count),
83 rxFifo(
p.rx_fifo_size), txFifo(
p.tx_fifo_size),
84 rxKickTick(0), txKickTick(0),
86 rxDmaEvent([
this]{ rxDmaDone(); },
name()),
87 txDmaEvent([
this]{ txDmaDone(); },
name()),
88 dmaReadDelay(
p.dma_read_delay), dmaReadFactor(
p.dma_read_factor),
89 dmaWriteDelay(
p.dma_write_delay), dmaWriteFactor(
p.dma_write_factor),
90 sinicDeviceStats(
this)
92 interface = new Interface(
name() + ".int0", this);
100 :
Stats::Group(parent,
"SinicDevice"),
102 "Total vnic distance"),
104 "Number of vnic distance measurements"),
108 "Average vnic distance", totalVnicDistance / numVnicDistance),
124 if (if_name ==
"interface")
135 panic(
"Trying to access a vnic that doesn't exist %d > %d\n",
146 using namespace Regs;
152 uint64_t rxdone = vnic.
RxDone;
155 rxdone = set_RxDone_High(rxdone,
rxFifo.
size() >
regs.RxFifoHigh);
156 rxdone = set_RxDone_NotHigh(rxdone,
rxLow);
158 regs.RxDone = rxdone;
159 regs.RxWait = rxdone;
162 uint64_t txdone = vnic.
TxDone;
167 regs.TxDone = txdone;
168 regs.TxWait = txdone;
174 if (vnic != -1 &&
virtualRegs[vnic].rxPacketOffset > 0)
178 regs.RxStatus = set_RxStatus_Head(
regs.RxStatus, head);
199 assert(
BARs[0]->range().contains(daddr));
200 daddr -=
BARs[0]->addr();
207 panic(
"invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d",
212 panic(
"read %s (write only): "
213 "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
216 panic(
"read %s (invalid size): "
217 "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
222 M5_VAR_USED uint64_t value = 0;
236 "read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n",
241 if (raddr == Regs::IntrStatus)
286 assert(
BARs[0]->range().contains(daddr));
287 daddr -=
BARs[0]->addr();
294 panic(
"invalid register: cpu=%d, da=%#x pa=%#x size=%d",
299 panic(
"write %s (read only): "
300 "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
304 panic(
"write %s (invalid size): "
305 "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
311 "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
313 pkt->
getLE<uint32_t>() : pkt->
getLE<uint64_t>(),
327 case Regs::IntrStatus:
329 pkt->
getLE<uint32_t>());
337 if (Regs::get_RxDone_Busy(vnic.
RxDone))
338 panic(
"receive machine busy with another request! rxState=%s",
342 vnic.
RxDone = Regs::RxDone_Busy;
346 if (Regs::get_RxData_Vaddr(pkt->
getLE<uint64_t>())) {
347 panic(
"vtophys not implemented in newmem");
349 DPRINTF(EthernetPIO,
"write RxData vnic %d (rxunique %d)\n",
354 DPRINTF(EthernetPIO,
"request new packet...appending to rxList\n");
357 DPRINTF(EthernetPIO,
"packet exists...appending to rxBusy\n");
368 if (Regs::get_TxDone_Busy(vnic.
TxDone))
369 panic(
"transmit machine busy with another request! txState=%s",
373 vnic.
TxDone = Regs::TxDone_Busy;
375 if (Regs::get_TxData_Vaddr(pkt->
getLE<uint64_t>())) {
376 panic(
"vtophys won't work here in newmem.\n");
378 DPRINTF(EthernetPIO,
"write TxData vnic %d (txunique %d)\n",
397 if ((interrupts & Regs::Intr_Res))
398 panic(
"Cannot set a reserved interrupt");
400 regs.IntrStatus |= interrupts;
403 "interrupt written to intStatus: intr=%#x status=%#x mask=%#x\n",
404 interrupts,
regs.IntrStatus,
regs.IntrMask);
406 interrupts =
regs.IntrStatus &
regs.IntrMask;
413 interrupts &= ~Regs::Intr_RxHigh;
420 interrupts &= ~Regs::Intr_TxLow;
424 if ((interrupts & Regs::Intr_NoDelay) == 0)
433 if ((interrupts & Regs::Intr_Res))
434 panic(
"Cannot clear a reserved interrupt");
436 regs.IntrStatus &= ~interrupts;
439 "interrupt cleared from intStatus: intr=%x status=%x mask=%x\n",
440 interrupts,
regs.IntrStatus,
regs.IntrMask);
442 if (!(
regs.IntrStatus &
regs.IntrMask))
449 if (
regs.IntrMask == newmask)
452 regs.IntrMask = newmask;
455 "interrupt mask changed: intStatus=%x intMask=%x masked=%x\n",
458 if (
regs.IntrStatus &
regs.IntrMask)
479 DPRINTF(EthernetIntr,
"interrupts not enabled.\n",
485 DPRINTF(EthernetIntr,
"don't need to schedule event...intrTick=%d\n",
495 DPRINTF(EthernetIntr,
"going to schedule an interrupt for intrTick=%d\n",
519 "would send an interrupt now, but there's already pending\n");
524 DPRINTF(EthernetIntr,
"posting interrupt\n");
544 DPRINTF(EthernetIntr,
"clearing cchip interrupt\n");
555 uint32_t changed =
regs.Config ^ newconf;
559 regs.Config = newconf;
561 if ((changed & Regs::Config_IntEn)) {
564 if (
regs.IntrStatus &
regs.IntrMask)
571 if ((changed & Regs::Config_TxEn)) {
577 if ((changed & Regs::Config_RxEn)) {
587 if (
command & Regs::Command_Intr)
590 if (
command & Regs::Command_Reset)
597 using namespace Regs;
603 regs.Config |= Config_RxThread;
605 regs.Config |= Config_TxThread;
607 regs.Config |= Config_RSS;
609 regs.Config |= Config_ZeroCopy;
611 regs.Config |= Config_DelayCopy;
612 if (
params().virtual_addr)
613 regs.Config |= Config_Vaddr;
616 panic(
"Can't delay copy and zero copy");
618 regs.IntrMask = Intr_Soft | Intr_RxHigh | Intr_RxPacket | Intr_TxLow;
622 regs.ZeroCopyMark =
params().zero_copy_threshold;
633 if (
regs.RxMaxCopy <
regs.ZeroCopyMark)
634 panic(
"Must be able to copy at least as many bytes as the threshold");
636 if (
regs.ZeroCopySize >=
regs.ZeroCopyMark)
637 panic(
"The number of bytes to copy must be less than the threshold");
660 for (
int i = 0;
i < size; ++
i)
669 DPRINTF(EthernetDMA,
"end rx dma write paddr=%#x len=%d\n",
685 DPRINTF(EthernetSM,
"rxKick: rxState=%s (rxFifo.size=%d)\n",
689 DPRINTF(EthernetSM,
"rxKick: exiting, can't run till %d\n",
703 DPRINTF(EthernetSM,
"processing rxState=%s\n",
708 "processing rxState=%s for vnic %d (rxunique %d)\n",
717 for (
int i = 0;
i < size; ++
i) {
719 bool busy = Regs::get_RxDone_Busy(vn->
RxDone);
735 "vnic %d %s (rxunique %d), packet %d, slack %d\n",
741 DPRINTF(EthernetSM,
"vnic %d unmapped (rxunique %d)\n",
753 panic(
"continuing vnic without packet\n");
756 "continue processing for vnic %d (rxunique %d)\n",
773 DPRINTF(EthernetSM,
"receive waiting for data. Nothing to do.\n");
778 panic(
"Not idle, but nothing to do!");
787 "processing new packet for vnic %d (rxunique %d)\n",
802 DPRINTF(Ethernet,
"ID is %d\n",
ip->id());
806 DPRINTF(EthernetCksum,
"Rx IP Checksum Error\n");
813 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
819 DPRINTF(EthernetCksum,
"Rx TCP Checksum Error\n");
825 if (
cksum(udp) != 0) {
826 DPRINTF(EthernetCksum,
"Rx UDP Checksum Error\n");
847 if ((Regs::get_Config_ZeroCopy(
regs.Config) ||
848 Regs::get_Config_DelayCopy(
regs.Config)) &&
849 !Regs::get_RxData_NoDelay(vnic->
RxData) &&
rxLow) {
864 DPRINTF(EthernetSM,
"receive machine still copying\n");
869 vnic->
RxDone |= Regs::RxDone_Complete;
880 "rxKick: packet complete on vnic %d (rxunique %d)\n",
891 vnic->
RxDone |= Regs::RxDone_More;
895 "rxKick: packet not complete on vnic %d (rxunique %d): "
918 panic(
"Invalid rxState!");
921 DPRINTF(EthernetSM,
"entering next rxState=%s\n",
930 DPRINTF(EthernetSM,
"rx state machine exited rxState=%s\n",
939 DPRINTF(EthernetDMA,
"tx dma read paddr=%#x len=%d\n",
954 DPRINTF(Ethernet,
"nothing to transmit\n");
961 DPRINTF(Ethernet,
"Packet Transmit: failed txFifo available %d\n",
971 DPRINTF(Ethernet,
"ID is %d\n",
ip->id());
975 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
983 DDUMP(EthernetData, packet->data, packet->length);
987 DPRINTF(Ethernet,
"Packet Transmit: successful txFifo Available %d\n",
990 interrupts = Regs::Intr_TxPacket;
992 interrupts |= Regs::Intr_TxLow;
1000 DPRINTF(EthernetSM,
"txKick: txState=%s (txFifo.size=%d)\n",
1004 DPRINTF(EthernetSM,
"txKick: exiting, can't run till %d\n",
1018 assert(Regs::get_TxDone_Busy(vnic->
TxDone));
1021 txPacket = std::make_shared<EthPacketData>(16384);
1026 Regs::get_TxData_Len(vnic->
TxData)) {
1027 DPRINTF(EthernetSM,
"transmit fifo full. Nothing to do.\n");
1047 DPRINTF(EthernetSM,
"transmit machine still copying\n");
1054 if ((vnic->
TxData & Regs::TxData_More)) {
1062 if ((vnic->
TxData & Regs::TxData_Checksum)) {
1098 panic(
"Invalid txState!");
1101 DPRINTF(EthernetSM,
"entering next txState=%s\n",
1110 DPRINTF(EthernetSM,
"tx state machine exited txState=%s\n",
1118 DPRINTF(Ethernet,
"transfer complete: txFifo empty...nothing to do\n");
1122 DPRINTF(Ethernet,
"transfer complete: data in txFifo...schedule xmit\n");
1130 if (!Regs::get_Config_Filter(
regs.Config))
1133 panic(
"receive filter not implemented\n");
1144 DPRINTF(Ethernet,
"Receiving packet from wire, rxFifo Available is %d\n",
1148 DPRINTF(Ethernet,
"receive disabled...packet dropped\n");
1153 DPRINTF(Ethernet,
"packet filtered...dropped\n");
1162 "packet will not fit in receive buffer...packet dropped\n");
1206 Tick intrEventTick = 0;
1229 if (intrEventTick) {
1245 panic(
"can't serialize with an in flight dma request rxState=%s",
1249 panic(
"can't serialize with an in flight dma request txState=%s",
1266 for (
int i = 0;
i < virtualRegsSize; ++
i) {
1277 if (rxPacketExists) {
1303 VirtualList::const_iterator
i, end;
1306 int rxListSize =
count;
1311 int rxBusySize =
count;
1316 int txListSize =
count;
1335 bool txPacketExists =
txPacket !=
nullptr;
1337 if (txPacketExists) {
1374 for (
int i = 0;
i < rxListSize; ++
i) {
1383 for (
int i = 0;
i < rxBusySize; ++
i) {
1392 for (
int i = 0;
i < txListSize; ++
i) {
1426 bool txPacketExists;
1429 if (txPacketExists) {
1430 txPacket = std::make_shared<EthPacketData>(16384);
1442 int virtualRegsSize;
1446 for (
int i = 0;
i < virtualRegsSize; ++
i) {
1458 bool rxPacketExists;
1460 if (rxPacketExists) {
int countPacketsBefore(const_iterator i) const
static const int VirtualMask
PacketFifo::iterator rxIndex
bool scheduled() const
Determine if the current event is scheduled.
bool push(EthPacketPtr ptr)
#define LL(N)
int64_t constant
@ Running
Running normally.
Stats::Scalar rxUdpChecksums
void serialize(const std::string &base, CheckpointOut &cp) const
Serialization stuff.
#define UNSERIALIZE_SCALAR(scalar)
Stats::Scalar maxVnicDistance
EventFunctionWrapper rxDmaEvent
std::array< PciBar *, 6 > BARs
void unserialize(const std::string &base, CheckpointIn &cp)
void reschedule(Event &event, Tick when, bool always=false)
void cpuIntrPost(Tick when)
DeviceStats(Stats::Group *parent)
virtual void drainResume() override
Resume execution after a successful drain.
int ContextID
Globally unique thread context ID.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Tick read(PacketPtr pkt) override
Memory Interface.
Tick write(PacketPtr pkt) override
IPR read of device register.
uint64_t Tick
Tick count type.
Stats::Scalar rxIpChecksums
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
PCIConfig config
The current config space.
RequestPtr req
A pointer to the original request.
EventFunctionWrapper txEvent
void changeConfig(uint32_t newconfig)
device configuration
const char * RxStateStrings[]
Tick when() const
Get the time that the event is scheduled.
void devIntrChangeMask(uint32_t newmask)
Stats::Scalar numVnicDistance
virtual void resetStats()
Callback to reset stats.
static const int VirtualShift
virtual void drainResume()
Resume execution after a successful drain.
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
void prepareIO(ContextID cpu, int index)
void schedule(Event &event, Tick when)
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
Stats::Scalar txTcpChecksums
void devIntrClear(uint32_t interrupts=Regs::Intr_All)
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
void resetStats() override
Callback to reset stats.
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
void serialize(CheckpointOut &cp) const override
Serialization stuff.
Ports are used to interface objects to each other.
const char * TxStateStrings[]
RxState
Receive State Machine States.
const Regs::Info & regInfo(Addr daddr)
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...
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool cpuIntrPending() const
Stats::Scalar txIpChecksums
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Stats::Scalar totalVnicDistance
void devIntrPost(uint32_t interrupts)
Interrupt management.
uint16_t cksum(const IpPtr &ptr)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
TxState
Transmit State Machine states.
void prepareWrite(ContextID cpu, int index)
fifo_list::iterator iterator
void rxDmaDone()
DMA parameters.
void prepareRead(ContextID cpu, int index)
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
void transmit()
Retransmit event.
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
bool regValid(Addr daddr)
Sinic::Device::DeviceStats sinicDeviceStats
DrainState drainState() const
Return the current drain state of an object.
EventFunctionWrapper * intrEvent
virtual const std::string name() const
#define UNIT_RATE(T1, T2)
bool rxFilter(const EthPacketPtr &packet)
receive address filter
uint64_t & regData64(Addr daddr)
std::shared_ptr< EthPacketData > EthPacketPtr
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Stats::Scalar rxTcpChecksums
bool recvPacket(EthPacketPtr packet)
device ethernet interface
EventFunctionWrapper txDmaEvent
uint32_t & regData32(Addr daddr)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void command(uint32_t command)
void squash()
Squash the current event.
Cycles is a wrapper class for representing cycle counts, i.e.
void setLE(T v)
Set the value in the data pointer to v as little endian.
std::ostream CheckpointOut
bool sendPacket(EthPacketPtr packet)
Tick curTick()
The universal simulation clock.
Dummy class to keep the Python class hierarchy in sync with the C++ object hierarchy.
struct Sinic::Device::@90 regs
device register file
const Params & params() const
void serialize(CheckpointOut &cp) const override
Serialization stuff.
EtherDevice::EtherDeviceStats etherDeviceStats
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
void sendRangeChange() const
Called by the owner to send a range change.
std::string csprintf(const char *format, const Args &...args)
int countPacketsAfter(const_iterator i) const
PacketFifo::iterator rxFifoPtr
Addr pciToDma(Addr pci_addr) const
#define panic(...)
This implements a cprintf based panic() function.
PioPort< PioDevice > pioPort
The pioPort that handles the requests for us and provides us requests that it sees.
Stats::Scalar txUdpChecksums
Generated on Tue Mar 23 2021 19:41:26 for gem5 by doxygen 1.8.17