Merge zizzer:/z/m5/Bitkeeper/m5

into zazzer.eecs.umich.edu:/z/rdreslin/m5bk/clean

--HG--
extra : convert_revision : 0a189db3ecd1424558c73620d81300344e68b86d
This commit is contained in:
Ron Dreslinski 2004-12-07 14:12:08 -05:00
commit a435be1b00
20 changed files with 726 additions and 162 deletions

View file

@ -108,14 +108,14 @@ EcoffObject::loadGlobalSymbols(SymbolTable *symtab)
return false; return false;
if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) { if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
cprintf("wrong magic\n"); warn("loadGlobalSymbols: wrong magic on %s\n", filename);
return false; return false;
} }
ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr); ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
if (syms->magic != magicSym2) { if (syms->magic != magicSym2) {
cprintf("bad symbol header magic\n"); warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
exit(1); return false;
} }
ecoff_extsym *ext_syms = (ecoff_extsym *)(fileData + syms->cbExtOffset); ecoff_extsym *ext_syms = (ecoff_extsym *)(fileData + syms->cbExtOffset);
@ -137,14 +137,14 @@ EcoffObject::loadLocalSymbols(SymbolTable *symtab)
return false; return false;
if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) { if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
cprintf("wrong magic\n"); warn("loadGlobalSymbols: wrong magic on %s\n", filename);
return false; return false;
} }
ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr); ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
if (syms->magic != magicSym2) { if (syms->magic != magicSym2) {
cprintf("bad symbol header magic\n"); warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
exit(1); return false;
} }
ecoff_sym *local_syms = (ecoff_sym *)(fileData + syms->cbSymOffset); ecoff_sym *local_syms = (ecoff_sym *)(fileData + syms->cbSymOffset);

View file

