diff options
author | Ali Saidi <saidi@eecs.umich.edu> | 2006-05-12 18:16:07 -0400 |
---|---|---|
committer | Ali Saidi <saidi@eecs.umich.edu> | 2006-05-12 18:16:07 -0400 |
commit | 03a00e5d32411f467735b2af890c1ca54930e949 (patch) | |
tree | 4154e4703c0c3e18bd4d6b4de98fe8650d6f704d | |
parent | a91ee5abc2275709871b016d43ca2d2440fa5000 (diff) | |
parent | 7929b9ee19b6fabc7e69b704fa07fdb6daa35c70 (diff) | |
download | gem5-03a00e5d32411f467735b2af890c1ca54930e949.tar.xz |
Merge zeep.pool:/z/saidi/work/m5.head
into zeep.pool:/z/saidi/work/m5.nm_m5_pull
SConscript:
dram memory needs to be converted to newmem before we can use it
dev/ide_ctrl.cc:
don't need this printing in newmem
dev/ide_disk.cc:
will read stats in next commit
dev/sinic.cc:
merge sinic from head, still needs work
--HG--
extra : convert_revision : b9aabd8c7814d07d54ce6f971aad3ec349fa24e1
-rw-r--r-- | arch/alpha/isa/decoder.isa | 2 | ||||
-rw-r--r-- | dev/ide_disk.hh | 14 | ||||
-rw-r--r-- | dev/sinic.cc | 289 | ||||
-rw-r--r-- | dev/sinic.hh | 16 | ||||
-rw-r--r-- | dev/sinicreg.hh | 62 | ||||
-rw-r--r-- | python/m5/objects/Ethernet.py | 10 | ||||
-rw-r--r-- | sim/serialize.cc | 12 | ||||
-rw-r--r-- | sim/serialize.hh | 5 | ||||
-rw-r--r-- | util/stats/barchart.py | 8 |
9 files changed, 318 insertions, 100 deletions
diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 3d38e91f9..1adcfb948 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -810,7 +810,7 @@ decode OPCODE default Unknown::unknown() { AlphaPseudo::addsymbol(xc->xcBase(), R16, R17); }}, IsNonSpeculative); 0x54: m5panic({{ - panic("M5 panic instruction called."); + panic("M5 panic instruction called at pc=%#x.", xc->readPC()); }}, IsNonSpeculative); } diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index 3d67abece..891c462b5 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -33,6 +33,7 @@ #ifndef __IDE_DISK_HH__ #define __IDE_DISK_HH__ +#include "base/statistics.hh" #include "dev/disk_image.hh" #include "dev/ide_atareg.h" #include "dev/ide_ctrl.hh" @@ -231,6 +232,13 @@ class IdeDisk : public SimObject /** Interrupt pending */ bool intrPending; + Stats::Scalar<> dmaReadFullPages; + Stats::Scalar<> dmaReadBytes; + Stats::Scalar<> dmaReadTxs; + Stats::Scalar<> dmaWriteFullPages; + Stats::Scalar<> dmaWriteBytes; + Stats::Scalar<> dmaWriteTxs; + public: /** * Create and initialize this Disk. @@ -252,6 +260,12 @@ class IdeDisk : public SimObject void reset(int id); /** + * Register statistics. + */ + void regStats(); + + + /** * Set the controller for this device * @param c The IDE controller */ diff --git a/dev/sinic.cc b/dev/sinic.cc index b5b6c6cf5..66ca88dbe 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -81,7 +81,8 @@ Base::Base(Params *p) } Device::Device(Params *p) - : Base(p), rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), + : Base(p), plat(p->plat), physmem(p->physmem), rxUnique(0), txUnique(0), + virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count), rxKickTick(0), txKickTick(0), txEvent(this), rxDmaEvent(this), txDmaEvent(this), dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor), @@ -268,12 +269,9 @@ void Device::prepareIO(int cpu, int index) { int size = virtualRegs.size(); - if (index < size) - return; - - virtualRegs.resize(index + 1); - for (int i = size; i <= index; ++i) - virtualRegs[i].rxPacket = rxFifo.end(); + if (index > size) + panic("Trying to access a vnic that doesn't exist %d > %d\n", + index, size); } void @@ -286,7 +284,10 @@ Device::prepareRead(int cpu, int index) // update rx registers uint64_t rxdone = vnic.RxDone; - rxdone = set_RxDone_Packets(rxdone, rxFifo.packets()); + rxdone = set_RxDone_Packets(rxdone, rxFifo.countPacketsAfter(rxFifoPtr)); + rxdone = set_RxDone_Empty(rxdone, rxFifo.empty()); + rxdone = set_RxDone_High(rxdone, rxFifo.size() > regs.RxFifoMark); + rxdone = set_RxDone_NotHigh(rxdone, rxLow); regs.RxData = vnic.RxData; regs.RxDone = rxdone; regs.RxWait = rxdone; @@ -325,17 +326,18 @@ Device::read(Packet &pkt) pkt.allocate(); if (!regValid(raddr)) - panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", - cpu, daddr, pkt.addr, pkt.size); + panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d", + cpu, index, daddr, pkt.addr, pkt.size); const Regs::Info &info = regInfo(raddr); if (!info.read) - panic("reading %s (write only): cpu=%d da=%#x pa=%#x size=%d", - info.name, cpu, daddr, pkt.addr, pkt.size); + panic("read %s (write only): " + "cpu=%d vnic=%d da=%#x pa=%#x size=%d", + info.name, cpu, index, daddr, pkt.addr, pkt.size); - if (pkt.size != info.size) - panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d", - info.name, cpu, daddr, pkt.addr, pkt.size); + panic("read %s (invalid size): " + "cpu=%d vnic=%d da=%#x pa=%#x size=%d", + info.name, cpu, index, daddr, pkt.addr, pkt.size); prepareRead(cpu, index); @@ -353,8 +355,8 @@ Device::read(Packet &pkt) } DPRINTF(EthernetPIO, - "read %s cpu=%d da=%#x pa=%#x size=%d val=%#x\n", - info.name, cpu, daddr, pkt.addr, pkt.size, value); + "read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n", + info.name, cpu, index, daddr, pkt.addr, pkt.size, value); // reading the interrupt status register has the side effect of // clearing it @@ -416,18 +418,20 @@ Device::write(Packet &pkt) const Regs::Info &info = regInfo(raddr); if (!info.write) - panic("write %s (read only): cpu=%d da=%#x pa=%#x size=%d", - info.name, cpu, daddr, pkt.addr, pkt.size); + panic("write %s (read only): " + "cpu=%d vnic=%d da=%#x pa=%#x size=%d", + info.name, cpu, index, daddr, pkt.addr, pkt.size); if (pkt.size != info.size) - panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d", - info.name, cpu, daddr, pkt.addr, pkt.size); + panic("write %s (invalid size): " + "cpu=%d vnic=%d da=%#x pa=%#x size=%d", + info.name, cpu, index, daddr, pkt.addr, pkt.size); VirtualReg &vnic = virtualRegs[index]; DPRINTF(EthernetPIO, - "write %s: cpu=%d val=%#x da=%#x pa=%#x size=%d\n", - info.name, cpu, info.size == 4 ? pkt.get<uint32_t>() : + "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n", + info.name, index, cpu, info.size == 4 ? pkt.get<uint32_t>() : pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size); prepareWrite(cpu, index); @@ -454,10 +458,32 @@ Device::write(Packet &pkt) panic("receive machine busy with another request! rxState=%s", RxStateStrings[rxState]); + vnic.rxUnique = rxUnique++; vnic.RxDone = Regs::RxDone_Busy; vnic.RxData = pkt.get<uint64_t>(); - rxList.push_back(index); - if (rxEnable && rxState == rxIdle) { + + if (Regs::get_RxData_Vaddr(reg64)) { + Addr vaddr = Regs::get_RxData_Addr(reg64); + Addr paddr = vtophys(req->xc, vaddr); + DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d): " + "vaddr=%#x, paddr=%#x\n", + index, vnic.rxUnique, vaddr, paddr); + + vnic.RxData = Regs::set_RxData_Addr(vnic.RxData, paddr); + } else { + DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d)\n", + index, vnic.rxUnique); + } + + if (vnic.rxPacket == rxFifo.end()) { + DPRINTF(EthernetPIO, "request new packet...appending to rxList\n"); + rxList.push_back(index); + } else { + DPRINTF(EthernetPIO, "packet exists...appending to rxBusy\n"); + rxBusy.push_back(index); + } + + if (rxEnable && (rxState == rxIdle || rxState == rxFifoBlock)) { rxState = rxFifoBlock; rxKick(); } @@ -468,8 +494,23 @@ Device::write(Packet &pkt) panic("transmit machine busy with another request! txState=%s", TxStateStrings[txState]); + vnic.txUnique = txUnique++; vnic.TxDone = Regs::TxDone_Busy; - vnic.TxData = pkt.get<uint64_t>(); + + if (Regs::get_TxData_Vaddr(pkt.get<uint64_t>())) { + panic("vtophys won't work here in newmem.\n"); + /*Addr vaddr = Regs::get_TxData_Addr(reg64); + Addr paddr = vtophys(req->xc, vaddr); + DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d): " + "vaddr=%#x, paddr=%#x\n", + index, vnic.txUnique, vaddr, paddr); + + vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr);*/ + } else { + DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d)\n", + index, vnic.txUnique); + } + if (txList.empty() || txList.front() != index) txList.push_back(index); if (txEnable && txState == txIdle && txList.front() == index) { @@ -695,10 +736,21 @@ Device::reset() regs.Config |= Config_TxThread; if (params()->rss) regs.Config |= Config_RSS; + if (params()->zero_copy) + regs.Config |= Config_ZeroCopy; + if (params()->delay_copy) + regs.Config |= Config_DelayCopy; + if (params()->virtual_addr) + regs.Config |= Config_Vaddr; + + if (params()->delay_copy && params()->zero_copy) + panic("Can't delay copy and zero copy"); + regs.IntrMask = Intr_Soft | Intr_RxHigh | Intr_RxPacket | Intr_TxLow; regs.RxMaxCopy = params()->rx_max_copy; regs.TxMaxCopy = params()->tx_max_copy; regs.RxMaxIntr = params()->rx_max_intr; + regs.VirtualCount = params()->virtual_count; regs.RxFifoSize = params()->rx_fifo_size; regs.TxFifoSize = params()->tx_fifo_size; regs.RxFifoMark = params()->rx_fifo_threshold; @@ -706,6 +758,8 @@ Device::reset() regs.HwAddr = params()->eaddr; rxList.clear(); + rxBusy.clear(); + rxActive = -1; txList.clear(); rxState = rxIdle; @@ -715,6 +769,7 @@ Device::reset() rxFifoPtr = rxFifo.end(); txFifo.clear(); rxEmpty = false; + rxLow = true; txFull = false; int size = virtualRegs.size(); @@ -729,7 +784,7 @@ Device::rxDmaDone() { assert(rxState == rxCopy); rxState = rxCopyDone; - DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", + DPRINTF(EthernetDMA, "end rx dma write paddr=%#x len=%d\n", rxDmaAddr, rxDmaLen); DDUMP(EthernetData, rxDmaData, rxDmaLen); @@ -743,13 +798,13 @@ Device::rxDmaDone() void Device::rxKick() { - VirtualReg *vnic; + VirtualReg *vnic = NULL; - DPRINTF(EthernetSM, "receive kick rxState=%s (rxFifo.size=%d)\n", + DPRINTF(EthernetSM, "rxKick: rxState=%s (rxFifo.size=%d)\n", RxStateStrings[rxState], rxFifo.size()); if (rxKickTick > curTick) { - DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n", + DPRINTF(EthernetSM, "rxKick: exiting, can't run till %d\n", rxKickTick); return; } @@ -758,16 +813,50 @@ Device::rxKick() if (rxState == rxIdle) goto exit; - assert(!rxList.empty()); - vnic = &virtualRegs[rxList.front()]; + if (rxActive == -1) { + if (rxState != rxFifoBlock) + panic("no active vnic while in state %s", RxStateStrings[rxState]); - DPRINTF(EthernetSM, "processing rxState=%s for virtual nic %d\n", - RxStateStrings[rxState], rxList.front()); + DPRINTF(EthernetSM, "processing rxState=%s\n", + RxStateStrings[rxState]); + } else { + vnic = &virtualRegs[rxActive]; + DPRINTF(EthernetSM, + "processing rxState=%s for vnic %d (rxunique %d)\n", + RxStateStrings[rxState], rxActive, vnic->rxUnique); + } switch (rxState) { case rxFifoBlock: - if (vnic->rxPacket != rxFifo.end()) { + if (DTRACE(EthernetSM)) { + PacketFifo::iterator end = rxFifo.end(); + int size = virtualRegs.size(); + for (int i = 0; i < size; ++i) { + VirtualReg *vn = &virtualRegs[i]; + if (vn->rxPacket != end && + !Regs::get_RxDone_Busy(vn->RxDone)) { + DPRINTF(EthernetSM, + "vnic %d (rxunique %d), has outstanding packet %d\n", + i, vn->rxUnique, + rxFifo.countPacketsBefore(vn->rxPacket)); + } + } + } + + if (!rxBusy.empty()) { + rxActive = rxBusy.front(); + rxBusy.pop_front(); + vnic = &virtualRegs[rxActive]; + + if (vnic->rxPacket == rxFifo.end()) + panic("continuing vnic without packet\n"); + + DPRINTF(EthernetSM, + "continue processing for vnic %d (rxunique %d)\n", + rxActive, vnic->rxUnique); + rxState = rxBeginCopy; + break; } @@ -776,8 +865,19 @@ Device::rxKick() goto exit; } + if (rxList.empty()) + panic("Not idle, but nothing to do!"); + assert(!rxFifo.empty()); + rxActive = rxList.front(); + rxList.pop_front(); + vnic = &virtualRegs[rxActive]; + + DPRINTF(EthernetSM, + "processing new packet for vnic %d (rxunique %d)\n", + rxActive, vnic->rxUnique); + // Grab a new packet from the fifo. vnic->rxPacket = rxFifoPtr++; vnic->rxPacketOffset = 0; @@ -788,6 +888,7 @@ Device::rxKick() /* scope for variables */ { IpPtr ip(*vnic->rxPacket); if (ip) { + DPRINTF(Ethernet, "ID is %d\n", ip->id()); vnic->rxDoneData |= Regs::RxDone_IpPacket; rxIpChecksums++; if (cksum(ip) != 0) { @@ -797,6 +898,10 @@ Device::rxKick() TcpPtr tcp(ip); UdpPtr udp(ip); if (tcp) { + DPRINTF(Ethernet, + "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", + tcp->sport(), tcp->dport(), tcp->seq(), + tcp->ack()); vnic->rxDoneData |= Regs::RxDone_TcpPacket; rxTcpChecksums++; if (cksum(tcp) != 0) { @@ -826,6 +931,11 @@ Device::rxKick() vnic->rxPacketBytes); rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset; rxState = rxCopy; + if (rxDmaAddr == 1LL) { + rxState = rxCopyDone; + break; + } + dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData); break; @@ -835,31 +945,44 @@ Device::rxKick() goto exit; case rxCopyDone: - vnic->RxDone = vnic->rxDoneData | rxDmaLen; + vnic->RxDone = vnic->rxDoneData; vnic->RxDone |= Regs::RxDone_Complete; if (vnic->rxPacketBytes == rxDmaLen) { - DPRINTF(EthernetSM, "rxKick: packet complete on vnic %d\n", - rxList.front()); + // Packet is complete. Indicate how many bytes were copied + vnic->RxDone = Regs::set_RxDone_CopyLen(vnic->RxDone, rxDmaLen); + + DPRINTF(EthernetSM, + "rxKick: packet complete on vnic %d (rxunique %d)\n", + rxActive, vnic->rxUnique); rxFifo.remove(vnic->rxPacket); vnic->rxPacket = rxFifo.end(); } else { - vnic->RxDone |= Regs::RxDone_More; vnic->rxPacketBytes -= rxDmaLen; vnic->rxPacketOffset += rxDmaLen; + vnic->RxDone |= Regs::RxDone_More; + vnic->RxDone = Regs::set_RxDone_CopyLen(vnic->RxDone, + vnic->rxPacketBytes); DPRINTF(EthernetSM, - "rxKick: packet not complete on vnic %d: %d bytes left\n", - rxList.front(), vnic->rxPacketBytes); + "rxKick: packet not complete on vnic %d (rxunique %d): " + "%d bytes left\n", + rxActive, vnic->rxUnique, vnic->rxPacketBytes); } - rxList.pop_front(); - rxState = rxList.empty() ? rxIdle : rxFifoBlock; + rxActive = -1; + rxState = rxBusy.empty() && rxList.empty() ? rxIdle : rxFifoBlock; if (rxFifo.empty()) { devIntrPost(Regs::Intr_RxEmpty); rxEmpty = true; } + if (rxFifo.size() < params()->rx_fifo_low_mark) + rxLow = true; + + if (rxFifo.size() > params()->rx_fifo_threshold) + rxLow = false; + devIntrPost(Regs::Intr_RxDMA); break; @@ -920,8 +1043,10 @@ Device::transmit() DPRINTF(Ethernet, "ID is %d\n", ip->id()); TcpPtr tcp(ip); if (tcp) { - DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n", - tcp->sport(), tcp->dport()); + DPRINTF(Ethernet, + "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", + tcp->sport(), tcp->dport(), tcp->seq(), + tcp->ack()); } } } @@ -950,11 +1075,11 @@ void Device::txKick() { VirtualReg *vnic; - DPRINTF(EthernetSM, "transmit kick txState=%s (txFifo.size=%d)\n", + DPRINTF(EthernetSM, "txKick: txState=%s (txFifo.size=%d)\n", TxStateStrings[txState], txFifo.size()); if (txKickTick > curTick) { - DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n", + DPRINTF(EthernetSM, "txKick: exiting, can't run till %d\n", txKickTick); return; } @@ -968,7 +1093,7 @@ Device::txKick() switch (txState) { case txFifoBlock: - assert(Regs::get_TxDone_Busy(vnic->TxData)); + assert(Regs::get_TxDone_Busy(vnic->TxDone)); if (!txPacket) { // Grab a new packet from the fifo. txPacket = new EthPacketData(16384); @@ -1213,6 +1338,8 @@ Base::unserialize(Checkpoint *cp, const std::string §ion) void Device::serialize(std::ostream &os) { + int count; + // Serialize the PciDev base class Base::serialize(os); @@ -1233,6 +1360,7 @@ Device::serialize(std::ostream &os) SERIALIZE_SCALAR(regs.RxMaxCopy); SERIALIZE_SCALAR(regs.TxMaxCopy); SERIALIZE_SCALAR(regs.RxMaxIntr); + SERIALIZE_SCALAR(regs.VirtualCount); SERIALIZE_SCALAR(regs.RxData); SERIALIZE_SCALAR(regs.RxDone); SERIALIZE_SCALAR(regs.TxData); @@ -1252,8 +1380,6 @@ Device::serialize(std::ostream &os) paramOut(os, reg + ".TxData", vnic->TxData); paramOut(os, reg + ".TxDone", vnic->TxDone); - PacketFifo::iterator rxFifoPtr; - bool rxPacketExists = vnic->rxPacket != rxFifo.end(); paramOut(os, reg + ".rxPacketExists", rxPacketExists); if (rxPacketExists) { @@ -1272,18 +1398,26 @@ Device::serialize(std::ostream &os) paramOut(os, reg + ".rxDoneData", vnic->rxDoneData); } - VirtualList::iterator i, end; - int count; + int rxFifoPtr = rxFifo.countPacketsBefore(this->rxFifoPtr); + SERIALIZE_SCALAR(rxFifoPtr); - int rxListSize = rxList.size(); - SERIALIZE_SCALAR(rxListSize); + SERIALIZE_SCALAR(rxActive); + + VirtualList::iterator i, end; for (count = 0, i = rxList.begin(), end = rxList.end(); i != end; ++i) paramOut(os, csprintf("rxList%d", count++), *i); + int rxListSize = count; + SERIALIZE_SCALAR(rxListSize); + + for (count = 0, i = rxBusy.begin(), end = rxBusy.end(); i != end; ++i) + paramOut(os, csprintf("rxBusy%d", count++), *i); + int rxBusySize = count; + SERIALIZE_SCALAR(rxBusySize); - int txListSize = txList.size(); - SERIALIZE_SCALAR(txListSize); for (count = 0, i = txList.begin(), end = txList.end(); i != end; ++i) paramOut(os, csprintf("txList%d", count++), *i); + int txListSize = count; + SERIALIZE_SCALAR(txListSize); /* * Serialize rx state machine @@ -1291,6 +1425,7 @@ Device::serialize(std::ostream &os) int rxState = this->rxState; SERIALIZE_SCALAR(rxState); SERIALIZE_SCALAR(rxEmpty); + SERIALIZE_SCALAR(rxLow); rxFifo.serialize("rxFifo", os); /* @@ -1331,11 +1466,14 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(regs.RxMaxCopy); UNSERIALIZE_SCALAR(regs.TxMaxCopy); UNSERIALIZE_SCALAR(regs.RxMaxIntr); + UNSERIALIZE_SCALAR(regs.VirtualCount); UNSERIALIZE_SCALAR(regs.RxData); UNSERIALIZE_SCALAR(regs.RxDone); UNSERIALIZE_SCALAR(regs.TxData); UNSERIALIZE_SCALAR(regs.TxDone); + UNSERIALIZE_SCALAR(rxActive); + int rxListSize; UNSERIALIZE_SCALAR(rxListSize); rxList.clear(); @@ -1345,6 +1483,15 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) rxList.push_back(value); } + int rxBusySize; + UNSERIALIZE_SCALAR(rxBusySize); + rxBusy.clear(); + for (int i = 0; i < rxBusySize; ++i) { + int value; + paramIn(cp, section, csprintf("rxBusy%d", i), value); + rxBusy.push_back(value); + } + int txListSize; UNSERIALIZE_SCALAR(txListSize); txList.clear(); @@ -1360,9 +1507,16 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) int rxState; UNSERIALIZE_SCALAR(rxState); UNSERIALIZE_SCALAR(rxEmpty); + UNSERIALIZE_SCALAR(rxLow); this->rxState = (RxState) rxState; rxFifo.unserialize("rxFifo", cp, section); + int rxFifoPtr; + UNSERIALIZE_SCALAR(rxFifoPtr); + this->rxFifoPtr = rxFifo.begin(); + for (int i = 0; i < rxFifoPtr; ++i) + ++this->rxFifoPtr; + /* * Unserialize tx state machine */ @@ -1400,6 +1554,9 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) paramIn(cp, section, reg + ".TxData", vnic->TxData); paramIn(cp, section, reg + ".TxDone", vnic->TxDone); + vnic->rxUnique = rxUnique++; + vnic->txUnique = txUnique++; + bool rxPacketExists; paramIn(cp, section, reg + ".rxPacketExists", rxPacketExists); if (rxPacketExists) { @@ -1488,6 +1645,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) Param<uint32_t> rx_fifo_size; Param<uint32_t> tx_fifo_size; Param<uint32_t> rx_fifo_threshold; + Param<uint32_t> rx_fifo_low_mark; + Param<uint32_t> tx_fifo_high_mark; Param<uint32_t> tx_fifo_threshold; Param<bool> rx_filter; @@ -1495,6 +1654,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) Param<bool> rx_thread; Param<bool> tx_thread; Param<bool> rss; + Param<uint32_t> virtual_count; + Param<bool> zero_copy; + Param<bool> delay_copy; + Param<bool> virtual_addr; END_DECLARE_SIM_OBJECT_PARAMS(Device) @@ -1525,13 +1688,19 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device) INIT_PARAM(rx_fifo_size, "max size in bytes of rxFifo"), INIT_PARAM(tx_fifo_size, "max size in bytes of txFifo"), INIT_PARAM(rx_fifo_threshold, "max size in bytes of rxFifo"), + INIT_PARAM(rx_fifo_low_mark, "max size in bytes of rxFifo"), + INIT_PARAM(tx_fifo_high_mark, "max size in bytes of txFifo"), INIT_PARAM(tx_fifo_threshold, "max size in bytes of txFifo"), INIT_PARAM(rx_filter, "Enable Receive Filter"), INIT_PARAM(hardware_address, "Ethernet Hardware Address"), INIT_PARAM(rx_thread, ""), INIT_PARAM(tx_thread, ""), - INIT_PARAM(rss, "") + INIT_PARAM(rss, ""), + INIT_PARAM(virtual_count, ""), + INIT_PARAM(zero_copy, ""), + INIT_PARAM(delay_copy, ""), + INIT_PARAM(virtual_addr, "") END_INIT_SIM_OBJECT_PARAMS(Device) @@ -1564,6 +1733,8 @@ CREATE_SIM_OBJECT(Device) params->rx_fifo_size = rx_fifo_size; params->tx_fifo_size = tx_fifo_size; params->rx_fifo_threshold = rx_fifo_threshold; + params->rx_fifo_low_mark = rx_fifo_low_mark; + params->tx_fifo_high_mark = tx_fifo_high_mark; params->tx_fifo_threshold = tx_fifo_threshold; params->rx_filter = rx_filter; @@ -1571,6 +1742,10 @@ CREATE_SIM_OBJECT(Device) params->rx_thread = rx_thread; params->tx_thread = tx_thread; params->rss = rss; + params->virtual_count = virtual_count; + params->zero_copy = zero_copy; + params->delay_copy = delay_copy; + params->virtual_addr = virtual_addr; return new Device(params); } diff --git a/dev/sinic.hh b/dev/sinic.hh index 63a8585dc..a786c3e44 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -117,7 +117,7 @@ class Device : public Base uint32_t RxMaxCopy; // 0x10 uint32_t TxMaxCopy; // 0x14 uint32_t RxMaxIntr; // 0x18 - uint32_t Reserved0; // 0x1c + uint32_t VirtualCount; // 0x1c uint32_t RxFifoSize; // 0x20 uint32_t TxFifoSize; // 0x24 uint32_t RxFifoMark; // 0x28 @@ -142,6 +142,9 @@ class Device : public Base int rxPacketBytes; uint64_t rxDoneData; + Counter rxUnique; + Counter txUnique; + VirtualReg() : RxData(0), RxDone(0), TxData(0), TxDone(0), rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) @@ -149,8 +152,12 @@ class Device : public Base }; typedef std::vector<VirtualReg> VirtualRegs; typedef std::list<int> VirtualList; + Counter rxUnique; + Counter txUnique; VirtualRegs virtualRegs; VirtualList rxList; + VirtualList rxBusy; + int rxActive; VirtualList txList; uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } @@ -162,6 +169,7 @@ class Device : public Base PacketFifo rxFifo; PacketFifo::iterator rxFifoPtr; bool rxEmpty; + bool rxLow; Addr rxDmaAddr; uint8_t *rxDmaData; int rxDmaLen; @@ -318,6 +326,8 @@ class Device : public Base uint32_t rx_fifo_size; uint32_t tx_fifo_size; uint32_t rx_fifo_threshold; + uint32_t rx_fifo_low_mark; + uint32_t tx_fifo_high_mark; uint32_t tx_fifo_threshold; Tick dma_read_delay; Tick dma_read_factor; @@ -326,6 +336,10 @@ class Device : public Base bool rx_thread; bool tx_thread; bool rss; + uint32_t virtual_count; + bool zero_copy; + bool delay_copy; + bool virtual_addr; }; protected: diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh index f90432398..d41eb5b16 100644 --- a/dev/sinicreg.hh +++ b/dev/sinicreg.hh @@ -55,38 +55,40 @@ namespace Sinic { namespace Regs { -static const int VirtualMask = 0xff; static const int VirtualShift = 8; +static const int VirtualMask = 0xff; // Registers -__SINIC_REG32(Config, 0x00); // 32: configuration register -__SINIC_REG32(Command, 0x04); // 32: command register -__SINIC_REG32(IntrStatus, 0x08); // 32: interrupt status -__SINIC_REG32(IntrMask, 0x0c); // 32: interrupt mask -__SINIC_REG32(RxMaxCopy, 0x10); // 32: max bytes per rx copy -__SINIC_REG32(TxMaxCopy, 0x14); // 32: max bytes per tx copy -__SINIC_REG32(RxMaxIntr, 0x18); // 32: max receives per interrupt -__SINIC_REG32(Reserved0, 0x1c); // 32: reserved -__SINIC_REG32(RxFifoSize, 0x20); // 32: rx fifo capacity in bytes -__SINIC_REG32(TxFifoSize, 0x24); // 32: tx fifo capacity in bytes -__SINIC_REG32(RxFifoMark, 0x28); // 32: rx fifo high watermark -__SINIC_REG32(TxFifoMark, 0x2c); // 32: tx fifo low watermark -__SINIC_REG32(RxData, 0x30); // 64: receive data -__SINIC_REG32(RxDone, 0x38); // 64: receive done -__SINIC_REG32(RxWait, 0x40); // 64: receive done (busy wait) -__SINIC_REG32(TxData, 0x48); // 64: transmit data -__SINIC_REG32(TxDone, 0x50); // 64: transmit done -__SINIC_REG32(TxWait, 0x58); // 64: transmit done (busy wait) -__SINIC_REG32(HwAddr, 0x60); // 64: mac address -__SINIC_REG32(Size, 0x68); // register addres space size +__SINIC_REG32(Config, 0x00); // 32: configuration register +__SINIC_REG32(Command, 0x04); // 32: command register +__SINIC_REG32(IntrStatus, 0x08); // 32: interrupt status +__SINIC_REG32(IntrMask, 0x0c); // 32: interrupt mask +__SINIC_REG32(RxMaxCopy, 0x10); // 32: max bytes per rx copy +__SINIC_REG32(TxMaxCopy, 0x14); // 32: max bytes per tx copy +__SINIC_REG32(RxMaxIntr, 0x18); // 32: max receives per interrupt +__SINIC_REG32(VirtualCount, 0x1c); // 32: number of virutal NICs +__SINIC_REG32(RxFifoSize, 0x20); // 32: rx fifo capacity in bytes +__SINIC_REG32(TxFifoSize, 0x24); // 32: tx fifo capacity in bytes +__SINIC_REG32(RxFifoMark, 0x28); // 32: rx fifo high watermark +__SINIC_REG32(TxFifoMark, 0x2c); // 32: tx fifo low watermark +__SINIC_REG32(RxData, 0x30); // 64: receive data +__SINIC_REG32(RxDone, 0x38); // 64: receive done +__SINIC_REG32(RxWait, 0x40); // 64: receive done (busy wait) +__SINIC_REG32(TxData, 0x48); // 64: transmit data +__SINIC_REG32(TxDone, 0x50); // 64: transmit done +__SINIC_REG32(TxWait, 0x58); // 64: transmit done (busy wait) +__SINIC_REG32(HwAddr, 0x60); // 64: mac address +__SINIC_REG32(Size, 0x68); // register addres space size // Config register bits +__SINIC_VAL32(Config_ZeroCopy, 12, 1); // enable zero copy +__SINIC_VAL32(Config_DelayCopy,11, 1); // enable delayed copy __SINIC_VAL32(Config_RSS, 10, 1); // enable receive side scaling __SINIC_VAL32(Config_RxThread, 9, 1); // enable receive threads __SINIC_VAL32(Config_TxThread, 8, 1); // enable transmit thread __SINIC_VAL32(Config_Filter, 7, 1); // enable receive filter __SINIC_VAL32(Config_Vlan, 6, 1); // enable vlan tagging -__SINIC_VAL32(Config_Virtual, 5, 1); // enable virtual addressing +__SINIC_VAL32(Config_Vaddr, 5, 1); // enable virtual addressing __SINIC_VAL32(Config_Desc, 4, 1); // enable tx/rx descriptors __SINIC_VAL32(Config_Poll, 3, 1); // enable polling __SINIC_VAL32(Config_IntEn, 2, 1); // enable interrupts @@ -112,13 +114,15 @@ __SINIC_REG32(Intr_NoDelay, 0x01cc); // interrupts that aren't coalesced __SINIC_REG32(Intr_Res, ~0x01ff); // reserved interrupt bits // RX Data Description -__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 1M -__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB +__SINIC_VAL64(RxData_Vaddr, 60, 1); // Addr is virtual +__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 256k +__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB // TX Data Description __SINIC_VAL64(TxData_More, 63, 1); // Packet not complete (will dma more) __SINIC_VAL64(TxData_Checksum, 62, 1); // do checksum -__SINIC_VAL64(TxData_Len, 40, 20); // 0 - 1M +__SINIC_VAL64(TxData_Vaddr, 60, 1); // Addr is virtual +__SINIC_VAL64(TxData_Len, 40, 20); // 0 - 256k __SINIC_VAL64(TxData_Addr, 0, 40); // Address 1TB // RX Done/Busy Information @@ -126,9 +130,9 @@ __SINIC_VAL64(RxDone_Packets, 32, 16); // number of packets in rx fifo __SINIC_VAL64(RxDone_Busy, 31, 1); // receive dma busy copying __SINIC_VAL64(RxDone_Complete, 30, 1); // valid data (packet complete) __SINIC_VAL64(RxDone_More, 29, 1); // Packet has more data (dma again) -__SINIC_VAL64(RxDone_Res0, 28, 1); // reserved -__SINIC_VAL64(RxDone_Res1, 27, 1); // reserved -__SINIC_VAL64(RxDone_Res2, 26, 1); // reserved +__SINIC_VAL64(RxDone_Empty, 28, 1); // rx fifo is empty +__SINIC_VAL64(RxDone_High, 27, 1); // rx fifo is above the watermark +__SINIC_VAL64(RxDone_NotHigh, 26, 1); // rxfifo never hit the high watermark __SINIC_VAL64(RxDone_TcpError, 25, 1); // TCP packet error (bad checksum) __SINIC_VAL64(RxDone_UdpError, 24, 1); // UDP packet error (bad checksum) __SINIC_VAL64(RxDone_IpError, 23, 1); // IP packet error (bad checksum) @@ -175,7 +179,7 @@ regInfo(Addr daddr) { 4, true, false, "RxMaxCopy" }, { 4, true, false, "TxMaxCopy" }, { 4, true, false, "RxMaxIntr" }, - invalid, + { 4, true, false, "VirtualCount" }, { 4, true, false, "RxFifoSize" }, { 4, true, false, "TxFifoSize" }, { 4, true, false, "RxFifoMark" }, diff --git a/python/m5/objects/Ethernet.py b/python/m5/objects/Ethernet.py index 0667fc6d7..4286c71c8 100644 --- a/python/m5/objects/Ethernet.py +++ b/python/m5/objects/Ethernet.py @@ -101,8 +101,14 @@ class Sinic(EtherDevBase): rx_max_copy = Param.MemorySize('1514B', "rx max copy") tx_max_copy = Param.MemorySize('16kB', "tx max copy") rx_max_intr = Param.UInt32(10, "max rx packets per interrupt") - rx_fifo_threshold = Param.MemorySize('48kB', "rx fifo high threshold") - tx_fifo_threshold = Param.MemorySize('16kB', "tx fifo low threshold") + rx_fifo_threshold = Param.MemorySize('384kB', "rx fifo high threshold") + rx_fifo_low_mark = Param.MemorySize('128kB', "rx fifo low threshold") + tx_fifo_high_mark = Param.MemorySize('384kB', "tx fifo high threshold") + tx_fifo_threshold = Param.MemorySize('128kB', "tx fifo low threshold") + virtual_count = Param.UInt32(1, "Virtualized SINIC") + zero_copy = Param.Bool(False, "Zero copy receive") + delay_copy = Param.Bool(False, "Delayed copy transmit") + virtual_addr = Param.Bool(False, "Virtual addressing") class SinicInt(EtherInt): type = 'SinicInt' diff --git a/sim/serialize.cc b/sim/serialize.cc index ec7241498..c4ef124bb 100644 --- a/sim/serialize.cc +++ b/sim/serialize.cc @@ -51,8 +51,9 @@ using namespace std; -int Serializable::maxCount = 0; -int Serializable::count = 0; +int Serializable::ckptMaxCount = 0; +int Serializable::ckptCount = 0; +int Serializable::ckptPrevCount = -1; void Serializable::nameOut(ostream &os) @@ -241,8 +242,11 @@ Serializable::serializeAll() globals.serialize(outstream); SimObject::serializeAll(outstream); - if (maxCount && ++count >= maxCount) + assert(Serializable::ckptPrevCount + 1 == Serializable::ckptCount); + Serializable::ckptPrevCount++; + if (ckptMaxCount && ++ckptCount >= ckptMaxCount) SimExit(curTick + 1, "Maximum number of checkpoints dropped"); + } @@ -352,7 +356,7 @@ SerializeParamContext::checkParams() if (serialize_cycle > 0) Checkpoint::setup(serialize_cycle, serialize_period); - Serializable::maxCount = serialize_count; + Serializable::ckptMaxCount = serialize_count; } void diff --git a/sim/serialize.hh b/sim/serialize.hh index bc82bf9b8..d8f5f8fc5 100644 --- a/sim/serialize.hh +++ b/sim/serialize.hh @@ -119,8 +119,9 @@ class Serializable static Serializable *create(Checkpoint *cp, const std::string §ion); - static int count; - static int maxCount; + static int ckptCount; + static int ckptMaxCount; + static int ckptPrevCount; static void serializeAll(); static void unserializeGlobals(Checkpoint *cp); }; diff --git a/util/stats/barchart.py b/util/stats/barchart.py index 5d6dd0ab1..a477d1f3b 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -233,7 +233,7 @@ class BarChart(ChartOptions): inner_axes.set_yticks(ticks) inner_axes.set_yticklabels(self.yticks) elif self.ylim is not None: - self.inner_axes.set_ylim(self.ylim) + inner_axes.set_ylim(self.ylim) if self.xticks is not None: outer_axes.set_xticks(arange(cshape[2]) + .5) @@ -242,9 +242,9 @@ class BarChart(ChartOptions): if self.xsubticks is not None: numticks = (cshape[0] + 1) * cshape[2] inner_axes.set_xticks(arange(numticks) * width + 2 * center) - self.xsubticks.append('') - inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7, - rotation=90) + xsubticks = list(self.xsubticks) + [ '' ] + inner_axes.set_xticklabels(xsubticks * cshape[2], fontsize=7, + rotation=30) if self.legend is not None: if dim == 1: |