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;
|
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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
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;
|
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 §ion)
|
LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion)
|
||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
243
dev/ns_gige.cc
243
dev/ns_gige.cc
|
@ -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 §ion)
|
||||||
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 §ion)
|
||||||
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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1225,7 +1225,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
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 §ion)
|
||||||
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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 §ion)
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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] = {}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue