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:
commit
a435be1b00
20 changed files with 726 additions and 162 deletions
|
@ -108,14 +108,14 @@ EcoffObject::loadGlobalSymbols(SymbolTable *symtab)
|
|||
return false;
|
||||
|
||||
if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
|
||||
cprintf("wrong magic\n");
|
||||
warn("loadGlobalSymbols: wrong magic on %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
|
||||
if (syms->magic != magicSym2) {
|
||||
cprintf("bad symbol header magic\n");
|
||||
exit(1);
|
||||
warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
ecoff_extsym *ext_syms = (ecoff_extsym *)(fileData + syms->cbExtOffset);
|
||||
|
@ -137,14 +137,14 @@ EcoffObject::loadLocalSymbols(SymbolTable *symtab)
|
|||
return false;
|
||||
|
||||
if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
|
||||
cprintf("wrong magic\n");
|
||||
warn("loadGlobalSymbols: wrong magic on %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
|
||||
if (syms->magic != magicSym2) {
|
||||
cprintf("bad symbol header magic\n");
|
||||
exit(1);
|
||||
warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
ecoff_sym *local_syms = (ecoff_sym *)(fileData + syms->cbSymOffset);
|
||||
|
|
|
@ -64,7 +64,7 @@ ListenSocket::listen(int port, bool reuse)
|
|||
|
||||
fd = ::socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
panic("Can't create socket!");
|
||||
panic("Can't create socket:%s !", strerror(errno));
|
||||
|
||||
if (reuse) {
|
||||
int i = 1;
|
||||
|
|
45
configs/boot/netperf-stream-nt-client.rcS
Normal file
45
configs/boot/netperf-stream-nt-client.rcS
Normal 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
|
|
@ -195,7 +195,7 @@ EtherLink::Link::unserialize(Checkpoint *cp, const string §ion)
|
|||
bool packet_exists;
|
||||
UNSERIALIZE_SCALAR(packet_exists);
|
||||
if (packet_exists) {
|
||||
packet = new PacketData;
|
||||
packet = new PacketData(16384);
|
||||
packet->unserialize("packet", cp, section);
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ void
|
|||
LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion)
|
||||
{
|
||||
Event::unserialize(cp, section);
|
||||
packet = new PacketData;
|
||||
packet = new PacketData(16384);
|
||||
packet->unserialize("packet", cp, section);
|
||||
}
|
||||
|
||||
|
|
|
@ -219,8 +219,7 @@ EtherTap::process(int revent)
|
|||
|
||||
while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) {
|
||||
PacketPtr packet;
|
||||
packet = new PacketData;
|
||||
packet->data = new uint8_t[data_len];
|
||||
packet = new PacketData(data_len);
|
||||
packet->length = data_len;
|
||||
memcpy(packet->data, data, data_len);
|
||||
|
||||
|
|
243
dev/ns_gige.cc
243
dev/ns_gige.cc
|
@ -274,6 +274,180 @@ NSGigE::regStats()
|
|||
.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;
|
||||
rxBandwidth = rxBytes * Stats::constant(8) / simSeconds;
|
||||
txPacketRate = txPackets / simSeconds;
|
||||
|
@ -931,6 +1105,33 @@ NSGigE::devIntrPost(uint32_t interrupts)
|
|||
interrupts &= ~ISR_NOIMPL;
|
||||
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,
|
||||
"interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
|
||||
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
|
||||
NSGigE::devIntrClear(uint32_t interrupts)
|
||||
{
|
||||
if (interrupts & ISR_RESERVE)
|
||||
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;
|
||||
regs.isr &= ~interrupts;
|
||||
|
||||
|
@ -1767,8 +2002,7 @@ NSGigE::txKick()
|
|||
case txFifoBlock:
|
||||
if (!txPacket) {
|
||||
DPRINTF(EthernetSM, "****starting the tx of a new packet****\n");
|
||||
txPacket = new PacketData;
|
||||
txPacket->data = new uint8_t[16384];
|
||||
txPacket = new PacketData(16384);
|
||||
txPacketBufPtr = txPacket->data;
|
||||
}
|
||||
|
||||
|
@ -2034,6 +2268,7 @@ NSGigE::recvPacket(PacketPtr packet)
|
|||
if (rxFifo.avail() < packet->length) {
|
||||
DPRINTF(Ethernet,
|
||||
"packet will not fit in receive buffer...packet dropped\n");
|
||||
droppedPackets++;
|
||||
devIntrPost(ISR_RXORN);
|
||||
return false;
|
||||
}
|
||||
|
@ -2257,7 +2492,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
bool txPacketExists;
|
||||
UNSERIALIZE_SCALAR(txPacketExists);
|
||||
if (txPacketExists) {
|
||||
txPacket = new PacketData;
|
||||
txPacket = new PacketData(16384);
|
||||
txPacket->unserialize("txPacket", cp, section);
|
||||
uint32_t txPktBufPtr;
|
||||
UNSERIALIZE_SCALAR(txPktBufPtr);
|
||||
|
@ -2269,7 +2504,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
UNSERIALIZE_SCALAR(rxPacketExists);
|
||||
rxPacket = 0;
|
||||
if (rxPacketExists) {
|
||||
rxPacket = new PacketData;
|
||||
rxPacket = new PacketData(16384);
|
||||
rxPacket->unserialize("rxPacket", cp, section);
|
||||
uint32_t rxPktBufPtr;
|
||||
UNSERIALIZE_SCALAR(rxPktBufPtr);
|
||||
|
|
|
@ -385,6 +385,33 @@ class NSGigE : public PciDev
|
|||
Stats::Formula rxBandwidth;
|
||||
Stats::Formula txPacketRate;
|
||||
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:
|
||||
Tick cacheAccess(MemReqPtr &req);
|
||||
|
|
|
@ -33,10 +33,12 @@
|
|||
#include <deque>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <bitset>
|
||||
|
||||
#include "base/trace.hh"
|
||||
#include "dev/pciconfigall.hh"
|
||||
#include "dev/pcidev.hh"
|
||||
#include "dev/pcireg.h"
|
||||
#include "mem/bus/bus.hh"
|
||||
#include "mem/bus/pio_interface.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;
|
||||
}
|
||||
|
||||
// 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
|
||||
PciConfigAll::read(MemReqPtr &req, uint8_t *data)
|
||||
{
|
||||
|
|
|
@ -115,6 +115,12 @@ class PciConfigAll : public PioDevice
|
|||
|
||||
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.
|
||||
* @param os The stream to serialize to.
|
||||
|
@ -134,6 +140,7 @@ class PciConfigAll : public PioDevice
|
|||
* @return Tick when the request is done
|
||||
*/
|
||||
Tick cacheAccess(MemReqPtr &req);
|
||||
|
||||
};
|
||||
|
||||
#endif // __PCICONFIGALL_HH__
|
||||
|
|
|
@ -141,6 +141,10 @@ class PciDev : public DmaDevice
|
|||
intrClear()
|
||||
{ plat->clearPciInt(configData->config.hdr.pci0.interruptLine); }
|
||||
|
||||
uint8_t
|
||||
interruptLine()
|
||||
{ return configData->config.hdr.pci0.interruptLine; }
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor for PCI Dev. This function copies data from the
|
||||
|
|
|
@ -63,7 +63,7 @@ PacketFifo::unserialize(const string &base, Checkpoint *cp,
|
|||
fifo.resize(fifosize);
|
||||
|
||||
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);
|
||||
fifo.push_back(p);
|
||||
}
|
||||
|
|
|
@ -1225,7 +1225,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
UNSERIALIZE_SCALAR(rxPacketExists);
|
||||
rxPacket = 0;
|
||||
if (rxPacketExists) {
|
||||
rxPacket = new PacketData;
|
||||
rxPacket = new PacketData(16384);
|
||||
rxPacket->unserialize("rxPacket", cp, section);
|
||||
uint32_t rxPktBufPtr;
|
||||
UNSERIALIZE_SCALAR(rxPktBufPtr);
|
||||
|
@ -1245,7 +1245,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
UNSERIALIZE_SCALAR(txPacketExists);
|
||||
txPacket = 0;
|
||||
if (txPacketExists) {
|
||||
txPacket = new PacketData;
|
||||
txPacket = new PacketData(16384);
|
||||
txPacket->unserialize("txPacket", cp, section);
|
||||
uint32_t txPktBufPtr;
|
||||
UNSERIALIZE_SCALAR(txPktBufPtr);
|
||||
|
|
|
@ -58,7 +58,7 @@ class Tsunami : public Platform
|
|||
public:
|
||||
|
||||
/** Max number of CPUs in a Tsunami */
|
||||
static const int Max_CPUs = 4;
|
||||
static const int Max_CPUs = 64;
|
||||
|
||||
/** Pointer to the system */
|
||||
System *system;
|
||||
|
|
|
@ -55,14 +55,6 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
|
|||
{
|
||||
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) {
|
||||
pioInterface = newPioInterface(name, hier, bus, this,
|
||||
&TsunamiCChip::cacheAccess);
|
||||
|
@ -71,7 +63,14 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
|
|||
}
|
||||
|
||||
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
|
||||
tsunami->cchip = this;
|
||||
|
@ -80,16 +79,29 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
|
|||
Fault
|
||||
TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
|
||||
{
|
||||
DPRINTF(Tsunami, "read va=%#x size=%d\n",
|
||||
req->vaddr, req->size);
|
||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", 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;
|
||||
|
||||
switch (req->size) {
|
||||
|
||||
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:
|
||||
*(uint64_t*)data = 0x0;
|
||||
return No_Fault;
|
||||
|
@ -97,7 +109,9 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
|
|||
panic("TSDEV_CC_MTR not implemeted\n");
|
||||
return No_Fault;
|
||||
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;
|
||||
case TSDEV_CC_AAR0:
|
||||
case TSDEV_CC_AAR1:
|
||||
|
@ -147,6 +161,12 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
|
|||
case TSDEV_CC_MPR3:
|
||||
panic("TSDEV_CC_MPRx not implemented\n");
|
||||
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:
|
||||
panic("default in cchip read reached, accessing 0x%x\n");
|
||||
} // uint64_t
|
||||
|
@ -158,7 +178,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
|
|||
default:
|
||||
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;
|
||||
}
|
||||
|
@ -169,15 +189,57 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
|
|||
DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n",
|
||||
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;
|
||||
uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size();
|
||||
|
||||
switch (req->size) {
|
||||
|
||||
case sizeof(uint64_t):
|
||||
switch(daddr) {
|
||||
if (daddr & TSDEV_CC_BDIMS)
|
||||
{
|
||||
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");
|
||||
return No_Fault;
|
||||
|
@ -189,19 +251,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
|
|||
ipreq = (*(uint64_t*)data >> 12) & 0xF;
|
||||
//If it is bit 12-15, this is an IPI post
|
||||
if (ipreq) {
|
||||
for (int cpunum=0; cpunum < Tsunami::Max_CPUs; cpunum++) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
reqIPI(ipreq);
|
||||
supportedWrite = true;
|
||||
}
|
||||
|
||||
|
@ -209,36 +259,15 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
|
|||
uint64_t ipintr;
|
||||
ipintr = (*(uint64_t*)data >> 8) & 0xF;
|
||||
if (ipintr) {
|
||||
for (int cpunum=0; cpunum < Tsunami::Max_CPUs; cpunum++) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
clearIPI(ipintr);
|
||||
supportedWrite = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//If it is the 4-7th bit, clear the RTC interrupt
|
||||
uint64_t itintr;
|
||||
if ((itintr = (*(uint64_t*) data) & (0xf<<4))) {
|
||||
//Clear the bits in ITINTR
|
||||
misc &= ~(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);
|
||||
}
|
||||
}
|
||||
itintr = (*(uint64_t*)data >> 4) & 0xF;
|
||||
if (itintr) {
|
||||
clearITI(itintr);
|
||||
supportedWrite = true;
|
||||
}
|
||||
|
||||
|
@ -261,11 +290,11 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
|
|||
case TSDEV_CC_DIM2:
|
||||
case TSDEV_CC_DIM3:
|
||||
int number;
|
||||
if(daddr == TSDEV_CC_DIM0)
|
||||
if(regnum == TSDEV_CC_DIM0)
|
||||
number = 0;
|
||||
else if(daddr == TSDEV_CC_DIM1)
|
||||
else if(regnum == TSDEV_CC_DIM1)
|
||||
number = 1;
|
||||
else if(daddr == TSDEV_CC_DIM2)
|
||||
else if(regnum == TSDEV_CC_DIM2)
|
||||
number = 2;
|
||||
else
|
||||
number = 3;
|
||||
|
@ -280,7 +309,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
|
|||
dir[number] = dim[number] & drir;
|
||||
for(int x = 0; x < 64; x++)
|
||||
{
|
||||
bitvector = (uint64_t)1 << x;
|
||||
bitvector = ULL(1) << x;
|
||||
// Figure out which bits have changed
|
||||
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
|
||||
tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
|
||||
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_MPR3:
|
||||
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:
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
TsunamiCChip::postRTC()
|
||||
{
|
||||
int size = tsunami->intrctrl->cpu->system->execContexts.size();
|
||||
assert(size <= Tsunami::Max_CPUs);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (!RTCInterrupting[i]) {
|
||||
misc |= 16 << i;
|
||||
RTCInterrupting[i] = true;
|
||||
uint64_t cpumask = ULL(1) << i;
|
||||
if (!(cpumask & itint)) {
|
||||
itint |= cpumask;
|
||||
tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0);
|
||||
DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i);
|
||||
}
|
||||
|
@ -360,9 +473,11 @@ TsunamiCChip::postRTC()
|
|||
void
|
||||
TsunamiCChip::postDRIR(uint32_t interrupt)
|
||||
{
|
||||
uint64_t bitvector = (uint64_t)0x1 << interrupt;
|
||||
drir |= bitvector;
|
||||
uint64_t bitvector = ULL(1) << interrupt;
|
||||
uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size();
|
||||
assert(size <= Tsunami::Max_CPUs);
|
||||
drir |= bitvector;
|
||||
|
||||
for(int i=0; i < size; i++) {
|
||||
dir[i] = dim[i] & drir;
|
||||
if (dim[i] & bitvector) {
|
||||
|
@ -376,8 +491,10 @@ TsunamiCChip::postDRIR(uint32_t interrupt)
|
|||
void
|
||||
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();
|
||||
assert(size <= Tsunami::Max_CPUs);
|
||||
|
||||
if (drir & bitvector)
|
||||
{
|
||||
drir &= ~bitvector;
|
||||
|
@ -407,11 +524,9 @@ TsunamiCChip::serialize(std::ostream &os)
|
|||
{
|
||||
SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs);
|
||||
SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs);
|
||||
SERIALIZE_ARRAY(dirInterrupting, Tsunami::Max_CPUs);
|
||||
SERIALIZE_ARRAY(ipiInterrupting, Tsunami::Max_CPUs);
|
||||
SERIALIZE_SCALAR(ipint);
|
||||
SERIALIZE_SCALAR(itint);
|
||||
SERIALIZE_SCALAR(drir);
|
||||
SERIALIZE_SCALAR(misc);
|
||||
SERIALIZE_ARRAY(RTCInterrupting, Tsunami::Max_CPUs);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -419,11 +534,9 @@ TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
{
|
||||
UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs);
|
||||
UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs);
|
||||
UNSERIALIZE_ARRAY(dirInterrupting, Tsunami::Max_CPUs);
|
||||
UNSERIALIZE_ARRAY(ipiInterrupting, Tsunami::Max_CPUs);
|
||||
UNSERIALIZE_SCALAR(ipint);
|
||||
UNSERIALIZE_SCALAR(itint);
|
||||
UNSERIALIZE_SCALAR(drir);
|
||||
UNSERIALIZE_SCALAR(misc);
|
||||
UNSERIALIZE_ARRAY(RTCInterrupting, Tsunami::Max_CPUs);
|
||||
}
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
|
||||
|
|
|
@ -47,7 +47,7 @@ class TsunamiCChip : public PioDevice
|
|||
Addr addr;
|
||||
|
||||
/** The size of mappad from the above address */
|
||||
static const Addr size = 0xfff;
|
||||
static const Addr size = 0xfffffff;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -68,7 +68,6 @@ class TsunamiCChip : public PioDevice
|
|||
* One exists for each CPU, the DRIR X DIM = DIR
|
||||
*/
|
||||
uint64_t dir[Tsunami::Max_CPUs];
|
||||
bool dirInterrupting[Tsunami::Max_CPUs];
|
||||
|
||||
/**
|
||||
* This register contains bits for each PCI interrupt
|
||||
|
@ -76,17 +75,11 @@ class TsunamiCChip : public PioDevice
|
|||
*/
|
||||
uint64_t drir;
|
||||
|
||||
/**
|
||||
* The MISC register contains the CPU we are currently on
|
||||
* as well as bits to ack RTC and IPI interrupts.
|
||||
*/
|
||||
uint64_t misc;
|
||||
/** Indicator of which CPUs have an IPI interrupt */
|
||||
uint64_t ipint;
|
||||
|
||||
/** Count of the number of pending IPIs on a CPU */
|
||||
uint64_t ipiInterrupting[Tsunami::Max_CPUs];
|
||||
|
||||
/** Indicator of which CPUs have had an RTC interrupt */
|
||||
bool RTCInterrupting[Tsunami::Max_CPUs];
|
||||
/** Indicator of which CPUs have an RTC interrupt */
|
||||
uint64_t itint;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -137,6 +130,25 @@ class TsunamiCChip : public PioDevice
|
|||
*/
|
||||
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.
|
||||
* @param os The stream to serialize to.
|
||||
|
|
|
@ -60,6 +60,13 @@
|
|||
#define TSDEV_CC_IIC2 0x1C
|
||||
#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
|
||||
#define TSDEV_PC_WSBA0 0x00
|
||||
|
|
|
@ -40,13 +40,15 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
debug_break()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
kill(getpid(), SIGTRAP);
|
||||
}
|
||||
#else
|
||||
cprintf("debug_break suppressed, compiled with NDEBUG\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Debug event: place a breakpoint on the process function and
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
#ifndef __DEBUG_HH__
|
||||
#define __DEBUG_HH__
|
||||
|
||||
#ifdef DEBUG
|
||||
void debug_break();
|
||||
#else
|
||||
inline void debug_break() { }
|
||||
#endif
|
||||
|
||||
#endif // __DEBUG_HH__
|
||||
|
|
|
@ -47,27 +47,20 @@ def wrapop(op, lv, rv):
|
|||
|
||||
return op(lv, rv)
|
||||
|
||||
def same(lv, rv):
|
||||
for lrun,rrun in zip(lv.keys(),rv.keys()):
|
||||
if lrun != rrun:
|
||||
print 'lrun != rrun'
|
||||
print lrun, rrun
|
||||
print lv.keys()
|
||||
print rv.keys()
|
||||
return False
|
||||
for lx,rx in zip(lv[lrun].keys(),rv[rrun].keys()):
|
||||
def same(lrun, rrun):
|
||||
for lx,rx in zip(lrun.keys(),rrun.keys()):
|
||||
if lx != rx:
|
||||
print 'lx != rx'
|
||||
print lx, rx
|
||||
print lv[lrun].keys()
|
||||
print rv[rrun].keys()
|
||||
print lrun.keys()
|
||||
print rrun.keys()
|
||||
return False
|
||||
for ly,ry in zip(lv[lrun][lx].keys(),rv[rrun][rx].keys()):
|
||||
for ly,ry in zip(lrun[lx].keys(),rrun[rx].keys()):
|
||||
if ly != ry:
|
||||
print 'ly != ry'
|
||||
print ly, ry
|
||||
print lv[lrun][lx].keys()
|
||||
print rv[rrun][rx].keys()
|
||||
print lrun[lx].keys()
|
||||
print rrun[rx].keys()
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -79,10 +72,15 @@ def binaryop(op, lf, rf):
|
|||
lv = lf.value
|
||||
rv = rf.value
|
||||
|
||||
if not same(lv, rv):
|
||||
raise AttributeError, "run,x,y not identical"
|
||||
theruns = []
|
||||
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] = {}
|
||||
for x in lv[run].keys():
|
||||
result[run][x] = {}
|
||||
|
|
|
@ -39,23 +39,50 @@ def unique(list):
|
|||
map(set.__setitem__, list, [])
|
||||
return set.keys()
|
||||
|
||||
def graphdata(runs, tag, label, value):
|
||||
def graphdata(runs, options, tag, label, value):
|
||||
import info
|
||||
configs = ['stx', 'ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
|
||||
benchmarks = [ 'm', 's' ]
|
||||
dmas = [ 'x', 'd', 'b' ]
|
||||
configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
|
||||
#benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'nt2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'nw2', 'nw3' ]
|
||||
#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' ]
|
||||
checkpoints = [ '1' ]
|
||||
|
||||
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:
|
||||
if bench_system[bench] != options.system:
|
||||
continue
|
||||
|
||||
for dma in dmas:
|
||||
for cache in caches:
|
||||
for cpt in checkpoints:
|
||||
names.append([bench, dma, cache, cpt])
|
||||
names.append([bench, dma, cache])
|
||||
|
||||
for bench,dma,cache,cpt in names:
|
||||
base = '%s.%s.%s.%s' % (bench, dma, cache, cpt)
|
||||
for bench,dma,cache in names:
|
||||
base = '%s.%s.%s' % (bench, dma, cache)
|
||||
fname = 'data/%s.%s.dat' % (tag, base)
|
||||
f = open(fname, 'w')
|
||||
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']):
|
||||
print >>f, '"%s"' % freq,
|
||||
for conf in configs:
|
||||
name = '%s.%s.%s.%s.%s.%s' % (conf, bench, dma, speed, cache,
|
||||
cpt)
|
||||
name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed)
|
||||
run = info.source.allRunNames[name]
|
||||
info.display_run = run.run;
|
||||
val = float(value)
|
||||
|
@ -174,7 +200,7 @@ def commands(options, command, args):
|
|||
stats = info.source.getStat(args[0])
|
||||
for stat in stats:
|
||||
if options.graph:
|
||||
graphdata(runs, stat.name, stat.name, stat)
|
||||
graphdata(runs, options, stat.name, stat.name, stat)
|
||||
else:
|
||||
if options.binned:
|
||||
print 'kernel ticks'
|
||||
|
@ -200,6 +226,39 @@ def commands(options, command, args):
|
|||
printdata(runs, stat)
|
||||
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 len(args) == 0:
|
||||
info.source.listBins()
|
||||
|
@ -241,7 +300,7 @@ def commands(options, command, args):
|
|||
user.bins = 'user'
|
||||
|
||||
if options.graph:
|
||||
graphdata(runs, 'usertime', 'User Fraction',
|
||||
graphdata(runs, options, 'usertime', 'User Fraction',
|
||||
user / system.full_cpu.numCycles)
|
||||
else:
|
||||
printdata(runs, user / system.full_cpu.numCycles)
|
||||
|
@ -270,7 +329,7 @@ def commands(options, command, args):
|
|||
if command == 'packets':
|
||||
packets = system.tsunami.etherdev.rxPackets
|
||||
if options.graph:
|
||||
graphdata(runs, 'packets', 'Packets', packets)
|
||||
graphdata(runs, options, 'packets', 'Packets', packets)
|
||||
else:
|
||||
printdata(runs, packets)
|
||||
return
|
||||
|
@ -283,7 +342,7 @@ def commands(options, command, args):
|
|||
if command == 'pps':
|
||||
pps = system.tsunami.etherdev.rxPackets / sim_seconds
|
||||
if options.graph:
|
||||
graphdata(runs, 'pps', 'Packets/s', pps)
|
||||
graphdata(runs, options, 'pps', 'Packets/s', pps)
|
||||
else:
|
||||
printdata(runs, pps)
|
||||
return
|
||||
|
@ -292,7 +351,7 @@ def commands(options, command, args):
|
|||
bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
|
||||
bpt = bytes / sim_ticks * 8
|
||||
if options.graph:
|
||||
graphdata(runs, 'bpt', 'bps / Hz', bpt)
|
||||
graphdata(runs, options, 'bpt', 'bps / Hz', bpt)
|
||||
else:
|
||||
printdata(runs, bpt, command == 'tpb')
|
||||
return
|
||||
|
@ -339,7 +398,7 @@ def commands(options, command, args):
|
|||
if command == 'rxbps':
|
||||
gbps = system.tsunami.etherdev.rxBandwidth / 1e9
|
||||
if options.graph:
|
||||
graphdata(runs, 'rxbps', 'Bandwidth (Gbps)', gbps)
|
||||
graphdata(runs, options, 'rxbps', 'Bandwidth (Gbps)', gbps)
|
||||
else:
|
||||
printdata(runs, gbps)
|
||||
return
|
||||
|
@ -347,7 +406,7 @@ def commands(options, command, args):
|
|||
if command == 'txbps':
|
||||
gbps = system.tsunami.etherdev.txBandwidth / 1e9
|
||||
if options.graph:
|
||||
graphdata(runs, 'txbps', 'Bandwidth (Gbps)', gbps)
|
||||
graphdata(runs, options, 'txbps', 'Bandwidth (Gbps)', gbps)
|
||||
else:
|
||||
printdata(runs, gbps)
|
||||
return
|
||||
|
@ -357,7 +416,7 @@ def commands(options, command, args):
|
|||
txbps = system.tsunami.etherdev.txBandwidth
|
||||
gbps = (rxbps + txbps) / 1e9
|
||||
if options.graph:
|
||||
graphdata(runs, 'bps', 'Bandwidth (Gbps)', gbps)
|
||||
graphdata(runs, options, 'bps', 'Bandwidth (Gbps)', gbps)
|
||||
else:
|
||||
printdata(runs, gbps)
|
||||
return
|
||||
|
@ -381,7 +440,7 @@ def commands(options, command, args):
|
|||
|
||||
stat.bins = None
|
||||
if options.graph:
|
||||
graphdata(runs, 'misses', 'Overall MSHR Misses', stat)
|
||||
graphdata(runs, options, 'misses', 'Overall MSHR Misses', stat)
|
||||
else:
|
||||
printdata(runs, stat)
|
||||
return
|
||||
|
@ -412,11 +471,42 @@ def commands(options, command, args):
|
|||
mpkb = misses / ((rxbytes + txbytes) / 1024)
|
||||
misses.bins = None
|
||||
if options.graph:
|
||||
graphdata(runs, 'mpkb', 'Misses / KB', mpkb)
|
||||
graphdata(runs, options, 'mpkb', 'Misses / KB', mpkb)
|
||||
else:
|
||||
printdata(runs, mpkb)
|
||||
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':
|
||||
printdata(runs, system.full_cpu.ISSUE__count)
|
||||
return
|
||||
|
@ -433,7 +523,7 @@ def commands(options, command, args):
|
|||
ed = system.tsunami.etherdev
|
||||
bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets)
|
||||
if options.graph:
|
||||
graphdata(runs, 'bpp', 'Bytes / Packet', bpp)
|
||||
graphdata(runs, options, 'bpp', 'Bytes / Packet', bpp)
|
||||
else:
|
||||
printdata(runs, bpp)
|
||||
return
|
||||
|
@ -441,7 +531,7 @@ def commands(options, command, args):
|
|||
if command == 'rxbpp':
|
||||
bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets
|
||||
if options.graph:
|
||||
graphdata(runs, 'rxbpp', 'Receive Bytes / Packet', bpp)
|
||||
graphdata(runs, options, 'rxbpp', 'Receive Bytes / Packet', bpp)
|
||||
else:
|
||||
printdata(runs, bpp)
|
||||
return
|
||||
|
@ -449,7 +539,7 @@ def commands(options, command, args):
|
|||
if command == 'txbpp':
|
||||
bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets
|
||||
if options.graph:
|
||||
graphdata(runs, 'txbpp', 'Transmit Bytes / Packet', bpp)
|
||||
graphdata(runs, options, 'txbpp', 'Transmit Bytes / Packet', bpp)
|
||||
else:
|
||||
printdata(runs, bpp)
|
||||
return
|
||||
|
@ -457,7 +547,7 @@ def commands(options, command, args):
|
|||
if command == 'rtp':
|
||||
rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets
|
||||
if options.graph:
|
||||
graphdata(runs, 'rtp', 'rxPackets / txPackets', rtp)
|
||||
graphdata(runs, options, 'rtp', 'rxPackets / txPackets', rtp)
|
||||
else:
|
||||
printdata(runs, rtp)
|
||||
return
|
||||
|
@ -465,7 +555,7 @@ def commands(options, command, args):
|
|||
if command == 'rtb':
|
||||
rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes
|
||||
if options.graph:
|
||||
graphdata(runs, 'rtb', 'rxBytes / txBytes', rtb)
|
||||
graphdata(runs, options, 'rtb', 'rxBytes / txBytes', rtb)
|
||||
else:
|
||||
printdata(runs, rtb)
|
||||
return
|
||||
|
|
Loading…
Reference in a new issue