diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/alpha/tlb.cc | 8 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/swap.isa | 2 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 3 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 1 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 2 | ||||
-rw-r--r-- | src/cpu/simple_thread.cc | 8 | ||||
-rw-r--r-- | src/dev/etherint.hh | 3 | ||||
-rw-r--r-- | src/dev/etherlink.hh | 1 | ||||
-rw-r--r-- | src/dev/i8254xGBe.cc | 6 | ||||
-rw-r--r-- | src/dev/uart8250.cc | 27 | ||||
-rw-r--r-- | src/dev/uart8250.hh | 1 | ||||
-rw-r--r-- | src/kern/linux/events.cc | 13 | ||||
-rw-r--r-- | src/kern/linux/events.hh | 8 | ||||
-rw-r--r-- | src/kern/linux/printk.cc | 13 | ||||
-rw-r--r-- | src/kern/linux/printk.hh | 4 | ||||
-rw-r--r-- | src/kern/tru64/tru64.hh | 2 | ||||
-rw-r--r-- | src/mem/bridge.cc | 45 | ||||
-rw-r--r-- | src/mem/bridge.hh | 51 | ||||
-rw-r--r-- | src/mem/bus.cc | 73 | ||||
-rw-r--r-- | src/mem/bus.hh | 22 | ||||
-rw-r--r-- | src/mem/packet.cc | 2 | ||||
-rw-r--r-- | src/mem/port.hh | 6 | ||||
-rw-r--r-- | src/python/m5/objects/Bridge.py | 2 | ||||
-rw-r--r-- | src/python/m5/objects/Bus.py | 1 |
24 files changed, 215 insertions, 89 deletions
diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 3ab65e664..2dfff8c5f 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -213,7 +213,7 @@ TLB::flushAddr(Addr addr, uint8_t asn) if (i == lookupTable.end()) return; - while (i->first == vaddr.vpn()) { + while (i != lookupTable.end() && i->first == vaddr.vpn()) { int index = i->second; PTE *pte = &table[index]; assert(pte->valid); @@ -225,10 +225,10 @@ TLB::flushAddr(Addr addr, uint8_t asn) // invalidate this entry pte->valid = false; - lookupTable.erase(i); + lookupTable.erase(i++); + } else { + ++i; } - - ++i; } } diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa index 3814d1030..dde327f5c 100644 --- a/src/arch/sparc/isa/formats/mem/swap.isa +++ b/src/arch/sparc/isa/formats/mem/swap.isa @@ -39,7 +39,7 @@ def template SwapExecute {{ Addr EA; %(fp_enable_check)s; %(op_decl)s; - uint64_t mem_data; + uint64_t mem_data = 0; %(op_rd)s; %(ea_code)s; diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index fc24d7edc..9411c6c62 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -642,9 +642,6 @@ DefaultCommit<Impl>::handleInterrupt() // an interrupt needed to be handled. DPRINTF(Commit, "Interrupt detected.\n"); - Fault new_interrupt = cpu->getInterrupts(); - assert(new_interrupt != NoFault); - // Clear the interrupt now that it's going to be handled toIEW->commitInfo[0].clearInterrupt = true; diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 44e2cea76..bde4f8079 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -680,7 +680,6 @@ LSQUnit<Impl>::writebackStores() inst->seqNum); WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this); wb->schedule(curTick + 1); - delete state; completeStore(storeWBIdx); incrStIdx(storeWBIdx); continue; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 877dc5bd4..4fed2059b 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -79,7 +79,7 @@ BaseSimpleCPU::BaseSimpleCPU(Params *p) /* asid */ 0); #endif // !FULL_SYSTEM - thread->setStatus(ThreadContext::Suspended); + thread->setStatus(ThreadContext::Unallocated); tc = thread->getTC(); diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 39f31782b..191ae2f2e 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -221,10 +221,10 @@ SimpleThread::activate(int delay) lastActivate = curTick; - if (status() == ThreadContext::Unallocated) { - cpu->activateWhenReady(tid); - return; - } +// if (status() == ThreadContext::Unallocated) { +// cpu->activateWhenReady(tid); +// return; +// } _status = ThreadContext::Active; diff --git a/src/dev/etherint.hh b/src/dev/etherint.hh index dfc224ecc..430f45d66 100644 --- a/src/dev/etherint.hh +++ b/src/dev/etherint.hh @@ -63,6 +63,9 @@ class EtherInt : public SimObject bool sendPacket(EthPacketPtr packet) { return peer ? peer->recvPacket(packet) : true; } virtual bool recvPacket(EthPacketPtr packet) = 0; + + bool askBusy() {return peer->isBusy(); } + virtual bool isBusy() { return false; } }; #endif // __DEV_ETHERINT_HH__ diff --git a/src/dev/etherlink.hh b/src/dev/etherlink.hh index bb2854810..a16d6d799 100644 --- a/src/dev/etherlink.hh +++ b/src/dev/etherlink.hh @@ -114,6 +114,7 @@ class EtherLink : public SimObject Interface(const std::string &name, Link *txlink, Link *rxlink); bool recvPacket(EthPacketPtr packet) { return txlink->transmit(packet); } void sendDone() { peer->sendDone(); } + bool isBusy() { return txlink->busy(); } }; Link *link[2]; diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index 3d08bca1e..6acd06132 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -710,7 +710,7 @@ IGbE::RxDescCache::pktComplete() DPRINTF(EthernetDesc, "Checking UDP checksum\n"); status |= RXDS_UDPCS; desc->csum = htole(cksum(udp)); - if (cksum(tcp) != 0) { + if (cksum(udp) != 0) { DPRINTF(EthernetDesc, "Checksum is bad!!\n"); err |= RXDE_TCPE; } @@ -927,11 +927,13 @@ IGbE::TxDescCache::pktComplete() if (TxdOp::txsm(desc)) { if (isTcp) { TcpPtr tcp(ip); + assert(tcp); tcp->sum(0); tcp->sum(cksum(tcp)); DPRINTF(EthernetDesc, "Calculated TCP checksum\n"); } else { UdpPtr udp(ip); + assert(udp); udp->sum(0); udp->sum(cksum(udp)); DPRINTF(EthernetDesc, "Calculated UDP checksum\n"); @@ -1028,7 +1030,7 @@ IGbE::TxDescCache::hasOutstandingEvents() void IGbE::restartClock() { - if (!tickEvent.scheduled() && (rxTick || txTick) && getState() == + if (!tickEvent.scheduled() && (rxTick || txTick || txFifoTick) && getState() == SimObject::Running) tickEvent.schedule((curTick/cycles(1)) * cycles(1) + cycles(1)); } diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index ddee33695..50307aad4 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -68,6 +68,7 @@ Uart8250::IntrEvent::process() DPRINTF(Uart, "UART InterEvent, interrupting\n"); uart->platform->postConsoleInt(); uart->status |= intrBit; + uart->lastTxInt = curTick; } else DPRINTF(Uart, "UART InterEvent, not interrupting\n"); @@ -100,14 +101,11 @@ Uart8250::IntrEvent::scheduleIntr() Uart8250::Uart8250(Params *p) - : Uart(p), txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT) + : Uart(p), IER(0), DLAB(0), LCR(0), MCR(0), lastTxInt(0), + txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT) { pioSize = 8; - IER = 0; - DLAB = 0; - LCR = 0; - MCR = 0; } Tick @@ -153,13 +151,13 @@ Uart8250::read(PacketPtr pkt) if (status & RX_INT) /* Rx data interrupt has a higher priority */ pkt->set(IIR_RXID); - else if (status & TX_INT) + else if (status & TX_INT) { pkt->set(IIR_TXID); - else + //Tx interrupts are cleared on IIR reads + status &= ~TX_INT; + } else pkt->set(IIR_NOPEND); - //Tx interrupts are cleared on IIR reads - status &= ~TX_INT; break; case 0x3: // Line Control Register (LCR) pkt->set(LCR); @@ -222,7 +220,16 @@ Uart8250::write(PacketPtr pkt) if (UART_IER_THRI & IER) { DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n"); - txIntrEvent.scheduleIntr(); + if (curTick - lastTxInt > + (Tick)((Clock::Float::s / 2e9) * 450)) { + DPRINTF(Uart, "-- Interrupting Immediately... %d,%d\n", + curTick, lastTxInt); + txIntrEvent.process(); + } else { + DPRINTF(Uart, "-- Delaying interrupt... %d,%d\n", + curTick, lastTxInt); + txIntrEvent.scheduleIntr(); + } } else { diff --git a/src/dev/uart8250.hh b/src/dev/uart8250.hh index c28200592..c9c878aed 100644 --- a/src/dev/uart8250.hh +++ b/src/dev/uart8250.hh @@ -74,6 +74,7 @@ class Uart8250 : public Uart protected: uint8_t IER, DLAB, LCR, MCR; + Tick lastTxInt; class IntrEvent : public Event { diff --git a/src/kern/linux/events.cc b/src/kern/linux/events.cc index ba52e040a..42fa63a27 100644 --- a/src/kern/linux/events.cc +++ b/src/kern/linux/events.cc @@ -37,6 +37,7 @@ #include "kern/system_events.hh" #include "sim/system.hh" +#include <sstream> namespace Linux { @@ -44,15 +45,13 @@ void DebugPrintkEvent::process(ThreadContext *tc) { if (DTRACE(DebugPrintf)) { - if (!raw) { - StringWrap name(tc->getSystemPtr()->name() + ".dprintk"); - DPRINTFN(""); - } - + std::stringstream ss; TheISA::Arguments args(tc); - Printk(args); - SkipFuncEvent::process(tc); + Printk(ss, args); + StringWrap name(tc->getSystemPtr()->name() + ".dprintk"); + DPRINTFN("%s", ss.str()); } + SkipFuncEvent::process(tc); } } // namespace linux diff --git a/src/kern/linux/events.hh b/src/kern/linux/events.hh index b0510c18f..e36a72dde 100644 --- a/src/kern/linux/events.hh +++ b/src/kern/linux/events.hh @@ -38,13 +38,9 @@ namespace Linux { class DebugPrintkEvent : public SkipFuncEvent { - private: - bool raw; - public: - DebugPrintkEvent(PCEventQueue *q, const std::string &desc, Addr addr, - bool r = false) - : SkipFuncEvent(q, desc, addr), raw(r) {} + DebugPrintkEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : SkipFuncEvent(q, desc, addr) {} virtual void process(ThreadContext *xc); }; diff --git a/src/kern/linux/printk.cc b/src/kern/linux/printk.cc index 0e9fd6620..866353e31 100644 --- a/src/kern/linux/printk.cc +++ b/src/kern/linux/printk.cc @@ -32,22 +32,18 @@ #include <sys/types.h> #include <algorithm> -#include "base/trace.hh" #include "arch/arguments.hh" +#include "base/trace.hh" +#include "kern/linux/printk.hh" using namespace std; void -Printk(TheISA::Arguments args) +Printk(stringstream &out, TheISA::Arguments args) { - std::ostream &out = Trace::output(); char *p = (char *)args++; - ios::fmtflags saved_flags = out.flags(); - char old_fill = out.fill(); - int old_precision = out.precision(); - while (*p) { switch (*p) { case '%': { @@ -258,8 +254,5 @@ Printk(TheISA::Arguments args) } } - out.flags(saved_flags); - out.fill(old_fill); - out.precision(old_precision); } diff --git a/src/kern/linux/printk.hh b/src/kern/linux/printk.hh index 17d59b765..20dfb430f 100644 --- a/src/kern/linux/printk.hh +++ b/src/kern/linux/printk.hh @@ -34,8 +34,10 @@ #include "arch/isa_specific.hh" +#include <sstream> + class TheISA::Arguments; -void Printk(TheISA::Arguments args); +void Printk(std::stringstream &out, TheISA::Arguments args); #endif // __PRINTK_HH__ diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh index b94276035..a7703be7c 100644 --- a/src/kern/tru64/tru64.hh +++ b/src/kern/tru64/tru64.hh @@ -792,7 +792,7 @@ class Tru64 : public OperatingSystem for (int i = 0; i < process->numCpus(); ++i) { ThreadContext *tc = process->threadContexts[i]; - if (tc->status() == ThreadContext::Suspended) { + if (tc->status() == ThreadContext::Unallocated) { // inactive context... grab it init_thread_context(tc, attrp, uniq_val); diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index b787f79ca..b25d135e2 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -43,20 +43,24 @@ Bridge::BridgePort::BridgePort(const std::string &_name, Bridge *_bridge, BridgePort *_otherPort, - int _delay, int _queueLimit) + int _delay, int _queueLimit, + bool fix_partial_write) : Port(_name), bridge(_bridge), otherPort(_otherPort), - delay(_delay), outstandingResponses(0), - queueLimit(_queueLimit), sendEvent(this) + delay(_delay), fixPartialWrite(fix_partial_write), + outstandingResponses(0), queueLimit(_queueLimit), sendEvent(this) { } Bridge::Bridge(const std::string &n, int qsa, int qsb, - Tick _delay, int write_ack) + Tick _delay, int write_ack, bool fix_partial_write_a, + bool fix_partial_write_b) : MemObject(n), - portA(n + "-portA", this, &portB, _delay, qsa), - portB(n + "-portB", this, &portA, _delay, qsa), + portA(n + "-portA", this, &portB, _delay, qsa, fix_partial_write_a), + portB(n + "-portB", this, &portA, _delay, qsa, fix_partial_write_b), ackWrites(write_ack) { + if (ackWrites) + panic("No support for acknowledging writes\n"); } Port * @@ -82,7 +86,10 @@ Bridge::init() { // Make sure that both sides are connected to. if (portA.getPeer() == NULL || portB.getPeer() == NULL) - panic("Both ports of bus bridge are not connected to a bus.\n"); + fatal("Both ports of bus bridge are not connected to a bus.\n"); + + if (portA.peerBlockSize() != portB.peerBlockSize()) + fatal("Busses don't have the same block size... Not supported.\n"); } @@ -107,8 +114,10 @@ Bridge::BridgePort::recvTiming(PacketPtr pkt) bool Bridge::BridgePort::queueForSendTiming(PacketPtr pkt) { - if (queueFull()) + if (queueFull()) { + DPRINTF(BusBridge, "Queue full, returning false\n"); return false; + } if (pkt->isResponse()) { // This is a response for a request we forwarded earlier. The @@ -149,6 +158,7 @@ Bridge::BridgePort::trySend() assert(!sendQueue.empty()); bool was_full = queueFull(); + int pbs = peerBlockSize(); PacketBuffer *buf = sendQueue.front(); @@ -156,10 +166,18 @@ Bridge::BridgePort::trySend() PacketPtr pkt = buf->pkt; + pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set + + if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite && + pkt->getOffset(pbs) && pkt->getSize() != pbs) { + buf->partialWriteFix(this); + pkt = buf->pkt; + } + DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", buf->origSrc, pkt->getDest(), pkt->getAddr()); - pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set + if (sendTiming(pkt)) { // send successful sendQueue.pop_front(); @@ -191,6 +209,7 @@ Bridge::BridgePort::trySend() } else { DPRINTF(BusBridge, " unsuccessful\n"); + buf->undoPartialWriteFix(); } } @@ -248,6 +267,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge) Param<int> queue_size_b; Param<Tick> delay; Param<bool> write_ack; + Param<bool> fix_partial_write_a; + Param<bool> fix_partial_write_b; END_DECLARE_SIM_OBJECT_PARAMS(Bridge) @@ -256,14 +277,16 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Bridge) INIT_PARAM(queue_size_a, "The size of the queue for data coming into side a"), INIT_PARAM(queue_size_b, "The size of the queue for data coming into side b"), INIT_PARAM(delay, "The miminum delay to cross this bridge"), - INIT_PARAM(write_ack, "Acknowledge any writes that are received.") + INIT_PARAM(write_ack, "Acknowledge any writes that are received."), + INIT_PARAM(fix_partial_write_a, "Fixup any partial block writes that are received"), + INIT_PARAM(fix_partial_write_b, "Fixup any partial block writes that are received") END_INIT_SIM_OBJECT_PARAMS(Bridge) CREATE_SIM_OBJECT(Bridge) { return new Bridge(getInstanceName(), queue_size_a, queue_size_b, delay, - write_ack); + write_ack, fix_partial_write_a, fix_partial_write_b); } REGISTER_SIM_OBJECT("Bridge", Bridge) diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index f7d0d12d0..d1154eda0 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -66,6 +66,8 @@ class Bridge : public MemObject /** Minimum delay though this bridge. */ Tick delay; + bool fixPartialWrite; + class PacketBuffer : public Packet::SenderState { public: @@ -75,10 +77,13 @@ class Bridge : public MemObject short origSrc; bool expectResponse; + bool partialWriteFixed; + PacketPtr oldPkt; + PacketBuffer(PacketPtr _pkt, Tick t) : ready(t), pkt(_pkt), origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), - expectResponse(_pkt->needsResponse()) + expectResponse(_pkt->needsResponse()), partialWriteFixed(false) { if (!pkt->isResponse()) pkt->senderState = this; @@ -89,7 +94,46 @@ class Bridge : public MemObject assert(pkt->senderState == this); pkt->setDest(origSrc); pkt->senderState = origSenderState; + if (partialWriteFixed) + delete oldPkt; + } + + void partialWriteFix(Port *port) + { + assert(!partialWriteFixed); + assert(expectResponse); + + int pbs = port->peerBlockSize(); + partialWriteFixed = true; + PacketDataPtr data; + + data = new uint8_t[pbs]; + PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq, + Packet::Broadcast, pbs); + + funcPkt->dataStatic(data); + port->sendFunctional(funcPkt); + assert(funcPkt->result == Packet::Success); + delete funcPkt; + + oldPkt = pkt; + memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(), + pkt->getSize()); + pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq, + Packet::Broadcast, pbs); + pkt->dataDynamicArray(data); + pkt->senderState = oldPkt->senderState; } + + void undoPartialWriteFix() + { + if (!partialWriteFixed) + return; + delete pkt; + pkt = oldPkt; + partialWriteFixed = false; + } + }; /** @@ -140,7 +184,7 @@ class Bridge : public MemObject /** Constructor for the BusPort.*/ BridgePort(const std::string &_name, Bridge *_bridge, BridgePort *_otherPort, - int _delay, int _queueLimit); + int _delay, int _queueLimit, bool fix_partial_write); protected: @@ -182,7 +226,8 @@ class Bridge : public MemObject virtual void init(); - Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack); + Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack, + bool fix_partial_write_a, bool fix_partial_write_b); }; #endif //__MEM_BUS_HH__ diff --git a/src/mem/bus.cc b/src/mem/bus.cc index b0636ecc2..6682ade55 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -48,6 +48,7 @@ Bus::getPort(const std::string &if_name, int idx) if (defaultPort == NULL) { defaultPort = new BusPort(csprintf("%s-default",name()), this, defaultId); + cachedBlockSizeValid = false; return defaultPort; } else fatal("Default port already set\n"); @@ -68,6 +69,7 @@ Bus::getPort(const std::string &if_name, int idx) assert(maxId < std::numeric_limits<typeof(maxId)>::max()); BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id); interfaces[id] = bp; + cachedBlockSizeValid = false; return bp; } @@ -182,6 +184,7 @@ Bus::recvTiming(PacketPtr pkt) if (tickNextIdle > curTick || (retryList.size() && (!inRetry || pktPort != retryList.front()))) { addToRetryList(pktPort); + DPRINTF(Bus, "recvTiming: Bus is busy, returning false\n"); return false; } @@ -207,11 +210,12 @@ Bus::recvTiming(PacketPtr pkt) inRetry = false; } occupyBus(pkt); + DPRINTF(Bus, "recvTiming: Packet sucessfully sent\n"); return true; } } else { //Snoop didn't succeed - DPRINTF(Bus, "Adding a retry to RETRY list %d\n", + DPRINTF(Bus, "Adding1 a retry to RETRY list %d\n", pktPort->getId()); addToRetryList(pktPort); return false; @@ -239,13 +243,14 @@ Bus::recvTiming(PacketPtr pkt) } // Packet not successfully sent. Leave or put it on the retry list. - DPRINTF(Bus, "Adding a retry to RETRY list %d\n", + DPRINTF(Bus, "Adding2 a retry to RETRY list %d\n", pktPort->getId()); addToRetryList(pktPort); return false; } else { //Forwarding up from responder, just return true; + DPRINTF(Bus, "recvTiming: can we be here?\n"); return true; } } @@ -253,12 +258,12 @@ Bus::recvTiming(PacketPtr pkt) void Bus::recvRetry(int id) { - DPRINTF(Bus, "Received a retry\n"); + DPRINTF(Bus, "Received a retry from %s\n", id == -1 ? "self" : interfaces[id]->getPeer()->name()); // If there's anything waiting, and the bus isn't busy... if (retryList.size() && curTick >= tickNextIdle) { //retryingPort = retryList.front(); inRetry = true; - DPRINTF(Bus, "Sending a retry\n"); + DPRINTF(Bus, "Sending a retry to %s\n", retryList.front()->getPeer()->name()); retryList.front()->sendRetry(); // If inRetry is still true, sendTiming wasn't called if (inRetry) @@ -267,18 +272,20 @@ Bus::recvRetry(int id) retryList.pop_front(); inRetry = false; - //Bring tickNextIdle up to the present - while (tickNextIdle < curTick) - tickNextIdle += clock; + if (id != -1) { + //Bring tickNextIdle up to the present + while (tickNextIdle < curTick) + tickNextIdle += clock; - //Burn a cycle for the missed grant. - tickNextIdle += clock; + //Burn a cycle for the missed grant. + tickNextIdle += clock; - if (!busIdle.scheduled()) { - busIdle.schedule(tickNextIdle); - } else { - busIdle.reschedule(tickNextIdle); - } + if (!busIdle.scheduled()) { + busIdle.schedule(tickNextIdle); + } else { + busIdle.reschedule(tickNextIdle); + } + } // id != -1 } } //If we weren't able to drain before, we might be able to now. @@ -598,6 +605,37 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) } } +int +Bus::findBlockSize(int id) +{ + if (cachedBlockSizeValid) + return cachedBlockSize; + + int max_bs = -1, tmp_bs; + range_map<Addr,int>::iterator portIter; + std::vector<DevMap>::iterator snoopIter; + for (portIter = portMap.begin(); portIter != portMap.end(); portIter++) { + tmp_bs = interfaces[portIter->second]->peerBlockSize(); + if (tmp_bs > max_bs) + max_bs = tmp_bs; + } + for (snoopIter = portSnoopList.begin(); + snoopIter != portSnoopList.end(); snoopIter++) { + tmp_bs = interfaces[snoopIter->portId]->peerBlockSize(); + if (tmp_bs > max_bs) + max_bs = tmp_bs; + } + if (max_bs <= 0) + max_bs = defaultBlockSize; + + if (max_bs != 64) + warn_once("Blocksize found to not be 64... hmm... probably not.\n"); + cachedBlockSize = max_bs; + cachedBlockSizeValid = true; + return max_bs; +} + + unsigned int Bus::drain(Event * de) { @@ -618,6 +656,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus) Param<int> clock; Param<int> width; Param<bool> responder_set; + Param<int> block_size; END_DECLARE_SIM_OBJECT_PARAMS(Bus) @@ -625,12 +664,14 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Bus) INIT_PARAM(bus_id, "a globally unique bus id"), INIT_PARAM(clock, "bus clock speed"), INIT_PARAM(width, "width of the bus (bits)"), - INIT_PARAM(responder_set, "Is a default responder set by the user") + INIT_PARAM(responder_set, "Is a default responder set by the user"), + INIT_PARAM(block_size, "Default blocksize if no device has one") END_INIT_SIM_OBJECT_PARAMS(Bus) CREATE_SIM_OBJECT(Bus) { - return new Bus(getInstanceName(), bus_id, clock, width, responder_set); + return new Bus(getInstanceName(), bus_id, clock, width, responder_set, + block_size); } REGISTER_SIM_OBJECT("Bus", Bus) diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 0dd7547c5..f0dc67b12 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -133,6 +133,12 @@ class Bus : public MemObject /** Occupy the bus with transmitting the packet pkt */ void occupyBus(PacketPtr pkt); + /** Ask everyone on the bus what their size is + * @param id id of the busport that made the request + * @return the max of all the sizes + */ + int findBlockSize(int id); + /** Declaration of the buses port type, one will be instantiated for each of the interfaces connecting to the bus. */ class BusPort : public Port @@ -195,8 +201,11 @@ class Bus : public MemObject AddrRangeList &snoop) { bus->addressRanges(resp, snoop, id); } - // Hack to make translating port work without changes - virtual int deviceBlockSize() { return 32; } + // Ask the bus to ask everyone on the bus what their block size is and + // take the max of it. This might need to be changed a bit if we ever + // support multiple block sizes. + virtual int deviceBlockSize() + { return bus->findBlockSize(id); } }; @@ -256,6 +265,10 @@ class Bus : public MemObject /** Has the user specified their own default responder? */ bool responderSet; + int defaultBlockSize; + int cachedBlockSize; + bool cachedBlockSizeValid; + public: /** A function used to return the port associated with this bus object. */ @@ -267,11 +280,12 @@ class Bus : public MemObject unsigned int drain(Event *de); Bus(const std::string &n, int bus_id, int _clock, int _width, - bool responder_set) + bool responder_set, int dflt_blk_size) : MemObject(n), busId(bus_id), clock(_clock), width(_width), tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false), maxId(0), defaultPort(NULL), funcPort(NULL), funcPortId(-4), - responderSet(responder_set) + responderSet(responder_set), defaultBlockSize(dflt_blk_size), + cachedBlockSize(0), cachedBlockSizeValid(false) { //Both the width and clock period must be positive if (width <= 0) diff --git a/src/mem/packet.cc b/src/mem/packet.cc index 14d08db1b..2463a19ba 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -85,7 +85,7 @@ MemCmd::commandInfo[] = { SET5(IsWrite, IsInvalidate, IsRequest, HasData, NeedsResponse), WriteInvalidateResp, "WriteInvalidateReq" }, /* WriteInvalidateResp */ - { SET5(IsWrite, IsInvalidate, IsRequest, NeedsResponse, IsResponse), + { SET3(IsWrite, IsInvalidate, IsResponse), InvalidCmd, "WriteInvalidateResp" }, /* UpgradeReq */ { SET3(IsInvalidate, IsRequest, IsUpgrade), InvalidCmd, "UpgradeReq" }, diff --git a/src/mem/port.hh b/src/mem/port.hh index 6296b42ca..877e00293 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -161,10 +161,10 @@ class Port /** Called by a peer port in order to determine the block size of the device connected to this port. It sometimes doesn't make sense for - this function to be called, a DMA interface doesn't really have a - block size, so it is defaulted to a panic. + this function to be called, so it just returns 0. Anytthing that is + concerned with the size should just ignore that. */ - virtual int deviceBlockSize() { panic("??"); M5_DUMMY_RETURN } + virtual int deviceBlockSize() { return 0; } /** The peer port is requesting us to reply with a list of the ranges we are responsible for. diff --git a/src/python/m5/objects/Bridge.py b/src/python/m5/objects/Bridge.py index ee8e76bff..e123c2891 100644 --- a/src/python/m5/objects/Bridge.py +++ b/src/python/m5/objects/Bridge.py @@ -9,3 +9,5 @@ class Bridge(MemObject): queue_size_b = Param.Int(16, "The number of requests to buffer") delay = Param.Latency('0ns', "The latency of this bridge") write_ack = Param.Bool(False, "Should this bridge ack writes") + fix_partial_write_a = Param.Bool(False, "Should this bridge fixup partial block writes") + fix_partial_write_b = Param.Bool(False, "Should this bridge fixup partial block writes") diff --git a/src/python/m5/objects/Bus.py b/src/python/m5/objects/Bus.py index 8226fe8d2..48dbbe307 100644 --- a/src/python/m5/objects/Bus.py +++ b/src/python/m5/objects/Bus.py @@ -11,6 +11,7 @@ class Bus(MemObject): clock = Param.Clock("1GHz", "bus clock speed") width = Param.Int(64, "bus width (bytes)") responder_set = Param.Bool(False, "Did the user specify a default responder.") + block_size = Param.Int(64, "The default block size if one isn't set by a device attached to the bus.") if build_env['FULL_SYSTEM']: responder = BadAddr(pio_addr=0x0, pio_latency="1ps") default = Port(Self.responder.pio, "Default port for requests that aren't handled by a device.") |