@ -64,7 +64,7 @@ ListenSocket::listen(int port, bool reuse)
fd = ::socket(PF_INET, SOCK_STREAM, 0); fd = ::socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0) if (fd < 0)
panic("Can't create socket!"); panic("Can't create socket:%s !", strerror(errno));
if (reuse) { if (reuse) {
int i = 1; int i = 1;

View file

@ -0,0 +1,45 @@
#!/bin/sh
SERVER=10.0.0.1
CLIENT=10.0.0.2
echo "setting up network..."
ifconfig lo 127.0.0.1
ifconfig eth0 $CLIENT txqueuelen 1000
echo "0" > /proc/sys/net/ipv4/tcp_timestamps
echo "0" > /proc/sys/net/ipv4/tcp_sack
echo "5000000 5000000 5000000" > /proc/sys/net/ipv4/tcp_rmem
echo "5000000 5000000 5000000" > /proc/sys/net/ipv4/tcp_wmem
echo "5000000 5000000 5000000" > /proc/sys/net/ipv4/tcp_mem
echo "262143" > /proc/sys/net/core/rmem_max
echo "262143" > /proc/sys/net/core/wmem_max
echo "262143" > /proc/sys/net/core/rmem_default
echo "262143" > /proc/sys/net/core/wmem_default
echo "262143" > /proc/sys/net/core/optmem_max
echo "100000" > /proc/sys/net/core/netdev_max_backlog
echo -n "waiting for server..."
/usr/bin/netcat -c -l -p 8000
BINARY=/benchmarks/netperf/netperf
TEST="TCP_STREAM"
SHORT_ARGS="-l -100k"
LONG_ARGS="-- -m 65536 -M 65536 -s 262144 -S 262144"
SHORT="$BINARY -H $SERVER -t $TEST $SHORT_ARGS"
LONG="$BINARY -H $SERVER -t $TEST $LONG_ARGS"
echo "starting test..."
echo "netperf warmup"
echo $SHORT
eval $SHORT
echo "netperf benchmark"
echo $LONG
/sbin/m5 ivlb 1
/sbin/m5 resetstats
/sbin/m5 dumpresetstats 200000000 2000000000
/sbin/m5 checkpoint 200000000 2000000000
eval $LONG
/sbin/m5 exit

View file

@ -195,7 +195,7 @@ EtherLink::Link::unserialize(Checkpoint *cp, const string &section)
bool packet_exists; bool packet_exists;
UNSERIALIZE_SCALAR(packet_exists); UNSERIALIZE_SCALAR(packet_exists);
if (packet_exists) { if (packet_exists) {
packet = new PacketData; packet = new PacketData(16384);
packet->unserialize("packet", cp, section); packet->unserialize("packet", cp, section);
} }
@ -244,7 +244,7 @@ void
LinkDelayEvent::unserialize(Checkpoint *cp, const string &section) LinkDelayEvent::unserialize(Checkpoint *cp, const string &section)
{ {
Event::unserialize(cp, section); Event::unserialize(cp, section);
packet = new PacketData; packet = new PacketData(16384);
packet->unserialize("packet", cp, section); packet->unserialize("packet", cp, section);
} }

View file

@ -219,8 +219,7 @@ EtherTap::process(int revent)
while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) { while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) {
PacketPtr packet; PacketPtr packet;
packet = new PacketData; packet = new PacketData(data_len);
packet->data = new uint8_t[data_len];
packet->length = data_len; packet->length = data_len;
memcpy(packet->data, data, data_len); memcpy(packet->data, data, data_len);

View file

@ -274,6 +274,180 @@ NSGigE::regStats()
.prereq(rxBytes) .prereq(rxBytes)
; ;
postedSwi
.name(name() + ".postedSwi")
.desc("number of software interrupts posted to CPU")
.precision(0)
;
totalSwi
.name(name() + ".totalSwi")
.desc("number of total Swi written to ISR")
.precision(0)
;
coalescedSwi
.name(name() + ".coalescedSwi")
.desc("average number of Swi's coalesced into each post")
.precision(0)
;
postedRxIdle
.name(name() + ".postedRxIdle")
.desc("number of rxIdle interrupts posted to CPU")
.precision(0)
;
totalRxIdle
.name(name() + ".totalRxIdle")
.desc("number of total RxIdle written to ISR")
.precision(0)
;
coalescedRxIdle
.name(name() + ".coalescedRxIdle")
.desc("average number of RxIdle's coalesced into each post")
.precision(0)
;
postedRxOk
.name(name() + ".postedRxOk")
.desc("number of RxOk interrupts posted to CPU")
.precision(0)
;
totalRxOk
.name(name() + ".totalRxOk")
.desc("number of total RxOk written to ISR")
.precision(0)
;
coalescedRxOk
.name(name() + ".coalescedRxOk")
.desc("average number of RxOk's coalesced into each post")
.precision(0)
;
postedRxDesc
.name(name() + ".postedRxDesc")
.desc("number of RxDesc interrupts posted to CPU")
.precision(0)
;
totalRxDesc
.name(name() + ".totalRxDesc")
.desc("number of total RxDesc written to ISR")
.precision(0)
;
coalescedRxDesc
.name(name() + ".coalescedRxDesc")
.desc("average number of RxDesc's coalesced into each post")
.precision(0)
;
postedTxOk
.name(name() + ".postedTxOk")
.desc("number of TxOk interrupts posted to CPU")
.precision(0)
;
totalTxOk
.name(name() + ".totalTxOk")
.desc("number of total TxOk written to ISR")
.precision(0)
;
coalescedTxOk
.name(name() + ".coalescedTxOk")
.desc("average number of TxOk's coalesced into each post")
.precision(0)
;
postedTxIdle
.name(name() + ".postedTxIdle")
.desc("number of TxIdle interrupts posted to CPU")
.precision(0)
;
totalTxIdle
.name(name() + ".totalTxIdle")
.desc("number of total TxIdle written to ISR")
.precision(0)
;
coalescedTxIdle
.name(name() + ".coalescedTxIdle")
.desc("average number of TxIdle's coalesced into each post")
.precision(0)
;
postedTxDesc
.name(name() + ".postedTxDesc")
.desc("number of TxDesc interrupts posted to CPU")
.precision(0)
;
totalTxDesc
.name(name() + ".totalTxDesc")
.desc("number of total TxDesc written to ISR")
.precision(0)
;
coalescedTxDesc
.name(name() + ".coalescedTxDesc")
.desc("average number of TxDesc's coalesced into each post")
.precision(0)
;
postedRxOrn
.name(name() + ".postedRxOrn")
.desc("number of RxOrn posted to CPU")
.precision(0)
;
totalRxOrn
.name(name() + ".totalRxOrn")
.desc("number of total RxOrn written to ISR")
.precision(0)
;
coalescedRxOrn
.name(name() + ".coalescedRxOrn")
.desc("average number of RxOrn's coalesced into each post")
.precision(0)
;
coalescedTotal
.name(name() + ".coalescedTotal")
.desc("average number of interrupts coalesced into each post")
.precision(0)
;
postedInterrupts
.name(name() + ".postedInterrupts")
.desc("number of posts to CPU")
.precision(0)
;
droppedPackets
.name(name() + ".droppedPackets")
.desc("number of packets dropped")
.precision(0)
;
coalescedSwi = totalSwi / postedInterrupts;
coalescedRxIdle = totalRxIdle / postedInterrupts;
coalescedRxOk = totalRxOk / postedInterrupts;
coalescedRxDesc = totalRxDesc / postedInterrupts;
coalescedTxOk = totalTxOk / postedInterrupts;
coalescedTxIdle = totalTxIdle / postedInterrupts;
coalescedTxDesc = totalTxDesc / postedInterrupts;
coalescedRxOrn = totalRxOrn / postedInterrupts;
coalescedTotal = (totalSwi + totalRxIdle + totalRxOk + totalRxDesc + totalTxOk
+ totalTxIdle + totalTxDesc + totalRxOrn) / postedInterrupts;
txBandwidth = txBytes * Stats::constant(8) / simSeconds; txBandwidth = txBytes * Stats::constant(8) / simSeconds;
rxBandwidth = rxBytes * Stats::constant(8) / simSeconds; rxBandwidth = rxBytes * Stats::constant(8) / simSeconds;
txPacketRate = txPackets / simSeconds; txPacketRate = txPackets / simSeconds;
@ -931,6 +1105,33 @@ NSGigE::devIntrPost(uint32_t interrupts)
interrupts &= ~ISR_NOIMPL; interrupts &= ~ISR_NOIMPL;
regs.isr |= interrupts; regs.isr |= interrupts;
if (interrupts & regs.imr) {
if (interrupts & ISR_SWI) {
totalSwi++;
}
if (interrupts & ISR_RXIDLE) {
totalRxIdle++;
}
if (interrupts & ISR_RXOK) {
totalRxOk++;
}
if (interrupts & ISR_RXDESC) {
totalRxDesc++;
}
if (interrupts & ISR_TXOK) {
totalTxOk++;
}
if (interrupts & ISR_TXIDLE) {
totalTxIdle++;
}
if (interrupts & ISR_TXDESC) {
totalTxDesc++;
}
if (interrupts & ISR_RXORN) {
totalRxOrn++;
}
}
DPRINTF(EthernetIntr, DPRINTF(EthernetIntr,
"interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n", "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
interrupts, regs.isr, regs.imr); interrupts, regs.isr, regs.imr);
@ -943,12 +1144,46 @@ NSGigE::devIntrPost(uint32_t interrupts)
} }
} }
/* writing this interrupt counting stats inside this means that this function
is now limited to being used to clear all interrupts upon the kernel
reading isr and servicing. just telling you in case you were thinking
of expanding use.
*/
void void
NSGigE::devIntrClear(uint32_t interrupts) NSGigE::devIntrClear(uint32_t interrupts)
{ {
if (interrupts & ISR_RESERVE) if (interrupts & ISR_RESERVE)
panic("Cannot clear a reserved interrupt"); panic("Cannot clear a reserved interrupt");
if (regs.isr & regs.imr & ISR_SWI) {
postedSwi++;
}
if (regs.isr & regs.imr & ISR_RXIDLE) {
postedRxIdle++;
}
if (regs.isr & regs.imr & ISR_RXOK) {
postedRxOk++;
}
if (regs.isr & regs.imr & ISR_RXDESC) {
postedRxDesc++;
}
if (regs.isr & regs.imr & ISR_TXOK) {
postedTxOk++;
}
if (regs.isr & regs.imr & ISR_TXIDLE) {
postedTxIdle++;
}
if (regs.isr & regs.imr & ISR_TXDESC) {
postedTxDesc++;
}
if (regs.isr & regs.imr & ISR_RXORN) {
postedRxOrn++;
}
if (regs.isr & regs.imr & (ISR_SWI | ISR_RXIDLE | ISR_RXOK | ISR_RXDESC |
ISR_TXOK | ISR_TXIDLE | ISR_TXDESC | ISR_RXORN) )
postedInterrupts++;
interrupts &= ~ISR_NOIMPL; interrupts &= ~ISR_NOIMPL;
regs.isr &= ~interrupts; regs.isr &= ~interrupts;
@ -1767,8 +2002,7 @@ NSGigE::txKick()
case txFifoBlock: case txFifoBlock:
if (!txPacket) { if (!txPacket) {
DPRINTF(EthernetSM, "****starting the tx of a new packet****\n"); DPRINTF(EthernetSM, "****starting the tx of a new packet****\n");
txPacket = new PacketData; txPacket = new PacketData(16384);
txPacket->data = new uint8_t[16384];
txPacketBufPtr = txPacket->data; txPacketBufPtr = txPacket->data;
} }
@ -2034,6 +2268,7 @@ NSGigE::recvPacket(PacketPtr packet)
if (rxFifo.avail() < packet->length) { if (rxFifo.avail() < packet->length) {
DPRINTF(Ethernet, DPRINTF(Ethernet,
"packet will not fit in receive buffer...packet dropped\n"); "packet will not fit in receive buffer...packet dropped\n");
droppedPackets++;
devIntrPost(ISR_RXORN); devIntrPost(ISR_RXORN);
return false; return false;
} }
@ -2257,7 +2492,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
bool txPacketExists; bool txPacketExists;
UNSERIALIZE_SCALAR(txPacketExists); UNSERIALIZE_SCALAR(txPacketExists);
if (txPacketExists) { if (txPacketExists) {
txPacket = new PacketData; txPacket = new PacketData(16384);
txPacket->unserialize("txPacket", cp, section); txPacket->unserialize("txPacket", cp, section);
uint32_t txPktBufPtr; uint32_t txPktBufPtr;
UNSERIALIZE_SCALAR(txPktBufPtr); UNSERIALIZE_SCALAR(txPktBufPtr);
@ -2269,7 +2504,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(rxPacketExists); UNSERIALIZE_SCALAR(rxPacketExists);
rxPacket = 0; rxPacket = 0;
if (rxPacketExists) { if (rxPacketExists) {
rxPacket = new PacketData; rxPacket = new PacketData(16384);
rxPacket->unserialize("rxPacket", cp, section); rxPacket->unserialize("rxPacket", cp, section);
uint32_t rxPktBufPtr; uint32_t rxPktBufPtr;
UNSERIALIZE_SCALAR(rxPktBufPtr); UNSERIALIZE_SCALAR(rxPktBufPtr);

View file

@ -385,6 +385,33 @@ class NSGigE : public PciDev
Stats::Formula rxBandwidth; Stats::Formula rxBandwidth;
Stats::Formula txPacketRate; Stats::Formula txPacketRate;
Stats::Formula rxPacketRate; Stats::Formula rxPacketRate;
Stats::Scalar<> postedSwi;
Stats::Formula coalescedSwi;
Stats::Scalar<> totalSwi;
Stats::Scalar<> postedRxIdle;
Stats::Formula coalescedRxIdle;
Stats::Scalar<> totalRxIdle;
Stats::Scalar<> postedRxOk;
Stats::Formula coalescedRxOk;
Stats::Scalar<> totalRxOk;
Stats::Scalar<> postedRxDesc;
Stats::Formula coalescedRxDesc;
Stats::Scalar<> totalRxDesc;
Stats::Scalar<> postedTxOk;
Stats::Formula coalescedTxOk;
Stats::Scalar<> totalTxOk;
Stats::Scalar<> postedTxIdle;
Stats::Formula coalescedTxIdle;
Stats::Scalar<> totalTxIdle;
Stats::Scalar<> postedTxDesc;
Stats::Formula coalescedTxDesc;
Stats::Scalar<> totalTxDesc;
Stats::Scalar<> postedRxOrn;
Stats::Formula coalescedRxOrn;
Stats::Scalar<> totalRxOrn;
Stats::Formula coalescedTotal;
Stats::Scalar<> postedInterrupts;
Stats::Scalar<> droppedPackets;
public: public:
Tick cacheAccess(MemReqPtr &req); Tick cacheAccess(MemReqPtr &req);

View file

@ -33,10 +33,12 @@
#include <deque> #include <deque>
#include <string> #include <string>
#include <vector> #include <vector>
#include <bitset>
#include "base/trace.hh" #include "base/trace.hh"
#include "dev/pciconfigall.hh" #include "dev/pciconfigall.hh"
#include "dev/pcidev.hh" #include "dev/pcidev.hh"
#include "dev/pcireg.h"
#include "mem/bus/bus.hh" #include "mem/bus/bus.hh"
#include "mem/bus/pio_interface.hh" #include "mem/bus/pio_interface.hh"
#include "mem/bus/pio_interface_impl.hh" #include "mem/bus/pio_interface_impl.hh"
@ -65,6 +67,33 @@ PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu,
devices[x][y] = NULL; devices[x][y] = NULL;
} }
// If two interrupts share the same line largely bad things will happen.
// Since we don't track how many times an interrupt was set and correspondingly
// cleared two devices on the same interrupt line and assert and deassert each
// others interrupt "line". Interrupts will not work correctly.
void
PciConfigAll::startup()
{
bitset<256> intLines;
PciDev *tempDev;
uint8_t intline;
for (int x = 0; x < MAX_PCI_DEV; x++) {
for (int y = 0; y < MAX_PCI_FUNC; y++) {
if (devices[x][y] != NULL) {
tempDev = devices[x][y];
intline = tempDev->interruptLine();
if (intLines.test(intline))
warn("Interrupt line %#X is used multiple times"
"(You probably want to fix this).\n", (uint32_t)intline);
else
intLines.set(intline);
} // devices != NULL
} // PCI_FUNC
} // PCI_DEV
}
Fault Fault
PciConfigAll::read(MemReqPtr &req, uint8_t *data) PciConfigAll::read(MemReqPtr &req, uint8_t *data)
{ {

View file

@ -115,6 +115,12 @@ class PciConfigAll : public PioDevice
virtual Fault write(MemReqPtr &req, const uint8_t *data); virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* Start up function to check if more than one person is using an interrupt line
* and print a warning if such a case exists
*/
virtual void startup();
/** /**
* Serialize this object to the given output stream. * Serialize this object to the given output stream.
* @param os The stream to serialize to. * @param os The stream to serialize to.
@ -134,6 +140,7 @@ class PciConfigAll : public PioDevice
* @return Tick when the request is done * @return Tick when the request is done
*/ */
Tick cacheAccess(MemReqPtr &req); Tick cacheAccess(MemReqPtr &req);
}; };
#endif // __PCICONFIGALL_HH__ #endif // __PCICONFIGALL_HH__

View file

@ -141,6 +141,10 @@ class PciDev : public DmaDevice
intrClear() intrClear()
{ plat->clearPciInt(configData->config.hdr.pci0.interruptLine); } { plat->clearPciInt(configData->config.hdr.pci0.interruptLine); }
uint8_t
interruptLine()
{ return configData->config.hdr.pci0.interruptLine; }
public: public:
/** /**
* Constructor for PCI Dev. This function copies data from the * Constructor for PCI Dev. This function copies data from the

View file

@ -63,7 +63,7 @@ PacketFifo::unserialize(const string &base, Checkpoint *cp,
fifo.resize(fifosize); fifo.resize(fifosize);
for (int i = 0; i < fifosize; ++i) { for (int i = 0; i < fifosize; ++i) {
PacketPtr p = new PacketData; PacketPtr p = new PacketData(16384);
p->unserialize(csprintf("%s.packet%d", base, i), cp, section); p->unserialize(csprintf("%s.packet%d", base, i), cp, section);
fifo.push_back(p); fifo.push_back(p);
} }

View file

@ -1225,7 +1225,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(rxPacketExists); UNSERIALIZE_SCALAR(rxPacketExists);
rxPacket = 0; rxPacket = 0;
if (rxPacketExists) { if (rxPacketExists) {
rxPacket = new PacketData; rxPacket = new PacketData(16384);
rxPacket->unserialize("rxPacket", cp, section); rxPacket->unserialize("rxPacket", cp, section);
uint32_t rxPktBufPtr; uint32_t rxPktBufPtr;
UNSERIALIZE_SCALAR(rxPktBufPtr); UNSERIALIZE_SCALAR(rxPktBufPtr);
@ -1245,7 +1245,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(txPacketExists); UNSERIALIZE_SCALAR(txPacketExists);
txPacket = 0; txPacket = 0;
if (txPacketExists) { if (txPacketExists) {
txPacket = new PacketData; txPacket = new PacketData(16384);
txPacket->unserialize("txPacket", cp, section); txPacket->unserialize("txPacket", cp, section);
uint32_t txPktBufPtr; uint32_t txPktBufPtr;
UNSERIALIZE_SCALAR(txPktBufPtr); UNSERIALIZE_SCALAR(txPktBufPtr);

View file

@ -58,7 +58,7 @@ class Tsunami : public Platform
public: public:
/** Max number of CPUs in a Tsunami */ /** Max number of CPUs in a Tsunami */
static const int Max_CPUs = 4; static const int Max_CPUs = 64;
/** Pointer to the system */ /** Pointer to the system */
System *system; System *system;

View file

@ -55,14 +55,6 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
{ {
mmu->add_child(this, RangeSize(addr, size)); mmu->add_child(this, RangeSize(addr, size));
for(int i=0; i < Tsunami::Max_CPUs; i++) {
dim[i] = 0;
dir[i] = 0;
dirInterrupting[i] = false;
ipiInterrupting[i] = false;
RTCInterrupting[i] = false;
}
if (bus) { if (bus) {
pioInterface = newPioInterface(name, hier, bus, this, pioInterface = newPioInterface(name, hier, bus, this,
&TsunamiCChip::cacheAccess); &TsunamiCChip::cacheAccess);
@ -71,7 +63,14 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
} }
drir = 0; drir = 0;
misc = 0; ipint = 0;
itint = 0;
for (int x = 0; x < Tsunami::Max_CPUs; x++)
{
dim[x] = 0;
dir[x] = 0;
}
//Put back pointer in tsunami //Put back pointer in tsunami
tsunami->cchip = this; tsunami->cchip = this;
@ -80,16 +79,29 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
Fault Fault
TsunamiCChip::read(MemReqPtr &req, uint8_t *data) TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
{ {
DPRINTF(Tsunami, "read va=%#x size=%d\n", DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size);
req->vaddr, req->size);
Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6;
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6;
ExecContext *xc = req->xc; ExecContext *xc = req->xc;
switch (req->size) { switch (req->size) {
case sizeof(uint64_t): case sizeof(uint64_t):
switch(daddr) { if (daddr & TSDEV_CC_BDIMS)
{
*(uint64_t*)data = dim[(daddr >> 4) & 0x3F];
return No_Fault;
}
if (daddr & TSDEV_CC_BDIRS)
{
*(uint64_t*)data = dir[(daddr >> 4) & 0x3F];
return No_Fault;
}
switch(regnum) {
case TSDEV_CC_CSR: case TSDEV_CC_CSR:
*(uint64_t*)data = 0x0; *(uint64_t*)data = 0x0;
return No_Fault; return No_Fault;
@ -97,7 +109,9 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
panic("TSDEV_CC_MTR not implemeted\n"); panic("TSDEV_CC_MTR not implemeted\n");
return No_Fault; return No_Fault;
case TSDEV_CC_MISC: case TSDEV_CC_MISC:
*(uint64_t*)data = misc | (xc->cpu_id & 0x3); *(uint64_t*)data = (ipint << 8) & 0xF |
(itint << 4) & 0xF |
(xc->cpu_id & 0x3);
return No_Fault; return No_Fault;
case TSDEV_CC_AAR0: case TSDEV_CC_AAR0:
case TSDEV_CC_AAR1: case TSDEV_CC_AAR1:
@ -147,6 +161,12 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
case TSDEV_CC_MPR3: case TSDEV_CC_MPR3:
panic("TSDEV_CC_MPRx not implemented\n"); panic("TSDEV_CC_MPRx not implemented\n");
return No_Fault; return No_Fault;
case TSDEV_CC_IPIR:
*(uint64_t*)data = ipint;
return No_Fault;
case TSDEV_CC_ITIR:
*(uint64_t*)data = itint;
return No_Fault;
default: default:
panic("default in cchip read reached, accessing 0x%x\n"); panic("default in cchip read reached, accessing 0x%x\n");
} // uint64_t } // uint64_t
@ -158,7 +178,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
default: default:
panic("invalid access size(?) for tsunami register!\n"); panic("invalid access size(?) for tsunami register!\n");
} }
DPRINTFN("Tsunami CChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); DPRINTFN("Tsunami CChip ERROR: read regnum=%#x size=%d\n", regnum, req->size);
return No_Fault; return No_Fault;
} }
@ -169,16 +189,58 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n",
req->vaddr, *(uint64_t*)data, req->size); req->vaddr, *(uint64_t*)data, req->size);
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6;
bool supportedWrite = false; bool supportedWrite = false;
uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size();
switch (req->size) { switch (req->size) {
case sizeof(uint64_t): case sizeof(uint64_t):
switch(daddr) { if (daddr & TSDEV_CC_BDIMS)
case TSDEV_CC_CSR: {
int number = (daddr >> 4) & 0x3F;
uint64_t bitvector;
uint64_t olddim;
uint64_t olddir;
olddim = dim[number];
olddir = dir[number];
dim[number] = *(uint64_t*)data;
dir[number] = dim[number] & drir;
for(int x = 0; x < Tsunami::Max_CPUs; x++)
{
bitvector = ULL(1) << x;
// Figure out which bits have changed
if ((dim[number] & bitvector) != (olddim & bitvector))
{
// The bit is now set and it wasn't before (set)
if((dim[number] & bitvector) && (dir[number] & bitvector))
{
tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x);
DPRINTF(Tsunami, "dim write resulting in posting dir"
" interrupt to cpu %d\n", number);
}
else if ((olddir & bitvector) &&
!(dir[number] & bitvector))
{
// The bit was set and now its now clear and
// we were interrupting on that bit before
tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
DPRINTF(Tsunami, "dim write resulting in clear"
" dir interrupt to cpu %d\n", number);
}
}
}
return No_Fault;
}
switch(regnum) {
case TSDEV_CC_CSR:
panic("TSDEV_CC_CSR write\n"); panic("TSDEV_CC_CSR write\n");
return No_Fault; return No_Fault;
case TSDEV_CC_MTR: case TSDEV_CC_MTR:
@ -189,19 +251,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
ipreq = (*(uint64_t*)data >> 12) & 0xF; ipreq = (*(uint64_t*)data >> 12) & 0xF;
//If it is bit 12-15, this is an IPI post //If it is bit 12-15, this is an IPI post
if (ipreq) { if (ipreq) {
for (int cpunum=0; cpunum < Tsunami::Max_CPUs; cpunum++) { reqIPI(ipreq);
// Check each cpu bit
if (ipreq & (1 << cpunum)) {
// Check if there is already an ipi (bits 8:11)
if (!(misc & (0x100 << cpunum))) {
misc |= (0x100 << cpunum);
tsunami->intrctrl->post(cpunum,
TheISA::INTLEVEL_IRQ3, 0);
DPRINTF(IPI, "send IPI cpu=%d from=%d\n",
cpunum, req->cpu_num);
}
}
}
supportedWrite = true; supportedWrite = true;
} }
@ -209,36 +259,15 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
uint64_t ipintr; uint64_t ipintr;
ipintr = (*(uint64_t*)data >> 8) & 0xF; ipintr = (*(uint64_t*)data >> 8) & 0xF;
if (ipintr) { if (ipintr) {
for (int cpunum=0; cpunum < Tsunami::Max_CPUs; cpunum++) { clearIPI(ipintr);
// Check each cpu bit
if (ipintr & (1 << cpunum)) {
// Check if there is a pending ipi (bits 8:11)
if (misc & (0x100 << cpunum)) {
misc &= ~(0x100 << cpunum);
tsunami->intrctrl->clear(cpunum,
TheISA::INTLEVEL_IRQ3, 0);
DPRINTF(IPI, "clear IPI IPI cpu=%d from=%d\n",
cpunum, req->cpu_num);
}
}
}
supportedWrite = true; supportedWrite = true;
} }
//If it is the 4-7th bit, clear the RTC interrupt //If it is the 4-7th bit, clear the RTC interrupt
uint64_t itintr; uint64_t itintr;
if ((itintr = (*(uint64_t*) data) & (0xf<<4))) { itintr = (*(uint64_t*)data >> 4) & 0xF;
//Clear the bits in ITINTR if (itintr) {
misc &= ~(itintr); clearITI(itintr);
for (int i=0; i < size; i++) {
if ((itintr & (1 << (i+4))) && RTCInterrupting[i]) {
tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0);
RTCInterrupting[i] = false;
DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i);
}
}
supportedWrite = true; supportedWrite = true;
} }
@ -261,11 +290,11 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
case TSDEV_CC_DIM2: case TSDEV_CC_DIM2:
case TSDEV_CC_DIM3: case TSDEV_CC_DIM3:
int number; int number;
if(daddr == TSDEV_CC_DIM0) if(regnum == TSDEV_CC_DIM0)
number = 0; number = 0;
else if(daddr == TSDEV_CC_DIM1) else if(regnum == TSDEV_CC_DIM1)
number = 1; number = 1;
else if(daddr == TSDEV_CC_DIM2) else if(regnum == TSDEV_CC_DIM2)
number = 2; number = 2;
else else
number = 3; number = 3;
@ -280,7 +309,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
dir[number] = dim[number] & drir; dir[number] = dim[number] & drir;
for(int x = 0; x < 64; x++) for(int x = 0; x < 64; x++)
{ {
bitvector = (uint64_t)1 << x; bitvector = ULL(1) << x;
// Figure out which bits have changed // Figure out which bits have changed
if ((dim[number] & bitvector) != (olddim & bitvector)) if ((dim[number] & bitvector) != (olddim & bitvector))
{ {
@ -297,7 +326,8 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
// we were interrupting on that bit before // we were interrupting on that bit before
tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
DPRINTF(Tsunami, "dim write resulting in clear" DPRINTF(Tsunami, "dim write resulting in clear"
"dir interrupt to cpu 0\n"); " dir interrupt to cpu %d\n",
x);
} }
@ -324,6 +354,15 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
case TSDEV_CC_MPR2: case TSDEV_CC_MPR2:
case TSDEV_CC_MPR3: case TSDEV_CC_MPR3:
panic("TSDEV_CC_MPRx write not implemented\n"); panic("TSDEV_CC_MPRx write not implemented\n");
case TSDEV_CC_IPIR:
clearIPI(*(uint64_t*)data);
return No_Fault;
case TSDEV_CC_ITIR:
clearITI(*(uint64_t*)data);
return No_Fault;
case TSDEV_CC_IPIQ:
reqIPI(*(uint64_t*)data);
return No_Fault;
default: default:
panic("default in cchip read reached, accessing 0x%x\n"); panic("default in cchip read reached, accessing 0x%x\n");
} }
@ -341,15 +380,89 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
return No_Fault; return No_Fault;
} }
void
TsunamiCChip::clearIPI(uint64_t ipintr)
{
int numcpus = tsunami->intrctrl->cpu->system->execContexts.size();
assert(numcpus <= Tsunami::Max_CPUs);
if (ipintr) {
for (int cpunum=0; cpunum < numcpus; cpunum++) {
// Check each cpu bit
uint64_t cpumask = ULL(1) << cpunum;
if (ipintr & cpumask) {
// Check if there is a pending ipi
if (ipint & cpumask) {
ipint &= ~cpumask;
tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0);
DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum);
}
else
warn("clear IPI for CPU=%d, but NO IPI\n", cpunum);
}
}
}
else
panic("Big IPI Clear, but not processors indicated\n");
}
void
TsunamiCChip::clearITI(uint64_t itintr)
{
int numcpus = tsunami->intrctrl->cpu->system->execContexts.size();
assert(numcpus <= Tsunami::Max_CPUs);
if (itintr) {
for (int i=0; i < numcpus; i++) {
uint64_t cpumask = ULL(1) << i;
if (itintr & cpumask & itint) {
tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0);
itint &= ~cpumask;
DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i);
}
}
}
else
panic("Big ITI Clear, but not processors indicated\n");
}
void
TsunamiCChip::reqIPI(uint64_t ipreq)
{
int numcpus = tsunami->intrctrl->cpu->system->execContexts.size();
assert(numcpus <= Tsunami::Max_CPUs);
if (ipreq) {
for (int cpunum=0; cpunum < numcpus; cpunum++) {
// Check each cpu bit
uint64_t cpumask = ULL(1) << cpunum;
if (ipreq & cpumask) {
// Check if there is already an ipi (bits 8:11)
if (!(ipint & cpumask)) {
ipint |= cpumask;
tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0);
DPRINTF(IPI, "send IPI cpu=%d\n", cpunum);
}
else
warn("post IPI for CPU=%d, but IPI already\n", cpunum);
}
}
}
else
panic("Big IPI Request, but not processors indicated\n");
}
void void
TsunamiCChip::postRTC() TsunamiCChip::postRTC()
{ {
int size = tsunami->intrctrl->cpu->system->execContexts.size(); int size = tsunami->intrctrl->cpu->system->execContexts.size();
assert(size <= Tsunami::Max_CPUs);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (!RTCInterrupting[i]) { uint64_t cpumask = ULL(1) << i;
misc |= 16 << i; if (!(cpumask & itint)) {
RTCInterrupting[i] = true; itint |= cpumask;
tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0);
DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i);
} }
@ -360,9 +473,11 @@ TsunamiCChip::postRTC()
void void
TsunamiCChip::postDRIR(uint32_t interrupt) TsunamiCChip::postDRIR(uint32_t interrupt)
{ {
uint64_t bitvector = (uint64_t)0x1 << interrupt; uint64_t bitvector = ULL(1) << interrupt;
drir |= bitvector;
uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size(); uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size();
assert(size <= Tsunami::Max_CPUs);
drir |= bitvector;
for(int i=0; i < size; i++) { for(int i=0; i < size; i++) {
dir[i] = dim[i] & drir; dir[i] = dim[i] & drir;
if (dim[i] & bitvector) { if (dim[i] & bitvector) {
@ -376,8 +491,10 @@ TsunamiCChip::postDRIR(uint32_t interrupt)
void void
TsunamiCChip::clearDRIR(uint32_t interrupt) TsunamiCChip::clearDRIR(uint32_t interrupt)
{ {
uint64_t bitvector = (uint64_t)0x1 << interrupt; uint64_t bitvector = ULL(1) << interrupt;
uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size(); uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size();
assert(size <= Tsunami::Max_CPUs);
if (drir & bitvector) if (drir & bitvector)
{ {
drir &= ~bitvector; drir &= ~bitvector;
@ -407,11 +524,9 @@ TsunamiCChip::serialize(std::ostream &os)
{ {
SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs);
SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs);
SERIALIZE_ARRAY(dirInterrupting, Tsunami::Max_CPUs); SERIALIZE_SCALAR(ipint);
SERIALIZE_ARRAY(ipiInterrupting, Tsunami::Max_CPUs); SERIALIZE_SCALAR(itint);
SERIALIZE_SCALAR(drir); SERIALIZE_SCALAR(drir);
SERIALIZE_SCALAR(misc);
SERIALIZE_ARRAY(RTCInterrupting, Tsunami::Max_CPUs);
} }
void void
@ -419,11 +534,9 @@ TsunamiCChip::unserialize(Checkpoint *cp, const std::string &section)
{ {
UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs);
UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs);
UNSERIALIZE_ARRAY(dirInterrupting, Tsunami::Max_CPUs); UNSERIALIZE_SCALAR(ipint);
UNSERIALIZE_ARRAY(ipiInterrupting, Tsunami::Max_CPUs); UNSERIALIZE_SCALAR(itint);
UNSERIALIZE_SCALAR(drir); UNSERIALIZE_SCALAR(drir);
UNSERIALIZE_SCALAR(misc);
UNSERIALIZE_ARRAY(RTCInterrupting, Tsunami::Max_CPUs);
} }
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)

View file

@ -47,7 +47,7 @@ class TsunamiCChip : public PioDevice
Addr addr; Addr addr;
/** The size of mappad from the above address */ /** The size of mappad from the above address */
static const Addr size = 0xfff; static const Addr size = 0xfffffff;
protected: protected:
/** /**
@ -68,7 +68,6 @@ class TsunamiCChip : public PioDevice
* One exists for each CPU, the DRIR X DIM = DIR * One exists for each CPU, the DRIR X DIM = DIR
*/ */
uint64_t dir[Tsunami::Max_CPUs]; uint64_t dir[Tsunami::Max_CPUs];
bool dirInterrupting[Tsunami::Max_CPUs];
/** /**
* This register contains bits for each PCI interrupt * This register contains bits for each PCI interrupt
@ -76,17 +75,11 @@ class TsunamiCChip : public PioDevice
*/ */
uint64_t drir; uint64_t drir;
/** /** Indicator of which CPUs have an IPI interrupt */
* The MISC register contains the CPU we are currently on uint64_t ipint;
* as well as bits to ack RTC and IPI interrupts.
*/
uint64_t misc;
/** Count of the number of pending IPIs on a CPU */ /** Indicator of which CPUs have an RTC interrupt */
uint64_t ipiInterrupting[Tsunami::Max_CPUs]; uint64_t itint;
/** Indicator of which CPUs have had an RTC interrupt */
bool RTCInterrupting[Tsunami::Max_CPUs];
public: public:
/** /**
@ -137,6 +130,25 @@ class TsunamiCChip : public PioDevice
*/ */
void clearDRIR(uint32_t interrupt); void clearDRIR(uint32_t interrupt);
/**
* post an ipi interrupt to the CPU.
* @param ipintr the cpu number to clear(bitvector)
*/
void clearIPI(uint64_t ipintr);
/**
* clear a timer interrupt previously posted to the CPU.
* @param interrupt the cpu number to clear(bitvector)
*/
void clearITI(uint64_t itintr);
/**
* request an interrupt be posted to the CPU.
* @param ipreq the cpu number to interrupt(bitvector)
*/
void reqIPI(uint64_t ipreq);
/** /**
* Serialize this object to the given output stream. * Serialize this object to the given output stream.
* @param os The stream to serialize to. * @param os The stream to serialize to.

View file

@ -60,6 +60,13 @@
#define TSDEV_CC_IIC2 0x1C #define TSDEV_CC_IIC2 0x1C
#define TSDEV_CC_IIC3 0x1D #define TSDEV_CC_IIC3 0x1D
// BigTsunami Registers
#define TSDEV_CC_BDIMS 0x1000000
#define TSDEV_CC_BDIRS 0x2000000
#define TSDEV_CC_IPIQ 0x20 //0xf01a000800
#define TSDEV_CC_IPIR 0x21 //0xf01a000840
#define TSDEV_CC_ITIR 0x22 //0xf01a000880
// PChip Registers // PChip Registers
#define TSDEV_PC_WSBA0 0x00 #define TSDEV_PC_WSBA0 0x00

View file

@ -40,13 +40,15 @@
using namespace std; using namespace std;
#ifdef DEBUG
void void
debug_break() debug_break()
{ {
#ifndef NDEBUG
kill(getpid(), SIGTRAP); kill(getpid(), SIGTRAP);
} #else
cprintf("debug_break suppressed, compiled with NDEBUG\n");
#endif #endif
}
// //
// Debug event: place a breakpoint on the process function and // Debug event: place a breakpoint on the process function and

View file

@ -29,10 +29,6 @@
#ifndef __DEBUG_HH__ #ifndef __DEBUG_HH__
#define __DEBUG_HH__ #define __DEBUG_HH__
#ifdef DEBUG
void debug_break(); void debug_break();
#else
inline void debug_break() { }
#endif
#endif // __DEBUG_HH__ #endif // __DEBUG_HH__

View file

@ -47,28 +47,21 @@ def wrapop(op, lv, rv):
return op(lv, rv) return op(lv, rv)
def same(lv, rv): def same(lrun, rrun):
for lrun,rrun in zip(lv.keys(),rv.keys()): for lx,rx in zip(lrun.keys(),rrun.keys()):
if lrun != rrun: if lx != rx:
print 'lrun != rrun' print 'lx != rx'
print lrun, rrun print lx, rx
print lv.keys() print lrun.keys()
print rv.keys() print rrun.keys()
return False return False
for lx,rx in zip(lv[lrun].keys(),rv[rrun].keys()): for ly,ry in zip(lrun[lx].keys(),rrun[rx].keys()):
if lx != rx: if ly != ry:
print 'lx != rx' print 'ly != ry'
print lx, rx print ly, ry
print lv[lrun].keys() print lrun[lx].keys()
print rv[rrun].keys() print rrun[rx].keys()
return False return False
for ly,ry in zip(lv[lrun][lx].keys(),rv[rrun][rx].keys()):
if ly != ry:
print 'ly != ry'
print ly, ry
print lv[lrun][lx].keys()
print rv[rrun][rx].keys()
return False
return True return True
@ -79,10 +72,15 @@ def binaryop(op, lf, rf):
lv = lf.value lv = lf.value
rv = rf.value rv = rf.value
if not same(lv, rv): theruns = []
raise AttributeError, "run,x,y not identical" for r in lv.keys():
if rv.has_key(r):
if same(lv[r], rv[r]):
theruns.append(r)
else:
raise AttributeError
for run in lv.keys(): for run in theruns:
result[run] = {} result[run] = {}
for x in lv[run].keys(): for x in lv[run].keys():
result[run][x] = {} result[run][x] = {}

View file

@ -39,23 +39,50 @@ def unique(list):
map(set.__setitem__, list, []) map(set.__setitem__, list, [])
return set.keys() return set.keys()
def graphdata(runs, tag, label, value): def graphdata(runs, options, tag, label, value):
import info import info
configs = ['stx', 'ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ] configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
benchmarks = [ 'm', 's' ] #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'nt2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'nw2', 'nw3' ]
dmas = [ 'x', 'd', 'b' ] #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'w1', 'w2', 'w3', 'ns', 'nm', 'w1s' ]
benchmarks = [ 'm', 's', 'nb1', 'nb2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'snt' ]
#dmas = [ 'x', 'd', 'b' ]
dmas = [ 'x' ]
caches = [ '2', '4' ] caches = [ '2', '4' ]
checkpoints = [ '1' ]
names = [] names = []
bench_system = {
'm' : 'client',
's' : 'client',
'snt' : 'client',
'nb1' : 'server',
'nb2' : 'server',
'nt1' : 'server',
'nt2' : 'server',
'w1' : 'server',
'w2' : 'server',
'w3' : 'server',
'w4' : 'server',
'w1s' : 'server',
'w2s' : 'server',
'w3s' : 'server',
'ns' : 'natbox',
'nm' : 'natbox',
'nw1' : 'natbox',
'nw2' : 'natbox',
'nw3' : 'natbox'
}
for bench in benchmarks: for bench in benchmarks:
if bench_system[bench] != options.system:
continue
for dma in dmas: for dma in dmas:
for cache in caches: for cache in caches:
for cpt in checkpoints: names.append([bench, dma, cache])
names.append([bench, dma, cache, cpt])
for bench,dma,cache,cpt in names: for bench,dma,cache in names:
base = '%s.%s.%s.%s' % (bench, dma, cache, cpt) base = '%s.%s.%s' % (bench, dma, cache)
fname = 'data/%s.%s.dat' % (tag, base) fname = 'data/%s.%s.dat' % (tag, base)
f = open(fname, 'w') f = open(fname, 'w')
print >>f, '#set TITLE = %s' % base print >>f, '#set TITLE = %s' % base
@ -66,8 +93,7 @@ def graphdata(runs, tag, label, value):
for speed,freq in zip(['s', 'q'],['4GHz','10GHz']): for speed,freq in zip(['s', 'q'],['4GHz','10GHz']):
print >>f, '"%s"' % freq, print >>f, '"%s"' % freq,
for conf in configs: for conf in configs:
name = '%s.%s.%s.%s.%s.%s' % (conf, bench, dma, speed, cache, name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed)
cpt)
run = info.source.allRunNames[name] run = info.source.allRunNames[name]
info.display_run = run.run; info.display_run = run.run;
val = float(value) val = float(value)
@ -174,7 +200,7 @@ def commands(options, command, args):
stats = info.source.getStat(args[0]) stats = info.source.getStat(args[0])
for stat in stats: for stat in stats:
if options.graph: if options.graph:
graphdata(runs, stat.name, stat.name, stat) graphdata(runs, options, stat.name, stat.name, stat)
else: else:
if options.binned: if options.binned:
print 'kernel ticks' print 'kernel ticks'
@ -200,6 +226,39 @@ def commands(options, command, args):
printdata(runs, stat) printdata(runs, stat)
return return
if command == 'formula':
if len(args) != 1:
raise CommandException
stats = eval(args[0])
for stat in stats:
if options.graph:
graphdata(runs, options, stat.name, stat.name, stat)
else:
if options.binned:
print 'kernel ticks'
stat.bins = 'kernel'
printdata(runs, stat)
print 'idle ticks'
stat.bins = 'idle'
printdata(runs, stat)
print 'user ticks'
stat.bins = 'user'
printdata(runs, stat)
print 'interrupt ticks'
stat.bins = 'user'
printdata(runs, stat)
print 'total ticks'
stat.bins = None
print args[0]
printdata(runs, stat)
return
if command == 'bins': if command == 'bins':
if len(args) == 0: if len(args) == 0:
info.source.listBins() info.source.listBins()
@ -241,7 +300,7 @@ def commands(options, command, args):
user.bins = 'user' user.bins = 'user'
if options.graph: if options.graph:
graphdata(runs, 'usertime', 'User Fraction', graphdata(runs, options, 'usertime', 'User Fraction',
user / system.full_cpu.numCycles) user / system.full_cpu.numCycles)
else: else:
printdata(runs, user / system.full_cpu.numCycles) printdata(runs, user / system.full_cpu.numCycles)
@ -270,7 +329,7 @@ def commands(options, command, args):
if command == 'packets': if command == 'packets':
packets = system.tsunami.etherdev.rxPackets packets = system.tsunami.etherdev.rxPackets
if options.graph: if options.graph:
graphdata(runs, 'packets', 'Packets', packets) graphdata(runs, options, 'packets', 'Packets', packets)
else: else:
printdata(runs, packets) printdata(runs, packets)
return return
@ -283,7 +342,7 @@ def commands(options, command, args):
if command == 'pps': if command == 'pps':
pps = system.tsunami.etherdev.rxPackets / sim_seconds pps = system.tsunami.etherdev.rxPackets / sim_seconds
if options.graph: if options.graph:
graphdata(runs, 'pps', 'Packets/s', pps) graphdata(runs, options, 'pps', 'Packets/s', pps)
else: else:
printdata(runs, pps) printdata(runs, pps)
return return
@ -292,7 +351,7 @@ def commands(options, command, args):
bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
bpt = bytes / sim_ticks * 8 bpt = bytes / sim_ticks * 8
if options.graph: if options.graph:
graphdata(runs, 'bpt', 'bps / Hz', bpt) graphdata(runs, options, 'bpt', 'bps / Hz', bpt)
else: else:
printdata(runs, bpt, command == 'tpb') printdata(runs, bpt, command == 'tpb')
return return
@ -339,7 +398,7 @@ def commands(options, command, args):
if command == 'rxbps': if command == 'rxbps':
gbps = system.tsunami.etherdev.rxBandwidth / 1e9 gbps = system.tsunami.etherdev.rxBandwidth / 1e9
if options.graph: if options.graph:
graphdata(runs, 'rxbps', 'Bandwidth (Gbps)', gbps) graphdata(runs, options, 'rxbps', 'Bandwidth (Gbps)', gbps)
else: else:
printdata(runs, gbps) printdata(runs, gbps)
return return
@ -347,7 +406,7 @@ def commands(options, command, args):
if command == 'txbps': if command == 'txbps':
gbps = system.tsunami.etherdev.txBandwidth / 1e9 gbps = system.tsunami.etherdev.txBandwidth / 1e9
if options.graph: if options.graph:
graphdata(runs, 'txbps', 'Bandwidth (Gbps)', gbps) graphdata(runs, options, 'txbps', 'Bandwidth (Gbps)', gbps)
else: else:
printdata(runs, gbps) printdata(runs, gbps)
return return
@ -357,7 +416,7 @@ def commands(options, command, args):
txbps = system.tsunami.etherdev.txBandwidth txbps = system.tsunami.etherdev.txBandwidth
gbps = (rxbps + txbps) / 1e9 gbps = (rxbps + txbps) / 1e9
if options.graph: if options.graph:
graphdata(runs, 'bps', 'Bandwidth (Gbps)', gbps) graphdata(runs, options, 'bps', 'Bandwidth (Gbps)', gbps)
else: else:
printdata(runs, gbps) printdata(runs, gbps)
return return
@ -381,7 +440,7 @@ def commands(options, command, args):
stat.bins = None stat.bins = None
if options.graph: if options.graph:
graphdata(runs, 'misses', 'Overall MSHR Misses', stat) graphdata(runs, options, 'misses', 'Overall MSHR Misses', stat)
else: else:
printdata(runs, stat) printdata(runs, stat)
return return
@ -412,11 +471,42 @@ def commands(options, command, args):
mpkb = misses / ((rxbytes + txbytes) / 1024) mpkb = misses / ((rxbytes + txbytes) / 1024)
misses.bins = None misses.bins = None
if options.graph: if options.graph:
graphdata(runs, 'mpkb', 'Misses / KB', mpkb) graphdata(runs, options, 'mpkb', 'Misses / KB', mpkb)
else: else:
printdata(runs, mpkb) printdata(runs, mpkb)
return return
if command == 'ipkb':
interrupts = system.full_cpu.kern.faults[4]
rxbytes = system.tsunami.etherdev.rxBytes
txbytes = system.tsunami.etherdev.txBytes
if options.binned:
print 'ipkb kernel stats'
interrupts.bins = 'kernel'
ipkb = interrupts / ((rxbytes + txbytes) / 1024)
printdata(runs, ipkb)
print 'ipkb idle stats'
interrupts.bins = 'idle'
ipkb = interrupts / ((rxbytes + txbytes) / 1024)
printdata(runs, ipkb)
print 'ipkb user stats'
interrupts.bins = 'user'
ipkb = interrupts / ((rxbytes + txbytes) / 1024)
printdata(runs, ipkb)
print 'ipkb total stats'
ipkb = interrupts / ((rxbytes + txbytes) / 1024)
interrupts.bins = None
if options.graph:
graphdata(runs, options, 'ipkb', 'Interrupts / KB', ipkb)
else:
printdata(runs, ipkb)
return
if command == 'execute': if command == 'execute':
printdata(runs, system.full_cpu.ISSUE__count) printdata(runs, system.full_cpu.ISSUE__count)
return return
@ -433,7 +523,7 @@ def commands(options, command, args):
ed = system.tsunami.etherdev ed = system.tsunami.etherdev
bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets) bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets)
if options.graph: if options.graph:
graphdata(runs, 'bpp', 'Bytes / Packet', bpp) graphdata(runs, options, 'bpp', 'Bytes / Packet', bpp)
else: else:
printdata(runs, bpp) printdata(runs, bpp)
return return
@ -441,7 +531,7 @@ def commands(options, command, args):
if command == 'rxbpp': if command == 'rxbpp':
bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets
if options.graph: if options.graph:
graphdata(runs, 'rxbpp', 'Receive Bytes / Packet', bpp) graphdata(runs, options, 'rxbpp', 'Receive Bytes / Packet', bpp)
else: else:
printdata(runs, bpp) printdata(runs, bpp)
return return
@ -449,7 +539,7 @@ def commands(options, command, args):
if command == 'txbpp': if command == 'txbpp':
bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets
if options.graph: if options.graph:
graphdata(runs, 'txbpp', 'Transmit Bytes / Packet', bpp) graphdata(runs, options, 'txbpp', 'Transmit Bytes / Packet', bpp)
else: else:
printdata(runs, bpp) printdata(runs, bpp)
return return
@ -457,7 +547,7 @@ def commands(options, command, args):
if command == 'rtp': if command == 'rtp':
rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets
if options.graph: if options.graph:
graphdata(runs, 'rtp', 'rxPackets / txPackets', rtp) graphdata(runs, options, 'rtp', 'rxPackets / txPackets', rtp)
else: else:
printdata(runs, rtp) printdata(runs, rtp)
return return
@ -465,7 +555,7 @@ def commands(options, command, args):
if command == 'rtb': if command == 'rtb':
rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes
if options.graph: if options.graph:
graphdata(runs, 'rtb', 'rxBytes / txBytes', rtb) graphdata(runs, options, 'rtb', 'rxBytes / txBytes', rtb)
else: else:
printdata(runs, rtb) printdata(runs, rtb)
return return