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
This commit is contained in:
Ali Saidi
2006-05-12 18:16:07 -04:00
9 changed files with 318 additions and 100 deletions

View File

@@ -810,7 +810,7 @@ decode OPCODE default Unknown::unknown() {
AlphaPseudo::addsymbol(xc->xcBase(), R16, R17); AlphaPseudo::addsymbol(xc->xcBase(), R16, R17);
}}, IsNonSpeculative); }}, IsNonSpeculative);
0x54: m5panic({{ 0x54: m5panic({{
panic("M5 panic instruction called."); panic("M5 panic instruction called at pc=%#x.", xc->readPC());
}}, IsNonSpeculative); }}, IsNonSpeculative);
} }

View File

@@ -33,6 +33,7 @@
#ifndef __IDE_DISK_HH__ #ifndef __IDE_DISK_HH__
#define __IDE_DISK_HH__ #define __IDE_DISK_HH__
#include "base/statistics.hh"
#include "dev/disk_image.hh" #include "dev/disk_image.hh"
#include "dev/ide_atareg.h" #include "dev/ide_atareg.h"
#include "dev/ide_ctrl.hh" #include "dev/ide_ctrl.hh"
@@ -231,6 +232,13 @@ class IdeDisk : public SimObject
/** Interrupt pending */ /** Interrupt pending */
bool intrPending; bool intrPending;
Stats::Scalar<> dmaReadFullPages;
Stats::Scalar<> dmaReadBytes;
Stats::Scalar<> dmaReadTxs;
Stats::Scalar<> dmaWriteFullPages;
Stats::Scalar<> dmaWriteBytes;
Stats::Scalar<> dmaWriteTxs;
public: public:
/** /**
* Create and initialize this Disk. * Create and initialize this Disk.
@@ -251,6 +259,12 @@ class IdeDisk : public SimObject
*/ */
void reset(int id); void reset(int id);
/**
* Register statistics.
*/
void regStats();
/** /**
* Set the controller for this device * Set the controller for this device
* @param c The IDE controller * @param c The IDE controller

View File

@@ -81,7 +81,8 @@ Base::Base(Params *p)
} }
Device::Device(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), rxKickTick(0), txKickTick(0),
txEvent(this), rxDmaEvent(this), txDmaEvent(this), txEvent(this), rxDmaEvent(this), txDmaEvent(this),
dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor), dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
@@ -268,12 +269,9 @@ void
Device::prepareIO(int cpu, int index) Device::prepareIO(int cpu, int index)
{ {
int size = virtualRegs.size(); int size = virtualRegs.size();
if (index < size) if (index > size)
return; panic("Trying to access a vnic that doesn't exist %d > %d\n",
index, size);
virtualRegs.resize(index + 1);
for (int i = size; i <= index; ++i)
virtualRegs[i].rxPacket = rxFifo.end();
} }
void void
@@ -286,7 +284,10 @@ Device::prepareRead(int cpu, int index)
// update rx registers // update rx registers
uint64_t rxdone = vnic.RxDone; 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.RxData = vnic.RxData;
regs.RxDone = rxdone; regs.RxDone = rxdone;
regs.RxWait = rxdone; regs.RxWait = rxdone;
@@ -325,17 +326,18 @@ Device::read(Packet &pkt)
pkt.allocate(); pkt.allocate();
if (!regValid(raddr)) if (!regValid(raddr))
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d",
cpu, daddr, pkt.addr, pkt.size); cpu, index, daddr, pkt.addr, pkt.size);
const Regs::Info &info = regInfo(raddr); const Regs::Info &info = regInfo(raddr);
if (!info.read) if (!info.read)
panic("reading %s (write only): cpu=%d da=%#x pa=%#x size=%d", panic("read %s (write only): "
info.name, cpu, daddr, pkt.addr, pkt.size); "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("read %s (invalid size): "
panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d", "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
info.name, cpu, daddr, pkt.addr, pkt.size); info.name, cpu, index, daddr, pkt.addr, pkt.size);
prepareRead(cpu, index); prepareRead(cpu, index);
@@ -353,8 +355,8 @@ Device::read(Packet &pkt)
} }
DPRINTF(EthernetPIO, DPRINTF(EthernetPIO,
"read %s cpu=%d da=%#x pa=%#x size=%d val=%#x\n", "read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n",
info.name, cpu, daddr, pkt.addr, pkt.size, value); info.name, cpu, index, daddr, pkt.addr, pkt.size, value);
// reading the interrupt status register has the side effect of // reading the interrupt status register has the side effect of
// clearing it // clearing it
@@ -416,18 +418,20 @@ Device::write(Packet &pkt)
const Regs::Info &info = regInfo(raddr); const Regs::Info &info = regInfo(raddr);
if (!info.write) if (!info.write)
panic("write %s (read only): cpu=%d da=%#x pa=%#x size=%d", panic("write %s (read only): "
info.name, cpu, daddr, pkt.addr, pkt.size); "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
info.name, cpu, index, daddr, pkt.addr, pkt.size);
if (pkt.size != info.size) if (pkt.size != info.size)
panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d", panic("write %s (invalid size): "
info.name, cpu, daddr, pkt.addr, pkt.size); "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
info.name, cpu, index, daddr, pkt.addr, pkt.size);
VirtualReg &vnic = virtualRegs[index]; VirtualReg &vnic = virtualRegs[index];
DPRINTF(EthernetPIO, DPRINTF(EthernetPIO,
"write %s: cpu=%d val=%#x da=%#x pa=%#x size=%d\n", "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
info.name, cpu, info.size == 4 ? pkt.get<uint32_t>() : info.name, index, cpu, info.size == 4 ? pkt.get<uint32_t>() :
pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size); pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size);
prepareWrite(cpu, index); prepareWrite(cpu, index);
@@ -454,10 +458,32 @@ Device::write(Packet &pkt)
panic("receive machine busy with another request! rxState=%s", panic("receive machine busy with another request! rxState=%s",
RxStateStrings[rxState]); RxStateStrings[rxState]);
vnic.rxUnique = rxUnique++;
vnic.RxDone = Regs::RxDone_Busy; vnic.RxDone = Regs::RxDone_Busy;
vnic.RxData = pkt.get<uint64_t>(); 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; rxState = rxFifoBlock;
rxKick(); rxKick();
} }
@@ -468,8 +494,23 @@ Device::write(Packet &pkt)
panic("transmit machine busy with another request! txState=%s", panic("transmit machine busy with another request! txState=%s",
TxStateStrings[txState]); TxStateStrings[txState]);
vnic.txUnique = txUnique++;
vnic.TxDone = Regs::TxDone_Busy; 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) if (txList.empty() || txList.front() != index)
txList.push_back(index); txList.push_back(index);
if (txEnable && txState == txIdle && txList.front() == index) { if (txEnable && txState == txIdle && txList.front() == index) {
@@ -695,10 +736,21 @@ Device::reset()
regs.Config |= Config_TxThread; regs.Config |= Config_TxThread;
if (params()->rss) if (params()->rss)
regs.Config |= Config_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.IntrMask = Intr_Soft | Intr_RxHigh | Intr_RxPacket | Intr_TxLow;
regs.RxMaxCopy = params()->rx_max_copy; regs.RxMaxCopy = params()->rx_max_copy;
regs.TxMaxCopy = params()->tx_max_copy; regs.TxMaxCopy = params()->tx_max_copy;
regs.RxMaxIntr = params()->rx_max_intr; regs.RxMaxIntr = params()->rx_max_intr;
regs.VirtualCount = params()->virtual_count;
regs.RxFifoSize = params()->rx_fifo_size; regs.RxFifoSize = params()->rx_fifo_size;
regs.TxFifoSize = params()->tx_fifo_size; regs.TxFifoSize = params()->tx_fifo_size;
regs.RxFifoMark = params()->rx_fifo_threshold; regs.RxFifoMark = params()->rx_fifo_threshold;
@@ -706,6 +758,8 @@ Device::reset()
regs.HwAddr = params()->eaddr; regs.HwAddr = params()->eaddr;
rxList.clear(); rxList.clear();
rxBusy.clear();
rxActive = -1;
txList.clear(); txList.clear();
rxState = rxIdle; rxState = rxIdle;
@@ -715,6 +769,7 @@ Device::reset()
rxFifoPtr = rxFifo.end(); rxFifoPtr = rxFifo.end();
txFifo.clear(); txFifo.clear();
rxEmpty = false; rxEmpty = false;
rxLow = true;
txFull = false; txFull = false;
int size = virtualRegs.size(); int size = virtualRegs.size();
@@ -729,7 +784,7 @@ Device::rxDmaDone()
{ {
assert(rxState == rxCopy); assert(rxState == rxCopy);
rxState = rxCopyDone; 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); rxDmaAddr, rxDmaLen);
DDUMP(EthernetData, rxDmaData, rxDmaLen); DDUMP(EthernetData, rxDmaData, rxDmaLen);
@@ -743,13 +798,13 @@ Device::rxDmaDone()
void void
Device::rxKick() 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()); RxStateStrings[rxState], rxFifo.size());
if (rxKickTick > curTick) { 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); rxKickTick);
return; return;
} }
@@ -758,16 +813,50 @@ Device::rxKick()
if (rxState == rxIdle) if (rxState == rxIdle)
goto exit; goto exit;
assert(!rxList.empty()); if (rxActive == -1) {
vnic = &virtualRegs[rxList.front()]; if (rxState != rxFifoBlock)
panic("no active vnic while in state %s", RxStateStrings[rxState]);
DPRINTF(EthernetSM, "processing rxState=%s for virtual nic %d\n", DPRINTF(EthernetSM, "processing rxState=%s\n",
RxStateStrings[rxState], rxList.front()); RxStateStrings[rxState]);
} else {
vnic = &virtualRegs[rxActive];
DPRINTF(EthernetSM,
"processing rxState=%s for vnic %d (rxunique %d)\n",
RxStateStrings[rxState], rxActive, vnic->rxUnique);
}
switch (rxState) { switch (rxState) {
case rxFifoBlock: 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; rxState = rxBeginCopy;
break; break;
} }
@@ -776,8 +865,19 @@ Device::rxKick()
goto exit; goto exit;
} }
if (rxList.empty())
panic("Not idle, but nothing to do!");
assert(!rxFifo.empty()); 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. // Grab a new packet from the fifo.
vnic->rxPacket = rxFifoPtr++; vnic->rxPacket = rxFifoPtr++;
vnic->rxPacketOffset = 0; vnic->rxPacketOffset = 0;
@@ -788,6 +888,7 @@ Device::rxKick()
/* scope for variables */ { /* scope for variables */ {
IpPtr ip(*vnic->rxPacket); IpPtr ip(*vnic->rxPacket);
if (ip) { if (ip) {
DPRINTF(Ethernet, "ID is %d\n", ip->id());
vnic->rxDoneData |= Regs::RxDone_IpPacket; vnic->rxDoneData |= Regs::RxDone_IpPacket;
rxIpChecksums++; rxIpChecksums++;
if (cksum(ip) != 0) { if (cksum(ip) != 0) {
@@ -797,6 +898,10 @@ Device::rxKick()
TcpPtr tcp(ip); TcpPtr tcp(ip);
UdpPtr udp(ip); UdpPtr udp(ip);
if (tcp) { 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; vnic->rxDoneData |= Regs::RxDone_TcpPacket;
rxTcpChecksums++; rxTcpChecksums++;
if (cksum(tcp) != 0) { if (cksum(tcp) != 0) {
@@ -826,6 +931,11 @@ Device::rxKick()
vnic->rxPacketBytes); vnic->rxPacketBytes);
rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset; rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset;
rxState = rxCopy; rxState = rxCopy;
if (rxDmaAddr == 1LL) {
rxState = rxCopyDone;
break;
}
dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData); dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData);
break; break;
@@ -835,31 +945,44 @@ Device::rxKick()
goto exit; goto exit;
case rxCopyDone: case rxCopyDone:
vnic->RxDone = vnic->rxDoneData | rxDmaLen; vnic->RxDone = vnic->rxDoneData;
vnic->RxDone |= Regs::RxDone_Complete; vnic->RxDone |= Regs::RxDone_Complete;
if (vnic->rxPacketBytes == rxDmaLen) { if (vnic->rxPacketBytes == rxDmaLen) {
DPRINTF(EthernetSM, "rxKick: packet complete on vnic %d\n", // Packet is complete. Indicate how many bytes were copied
rxList.front()); 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); rxFifo.remove(vnic->rxPacket);
vnic->rxPacket = rxFifo.end(); vnic->rxPacket = rxFifo.end();
} else { } else {
vnic->RxDone |= Regs::RxDone_More;
vnic->rxPacketBytes -= rxDmaLen; vnic->rxPacketBytes -= rxDmaLen;
vnic->rxPacketOffset += rxDmaLen; vnic->rxPacketOffset += rxDmaLen;
vnic->RxDone |= Regs::RxDone_More;
vnic->RxDone = Regs::set_RxDone_CopyLen(vnic->RxDone,
vnic->rxPacketBytes);
DPRINTF(EthernetSM, DPRINTF(EthernetSM,
"rxKick: packet not complete on vnic %d: %d bytes left\n", "rxKick: packet not complete on vnic %d (rxunique %d): "
rxList.front(), vnic->rxPacketBytes); "%d bytes left\n",
rxActive, vnic->rxUnique, vnic->rxPacketBytes);
} }
rxList.pop_front(); rxActive = -1;
rxState = rxList.empty() ? rxIdle : rxFifoBlock; rxState = rxBusy.empty() && rxList.empty() ? rxIdle : rxFifoBlock;
if (rxFifo.empty()) { if (rxFifo.empty()) {
devIntrPost(Regs::Intr_RxEmpty); devIntrPost(Regs::Intr_RxEmpty);
rxEmpty = true; 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); devIntrPost(Regs::Intr_RxDMA);
break; break;
@@ -920,8 +1043,10 @@ Device::transmit()
DPRINTF(Ethernet, "ID is %d\n", ip->id()); DPRINTF(Ethernet, "ID is %d\n", ip->id());
TcpPtr tcp(ip); TcpPtr tcp(ip);
if (tcp) { if (tcp) {
DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n", DPRINTF(Ethernet,
tcp->sport(), tcp->dport()); "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() Device::txKick()
{ {
VirtualReg *vnic; 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()); TxStateStrings[txState], txFifo.size());
if (txKickTick > curTick) { 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); txKickTick);
return; return;
} }
@@ -968,7 +1093,7 @@ Device::txKick()
switch (txState) { switch (txState) {
case txFifoBlock: case txFifoBlock:
assert(Regs::get_TxDone_Busy(vnic->TxData)); assert(Regs::get_TxDone_Busy(vnic->TxDone));
if (!txPacket) { if (!txPacket) {
// Grab a new packet from the fifo. // Grab a new packet from the fifo.
txPacket = new EthPacketData(16384); txPacket = new EthPacketData(16384);
@@ -1213,6 +1338,8 @@ Base::unserialize(Checkpoint *cp, const std::string &section)
void void
Device::serialize(std::ostream &os) Device::serialize(std::ostream &os)
{ {
int count;
// Serialize the PciDev base class // Serialize the PciDev base class
Base::serialize(os); Base::serialize(os);
@@ -1233,6 +1360,7 @@ Device::serialize(std::ostream &os)
SERIALIZE_SCALAR(regs.RxMaxCopy); SERIALIZE_SCALAR(regs.RxMaxCopy);
SERIALIZE_SCALAR(regs.TxMaxCopy); SERIALIZE_SCALAR(regs.TxMaxCopy);
SERIALIZE_SCALAR(regs.RxMaxIntr); SERIALIZE_SCALAR(regs.RxMaxIntr);
SERIALIZE_SCALAR(regs.VirtualCount);
SERIALIZE_SCALAR(regs.RxData); SERIALIZE_SCALAR(regs.RxData);
SERIALIZE_SCALAR(regs.RxDone); SERIALIZE_SCALAR(regs.RxDone);
SERIALIZE_SCALAR(regs.TxData); SERIALIZE_SCALAR(regs.TxData);
@@ -1252,8 +1380,6 @@ Device::serialize(std::ostream &os)
paramOut(os, reg + ".TxData", vnic->TxData); paramOut(os, reg + ".TxData", vnic->TxData);
paramOut(os, reg + ".TxDone", vnic->TxDone); paramOut(os, reg + ".TxDone", vnic->TxDone);
PacketFifo::iterator rxFifoPtr;
bool rxPacketExists = vnic->rxPacket != rxFifo.end(); bool rxPacketExists = vnic->rxPacket != rxFifo.end();
paramOut(os, reg + ".rxPacketExists", rxPacketExists); paramOut(os, reg + ".rxPacketExists", rxPacketExists);
if (rxPacketExists) { if (rxPacketExists) {
@@ -1272,18 +1398,26 @@ Device::serialize(std::ostream &os)
paramOut(os, reg + ".rxDoneData", vnic->rxDoneData); paramOut(os, reg + ".rxDoneData", vnic->rxDoneData);
} }
VirtualList::iterator i, end; int rxFifoPtr = rxFifo.countPacketsBefore(this->rxFifoPtr);
int count; SERIALIZE_SCALAR(rxFifoPtr);
int rxListSize = rxList.size(); SERIALIZE_SCALAR(rxActive);
SERIALIZE_SCALAR(rxListSize);
VirtualList::iterator i, end;
for (count = 0, i = rxList.begin(), end = rxList.end(); i != end; ++i) for (count = 0, i = rxList.begin(), end = rxList.end(); i != end; ++i)
paramOut(os, csprintf("rxList%d", count++), *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) for (count = 0, i = txList.begin(), end = txList.end(); i != end; ++i)
paramOut(os, csprintf("txList%d", count++), *i); paramOut(os, csprintf("txList%d", count++), *i);
int txListSize = count;
SERIALIZE_SCALAR(txListSize);
/* /*
* Serialize rx state machine * Serialize rx state machine
@@ -1291,6 +1425,7 @@ Device::serialize(std::ostream &os)
int rxState = this->rxState; int rxState = this->rxState;
SERIALIZE_SCALAR(rxState); SERIALIZE_SCALAR(rxState);
SERIALIZE_SCALAR(rxEmpty); SERIALIZE_SCALAR(rxEmpty);
SERIALIZE_SCALAR(rxLow);
rxFifo.serialize("rxFifo", os); rxFifo.serialize("rxFifo", os);
/* /*
@@ -1331,11 +1466,14 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(regs.RxMaxCopy); UNSERIALIZE_SCALAR(regs.RxMaxCopy);
UNSERIALIZE_SCALAR(regs.TxMaxCopy); UNSERIALIZE_SCALAR(regs.TxMaxCopy);
UNSERIALIZE_SCALAR(regs.RxMaxIntr); UNSERIALIZE_SCALAR(regs.RxMaxIntr);
UNSERIALIZE_SCALAR(regs.VirtualCount);
UNSERIALIZE_SCALAR(regs.RxData); UNSERIALIZE_SCALAR(regs.RxData);
UNSERIALIZE_SCALAR(regs.RxDone); UNSERIALIZE_SCALAR(regs.RxDone);
UNSERIALIZE_SCALAR(regs.TxData); UNSERIALIZE_SCALAR(regs.TxData);
UNSERIALIZE_SCALAR(regs.TxDone); UNSERIALIZE_SCALAR(regs.TxDone);
UNSERIALIZE_SCALAR(rxActive);
int rxListSize; int rxListSize;
UNSERIALIZE_SCALAR(rxListSize); UNSERIALIZE_SCALAR(rxListSize);
rxList.clear(); rxList.clear();
@@ -1345,6 +1483,15 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
rxList.push_back(value); 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; int txListSize;
UNSERIALIZE_SCALAR(txListSize); UNSERIALIZE_SCALAR(txListSize);
txList.clear(); txList.clear();
@@ -1360,9 +1507,16 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
int rxState; int rxState;
UNSERIALIZE_SCALAR(rxState); UNSERIALIZE_SCALAR(rxState);
UNSERIALIZE_SCALAR(rxEmpty); UNSERIALIZE_SCALAR(rxEmpty);
UNSERIALIZE_SCALAR(rxLow);
this->rxState = (RxState) rxState; this->rxState = (RxState) rxState;
rxFifo.unserialize("rxFifo", cp, section); 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 * Unserialize tx state machine
*/ */
@@ -1400,6 +1554,9 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
paramIn(cp, section, reg + ".TxData", vnic->TxData); paramIn(cp, section, reg + ".TxData", vnic->TxData);
paramIn(cp, section, reg + ".TxDone", vnic->TxDone); paramIn(cp, section, reg + ".TxDone", vnic->TxDone);
vnic->rxUnique = rxUnique++;
vnic->txUnique = txUnique++;
bool rxPacketExists; bool rxPacketExists;
paramIn(cp, section, reg + ".rxPacketExists", rxPacketExists); paramIn(cp, section, reg + ".rxPacketExists", rxPacketExists);
if (rxPacketExists) { if (rxPacketExists) {
@@ -1488,6 +1645,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
Param<uint32_t> rx_fifo_size; Param<uint32_t> rx_fifo_size;
Param<uint32_t> tx_fifo_size; Param<uint32_t> tx_fifo_size;
Param<uint32_t> rx_fifo_threshold; 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<uint32_t> tx_fifo_threshold;
Param<bool> rx_filter; Param<bool> rx_filter;
@@ -1495,6 +1654,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
Param<bool> rx_thread; Param<bool> rx_thread;
Param<bool> tx_thread; Param<bool> tx_thread;
Param<bool> rss; 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) 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(rx_fifo_size, "max size in bytes of rxFifo"),
INIT_PARAM(tx_fifo_size, "max size in bytes of txFifo"), 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_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(tx_fifo_threshold, "max size in bytes of txFifo"),
INIT_PARAM(rx_filter, "Enable Receive Filter"), INIT_PARAM(rx_filter, "Enable Receive Filter"),
INIT_PARAM(hardware_address, "Ethernet Hardware Address"), INIT_PARAM(hardware_address, "Ethernet Hardware Address"),
INIT_PARAM(rx_thread, ""), INIT_PARAM(rx_thread, ""),
INIT_PARAM(tx_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) END_INIT_SIM_OBJECT_PARAMS(Device)
@@ -1564,6 +1733,8 @@ CREATE_SIM_OBJECT(Device)
params->rx_fifo_size = rx_fifo_size; params->rx_fifo_size = rx_fifo_size;
params->tx_fifo_size = tx_fifo_size; params->tx_fifo_size = tx_fifo_size;
params->rx_fifo_threshold = rx_fifo_threshold; 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->tx_fifo_threshold = tx_fifo_threshold;
params->rx_filter = rx_filter; params->rx_filter = rx_filter;
@@ -1571,6 +1742,10 @@ CREATE_SIM_OBJECT(Device)
params->rx_thread = rx_thread; params->rx_thread = rx_thread;
params->tx_thread = tx_thread; params->tx_thread = tx_thread;
params->rss = rss; 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); return new Device(params);
} }

View File

@@ -117,7 +117,7 @@ class Device : public Base
uint32_t RxMaxCopy; // 0x10 uint32_t RxMaxCopy; // 0x10
uint32_t TxMaxCopy; // 0x14 uint32_t TxMaxCopy; // 0x14
uint32_t RxMaxIntr; // 0x18 uint32_t RxMaxIntr; // 0x18
uint32_t Reserved0; // 0x1c uint32_t VirtualCount; // 0x1c
uint32_t RxFifoSize; // 0x20 uint32_t RxFifoSize; // 0x20
uint32_t TxFifoSize; // 0x24 uint32_t TxFifoSize; // 0x24
uint32_t RxFifoMark; // 0x28 uint32_t RxFifoMark; // 0x28
@@ -142,6 +142,9 @@ class Device : public Base
int rxPacketBytes; int rxPacketBytes;
uint64_t rxDoneData; uint64_t rxDoneData;
Counter rxUnique;
Counter txUnique;
VirtualReg() VirtualReg()
: RxData(0), RxDone(0), TxData(0), TxDone(0), : RxData(0), RxDone(0), TxData(0), TxDone(0),
rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
@@ -149,8 +152,12 @@ class Device : public Base
}; };
typedef std::vector<VirtualReg> VirtualRegs; typedef std::vector<VirtualReg> VirtualRegs;
typedef std::list<int> VirtualList; typedef std::list<int> VirtualList;
Counter rxUnique;
Counter txUnique;
VirtualRegs virtualRegs; VirtualRegs virtualRegs;
VirtualList rxList; VirtualList rxList;
VirtualList rxBusy;
int rxActive;
VirtualList txList; VirtualList txList;
uint8_t &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); } uint8_t &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
@@ -162,6 +169,7 @@ class Device : public Base
PacketFifo rxFifo; PacketFifo rxFifo;
PacketFifo::iterator rxFifoPtr; PacketFifo::iterator rxFifoPtr;
bool rxEmpty; bool rxEmpty;
bool rxLow;
Addr rxDmaAddr; Addr rxDmaAddr;
uint8_t *rxDmaData; uint8_t *rxDmaData;
int rxDmaLen; int rxDmaLen;
@@ -318,6 +326,8 @@ class Device : public Base
uint32_t rx_fifo_size; uint32_t rx_fifo_size;
uint32_t tx_fifo_size; uint32_t tx_fifo_size;
uint32_t rx_fifo_threshold; uint32_t rx_fifo_threshold;
uint32_t rx_fifo_low_mark;
uint32_t tx_fifo_high_mark;
uint32_t tx_fifo_threshold; uint32_t tx_fifo_threshold;
Tick dma_read_delay; Tick dma_read_delay;
Tick dma_read_factor; Tick dma_read_factor;
@@ -326,6 +336,10 @@ class Device : public Base
bool rx_thread; bool rx_thread;
bool tx_thread; bool tx_thread;
bool rss; bool rss;
uint32_t virtual_count;
bool zero_copy;
bool delay_copy;
bool virtual_addr;
}; };
protected: protected:

View File

@@ -55,38 +55,40 @@
namespace Sinic { namespace Sinic {
namespace Regs { namespace Regs {
static const int VirtualMask = 0xff;
static const int VirtualShift = 8; static const int VirtualShift = 8;
static const int VirtualMask = 0xff;
// Registers // Registers
__SINIC_REG32(Config, 0x00); // 32: configuration register __SINIC_REG32(Config, 0x00); // 32: configuration register
__SINIC_REG32(Command, 0x04); // 32: command register __SINIC_REG32(Command, 0x04); // 32: command register
__SINIC_REG32(IntrStatus, 0x08); // 32: interrupt status __SINIC_REG32(IntrStatus, 0x08); // 32: interrupt status
__SINIC_REG32(IntrMask, 0x0c); // 32: interrupt mask __SINIC_REG32(IntrMask, 0x0c); // 32: interrupt mask
__SINIC_REG32(RxMaxCopy, 0x10); // 32: max bytes per rx copy __SINIC_REG32(RxMaxCopy, 0x10); // 32: max bytes per rx copy
__SINIC_REG32(TxMaxCopy, 0x14); // 32: max bytes per tx copy __SINIC_REG32(TxMaxCopy, 0x14); // 32: max bytes per tx copy
__SINIC_REG32(RxMaxIntr, 0x18); // 32: max receives per interrupt __SINIC_REG32(RxMaxIntr, 0x18); // 32: max receives per interrupt
__SINIC_REG32(Reserved0, 0x1c); // 32: reserved __SINIC_REG32(VirtualCount, 0x1c); // 32: number of virutal NICs
__SINIC_REG32(RxFifoSize, 0x20); // 32: rx fifo capacity in bytes __SINIC_REG32(RxFifoSize, 0x20); // 32: rx fifo capacity in bytes
__SINIC_REG32(TxFifoSize, 0x24); // 32: tx 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(RxFifoMark, 0x28); // 32: rx fifo high watermark
__SINIC_REG32(TxFifoMark, 0x2c); // 32: tx fifo low watermark __SINIC_REG32(TxFifoMark, 0x2c); // 32: tx fifo low watermark
__SINIC_REG32(RxData, 0x30); // 64: receive data __SINIC_REG32(RxData, 0x30); // 64: receive data
__SINIC_REG32(RxDone, 0x38); // 64: receive done __SINIC_REG32(RxDone, 0x38); // 64: receive done
__SINIC_REG32(RxWait, 0x40); // 64: receive done (busy wait) __SINIC_REG32(RxWait, 0x40); // 64: receive done (busy wait)
__SINIC_REG32(TxData, 0x48); // 64: transmit data __SINIC_REG32(TxData, 0x48); // 64: transmit data
__SINIC_REG32(TxDone, 0x50); // 64: transmit done __SINIC_REG32(TxDone, 0x50); // 64: transmit done
__SINIC_REG32(TxWait, 0x58); // 64: transmit done (busy wait) __SINIC_REG32(TxWait, 0x58); // 64: transmit done (busy wait)
__SINIC_REG32(HwAddr, 0x60); // 64: mac address __SINIC_REG32(HwAddr, 0x60); // 64: mac address
__SINIC_REG32(Size, 0x68); // register addres space size __SINIC_REG32(Size, 0x68); // register addres space size
// Config register bits // 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_RSS, 10, 1); // enable receive side scaling
__SINIC_VAL32(Config_RxThread, 9, 1); // enable receive threads __SINIC_VAL32(Config_RxThread, 9, 1); // enable receive threads
__SINIC_VAL32(Config_TxThread, 8, 1); // enable transmit thread __SINIC_VAL32(Config_TxThread, 8, 1); // enable transmit thread
__SINIC_VAL32(Config_Filter, 7, 1); // enable receive filter __SINIC_VAL32(Config_Filter, 7, 1); // enable receive filter
__SINIC_VAL32(Config_Vlan, 6, 1); // enable vlan tagging __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_Desc, 4, 1); // enable tx/rx descriptors
__SINIC_VAL32(Config_Poll, 3, 1); // enable polling __SINIC_VAL32(Config_Poll, 3, 1); // enable polling
__SINIC_VAL32(Config_IntEn, 2, 1); // enable interrupts __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 __SINIC_REG32(Intr_Res, ~0x01ff); // reserved interrupt bits
// RX Data Description // RX Data Description
__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 1M __SINIC_VAL64(RxData_Vaddr, 60, 1); // Addr is virtual
__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB __SINIC_VAL64(RxData_Len, 40, 20); // 0 - 256k
__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB
// TX Data Description // TX Data Description
__SINIC_VAL64(TxData_More, 63, 1); // Packet not complete (will dma more) __SINIC_VAL64(TxData_More, 63, 1); // Packet not complete (will dma more)
__SINIC_VAL64(TxData_Checksum, 62, 1); // do checksum __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 __SINIC_VAL64(TxData_Addr, 0, 40); // Address 1TB
// RX Done/Busy Information // 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_Busy, 31, 1); // receive dma busy copying
__SINIC_VAL64(RxDone_Complete, 30, 1); // valid data (packet complete) __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_More, 29, 1); // Packet has more data (dma again)
__SINIC_VAL64(RxDone_Res0, 28, 1); // reserved __SINIC_VAL64(RxDone_Empty, 28, 1); // rx fifo is empty
__SINIC_VAL64(RxDone_Res1, 27, 1); // reserved __SINIC_VAL64(RxDone_High, 27, 1); // rx fifo is above the watermark
__SINIC_VAL64(RxDone_Res2, 26, 1); // reserved __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_TcpError, 25, 1); // TCP packet error (bad checksum)
__SINIC_VAL64(RxDone_UdpError, 24, 1); // UDP 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) __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, "RxMaxCopy" },
{ 4, true, false, "TxMaxCopy" }, { 4, true, false, "TxMaxCopy" },
{ 4, true, false, "RxMaxIntr" }, { 4, true, false, "RxMaxIntr" },
invalid, { 4, true, false, "VirtualCount" },
{ 4, true, false, "RxFifoSize" }, { 4, true, false, "RxFifoSize" },
{ 4, true, false, "TxFifoSize" }, { 4, true, false, "TxFifoSize" },
{ 4, true, false, "RxFifoMark" }, { 4, true, false, "RxFifoMark" },

View File

@@ -101,8 +101,14 @@ class Sinic(EtherDevBase):
rx_max_copy = Param.MemorySize('1514B', "rx max copy") rx_max_copy = Param.MemorySize('1514B', "rx max copy")
tx_max_copy = Param.MemorySize('16kB', "tx max copy") tx_max_copy = Param.MemorySize('16kB', "tx max copy")
rx_max_intr = Param.UInt32(10, "max rx packets per interrupt") rx_max_intr = Param.UInt32(10, "max rx packets per interrupt")
rx_fifo_threshold = Param.MemorySize('48kB', "rx fifo high threshold") rx_fifo_threshold = Param.MemorySize('384kB', "rx fifo high threshold")
tx_fifo_threshold = Param.MemorySize('16kB', "tx fifo low 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): class SinicInt(EtherInt):
type = 'SinicInt' type = 'SinicInt'

View File

@@ -51,8 +51,9 @@
using namespace std; using namespace std;
int Serializable::maxCount = 0; int Serializable::ckptMaxCount = 0;
int Serializable::count = 0; int Serializable::ckptCount = 0;
int Serializable::ckptPrevCount = -1;
void void
Serializable::nameOut(ostream &os) Serializable::nameOut(ostream &os)
@@ -241,8 +242,11 @@ Serializable::serializeAll()
globals.serialize(outstream); globals.serialize(outstream);
SimObject::serializeAll(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"); SimExit(curTick + 1, "Maximum number of checkpoints dropped");
} }
@@ -352,7 +356,7 @@ SerializeParamContext::checkParams()
if (serialize_cycle > 0) if (serialize_cycle > 0)
Checkpoint::setup(serialize_cycle, serialize_period); Checkpoint::setup(serialize_cycle, serialize_period);
Serializable::maxCount = serialize_count; Serializable::ckptMaxCount = serialize_count;
} }
void void

View File

@@ -119,8 +119,9 @@ class Serializable
static Serializable *create(Checkpoint *cp, static Serializable *create(Checkpoint *cp,
const std::string &section); const std::string &section);
static int count; static int ckptCount;
static int maxCount; static int ckptMaxCount;
static int ckptPrevCount;
static void serializeAll(); static void serializeAll();
static void unserializeGlobals(Checkpoint *cp); static void unserializeGlobals(Checkpoint *cp);
}; };

View File

@@ -233,7 +233,7 @@ class BarChart(ChartOptions):
inner_axes.set_yticks(ticks) inner_axes.set_yticks(ticks)
inner_axes.set_yticklabels(self.yticks) inner_axes.set_yticklabels(self.yticks)
elif self.ylim is not None: 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: if self.xticks is not None:
outer_axes.set_xticks(arange(cshape[2]) + .5) outer_axes.set_xticks(arange(cshape[2]) + .5)
@@ -242,9 +242,9 @@ class BarChart(ChartOptions):
if self.xsubticks is not None: if self.xsubticks is not None:
numticks = (cshape[0] + 1) * cshape[2] numticks = (cshape[0] + 1) * cshape[2]
inner_axes.set_xticks(arange(numticks) * width + 2 * center) inner_axes.set_xticks(arange(numticks) * width + 2 * center)
self.xsubticks.append('') xsubticks = list(self.xsubticks) + [ '' ]
inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7, inner_axes.set_xticklabels(xsubticks * cshape[2], fontsize=7,
rotation=90) rotation=30)
if self.legend is not None: if self.legend is not None:
if dim == 1: if dim == 1: