Merge zizzer:/z/m5/Bitkeeper/m5

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

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

View file

@ -108,14 +108,14 @@ EcoffObject::loadGlobalSymbols(SymbolTable *symtab)
return false;
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);

View file

@ -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;

View file

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

View file

@ -195,7 +195,7 @@ EtherLink::Link::unserialize(Checkpoint *cp, const string &section)
bool packet_exists;
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 &section)
{
Event::unserialize(cp, section);
packet = new PacketData;
packet = new PacketData(16384);
packet->unserialize("packet", cp, section);
}

View file

@ -219,8 +219,7 @@ EtherTap::process(int revent)
while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) {
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);

View file

@ -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 &section)
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 &section)
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);

View file

@ -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);

View file

@ -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)
{

View file

@ -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__

View file

@ -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

View file

@ -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);
}

View file

@ -1225,7 +1225,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
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 &section)
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);

View file

@ -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;

View file

@ -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,16 +189,58 @@ 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) {
case TSDEV_CC_CSR:
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;
case TSDEV_CC_MTR:
@ -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 &section)
{
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)

View file

@ -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.

View file

@ -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

View file

@ -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

View file

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

View file

@ -47,28 +47,21 @@ 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()
def same(lrun, rrun):
for lx,rx in zip(lrun.keys(),rrun.keys()):
if lx != rx:
print 'lx != rx'
print lx, rx
print lrun.keys()
print rrun.keys()
return False
for lx,rx in zip(lv[lrun].keys(),rv[rrun].keys()):
if lx != rx:
print 'lx != rx'
print lx, rx
print lv[lrun].keys()
print rv[rrun].keys()
for ly,ry in zip(lrun[lx].keys(),rrun[rx].keys()):
if ly != ry:
print 'ly != ry'
print ly, ry
print lrun[lx].keys()
print rrun[rx].keys()
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
@ -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] = {}

View file

@ -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