add a bridge object, modify bus object to be able to connect to other buses or bridge...
authorAli Saidi <saidi@eecs.umich.edu>
Fri, 28 Apr 2006 19:37:48 +0000 (15:37 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Fri, 28 Apr 2006 19:37:48 +0000 (15:37 -0400)
SConscript:
    add new cc files to scons
mem/bus.cc:
mem/bus.hh:
    implement addressRanges() on the bus.
    propigate address ranges to anyone who is interested stripping out ranges of who your propigating to (to avoid livelock)
mem/packet.hh:
    add intersect function that returns true if two packets touch at least one byte of the same data (for functional access)
    add fixPacket() that will eventually take the correct action giving a timing and functional packet, right now it panics
mem/physical.cc:
    Don't panic if the physical memory recieves a status change, just ignore.

--HG--
extra : convert_revision : d470d51f2fb1db2700ad271e09792315ef33ba01

SConscript
mem/bridge.cc [new file with mode: 0644]
mem/bridge.hh [new file with mode: 0644]
mem/bus.cc
mem/bus.hh
mem/packet.cc [new file with mode: 0644]
mem/packet.hh
mem/physical.cc
python/m5/objects/Bridge.py [new file with mode: 0644]

index cac083b6b2470e0700a7ccf244594f4a15f3ff84..d49bee5e423b9626543d05c3e41e3f501dc89018 100644 (file)
@@ -87,13 +87,15 @@ base_sources = Split('''
        cpu/pc_event.cc
        cpu/static_inst.cc
         cpu/sampler/sampler.cc
-
-        mem/request.cc
+    
+        mem/bridge.cc
+        mem/bus.cc
         mem/connector.cc
         mem/mem_object.cc
+        mem/packet.cc
         mem/physical.cc
         mem/port.cc
-        mem/bus.cc
+        mem/request.cc
 
         python/pyconfig.cc
         python/embedded_py.cc
diff --git a/mem/bridge.cc b/mem/bridge.cc
new file mode 100644 (file)
index 0000000..d358ef7
--- /dev/null
@@ -0,0 +1,263 @@
+
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file Definition of a simple bus bridge without buffering.
+ */
+
+
+#include "base/trace.hh"
+#include "mem/bridge.hh"
+#include "sim/builder.hh"
+
+void
+Bridge::init()
+{
+    // Make sure that both sides are connected to.
+    if (sideA == NULL || sideB == NULL)
+        panic("Both ports of bus bridge are not connected to a bus.\n");
+}
+
+
+/** Function called by the port when the bus is recieving a Timing
+ * transaction.*/
+bool
+Bridge::recvTiming(Packet &pkt, Side id)
+{
+    if (blockedA && id == SideA)
+        return false;
+    if (blockedB && id == SideB)
+        return false;
+
+    if (delay) {
+        if (!sendEvent.scheduled())
+            sendEvent.schedule(curTick + delay);
+        if (id == SideA) {
+            inboundA.push_back(std::make_pair<Packet*, Tick>(&pkt, curTick));
+            blockCheck(SideA);
+        } else {
+            inboundB.push_back(std::make_pair<Packet*, Tick>(&pkt, curTick));
+            blockCheck(SideB);
+        }
+    } else {
+        if (id == SideB) {
+            sideA->sendPkt(pkt);
+            blockCheck(SideB);
+        } else {
+            sideB->sendPkt(pkt);
+            blockCheck(SideA);
+        }
+    }
+    return true;
+
+}
+
+void
+Bridge::blockCheck(Side id)
+{
+    /* Check that we still have buffer space available. */
+    if (id == SideB) {
+        if (sideA->numQueued() + inboundB.size() >= queueSizeA && !blockedB) {
+            sideB->sendStatusChange(Port::Blocked);
+            blockedB = true;
+        } else if (sideA->numQueued() + inboundB.size() < queueSizeA && blockedB) {
+            sideB->sendStatusChange(Port::Unblocked);
+            blockedB = false;
+        }
+    } else {
+        if (sideB->numQueued() + inboundA.size() >= queueSizeB && !blockedA) {
+            sideA->sendStatusChange(Port::Blocked);
+            blockedA = true;
+        } else if (sideB->numQueued() + inboundA.size() < queueSizeB && blockedA) {
+            sideA->sendStatusChange(Port::Unblocked);
+            blockedA = false;
+        }
+    }
+}
+
+void Bridge::timerEvent()
+{
+    Tick t = 0;
+
+    assert(inboundA.size() || inboundB.size());
+    if (inboundA.size()) {
+        while (inboundA.front().second <= curTick + delay){
+            sideB->sendPkt(inboundA.front());
+            inboundA.pop_front();
+        }
+        if (inboundA.size())
+            t = inboundA.front().second + delay;
+    }
+    if (inboundB.size()) {
+        while (inboundB.front().second <= curTick + delay){
+            sideB->sendPkt(inboundA.front());
+            inboundB.pop_front();
+        }
+        if (inboundB.size())
+            if (t == 0)
+               t = inboundB.front().second + delay;
+            else
+               t = std::min(t,inboundB.front().second + delay);
+    } else {
+        panic("timerEvent() called but nothing to do?");
+    }
+
+    if (t != 0)
+        sendEvent.schedule(t);
+}
+
+
+void
+Bridge::BridgePort::sendPkt(Packet &pkt)
+{
+    if (!sendTiming(pkt))
+        outbound.push_back(std::make_pair<Packet*,Tick>(&pkt, curTick));
+}
+
+void
+Bridge::BridgePort::sendPkt(std::pair<Packet*, Tick> p)
+{
+    if (!sendTiming(*p.first))
+        outbound.push_back(p);
+}
+
+
+Packet *
+Bridge::BridgePort::recvRetry()
+{
+    Packet *pkt;
+    assert(outbound.size() > 0);
+    assert(outbound.front().second >= curTick + bridge->delay);
+    pkt = outbound.front().first;
+    outbound.pop_front();
+    bridge->blockCheck(side);
+    return pkt;
+}
+
+/** Function called by the port when the bus is recieving a Atomic
+ * transaction.*/
+Tick
+Bridge::recvAtomic(Packet &pkt, Side id)
+{
+    pkt.time += delay;
+
+    if (id == SideA)
+        return sideB->sendAtomic(pkt);
+    else
+        return sideA->sendAtomic(pkt);
+}
+
+/** Function called by the port when the bus is recieving a Functional
+ * transaction.*/
+void
+Bridge::recvFunctional(Packet &pkt, Side id)
+{
+    pkt.time += delay;
+    std::list<std::pair<Packet*, Tick> >::iterator i;
+    bool pktContinue = true;
+
+    for(i = inboundA.begin();  i != inboundA.end(); ++i) {
+        if (pkt.intersect(i->first)) {
+            pktContinue &= fixPacket(pkt, *i->first);
+        }
+    }
+
+    for(i = inboundB.begin();  i != inboundB.end(); ++i) {
+        if (pkt.intersect(i->first)) {
+            pktContinue &= fixPacket(pkt, *i->first);
+        }
+    }
+
+    for(i = sideA->outbound.begin();  i != sideA->outbound.end(); ++i) {
+        if (pkt.intersect(i->first)) {
+            pktContinue &= fixPacket(pkt, *i->first);
+        }
+    }
+
+    for(i = sideB->outbound.begin();  i != sideB->outbound.end(); ++i) {
+        if (pkt.intersect(i->first)) {
+            pktContinue &= fixPacket(pkt, *i->first);
+        }
+    }
+
+    if (pktContinue) {
+        if (id == SideA)
+            sideB->sendFunctional(pkt);
+        else
+            sideA->sendFunctional(pkt);
+    }
+}
+
+/** Function called by the port when the bus is recieving a status change.*/
+void
+Bridge::recvStatusChange(Port::Status status, Side id)
+{
+    if (status == Port::Blocked || status == Port::Unblocked)
+        return ;
+
+    if (id == SideA)
+        sideB->sendStatusChange(status);
+    else
+        sideA->sendStatusChange(status);
+}
+
+void
+Bridge::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id)
+{
+    if (id == SideA)
+        sideB->getPeerAddressRanges(resp, snoop);
+    else
+        sideA->getPeerAddressRanges(resp, snoop);
+}
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge)
+
+   Param<int> queue_size_a;
+   Param<int> queue_size_b;
+   Param<Tick> delay;
+   Param<bool> write_ack;
+
+END_DECLARE_SIM_OBJECT_PARAMS(Bridge)
+
+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.")
+
+END_INIT_SIM_OBJECT_PARAMS(Bridge)
+
+CREATE_SIM_OBJECT(Bridge)
+{
+    return new Bridge(getInstanceName(), queue_size_a, queue_size_b, delay,
+            write_ack);
+}
+
+REGISTER_SIM_OBJECT("Bridge", Bridge)
diff --git a/mem/bridge.hh b/mem/bridge.hh
new file mode 100644 (file)
index 0000000..6bd4d81
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file Decleration of a simple bus bridge object with no buffering
+ */
+
+#ifndef __MEM_BRIDGE_HH__
+#define __MEM_BRIDGE_HH__
+
+#include <string>
+#include <list>
+#include <inttypes.h>
+#include <queue>
+
+
+#include "mem/mem_object.hh"
+#include "mem/packet.hh"
+#include "mem/port.hh"
+#include "sim/eventq.hh"
+
+class Bridge : public MemObject
+{
+  public:
+    enum Side
+    {
+        SideA,
+        SideB
+    };
+
+  protected:
+    /** Function called by the port when the bus is recieving a Timing
+        transaction.*/
+    bool recvTiming(Packet &pkt, Side id);
+
+    /** Function called by the port when the bus is recieving a Atomic
+        transaction.*/
+    Tick recvAtomic(Packet &pkt, Side id);
+
+    /** Function called by the port when the bus is recieving a Functional
+        transaction.*/
+    void recvFunctional(Packet &pkt, Side id);
+
+    /** Function called by the port when the bus is recieving a status change.*/
+    void recvStatusChange(Port::Status status, Side id);
+
+    /** Process address range request.
+     * @param resp addresses that we can respond to
+     * @param snoop addresses that we would like to snoop
+     * @param id ide of the busport that made the request.
+     */
+    void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id);
+
+
+    /** Event that the SendEvent calls when it fires. This code must reschedule
+     * the send event as required. */
+    void timerEvent();
+
+    /** Decleration of the buses port type, one will be instantiated for each
+        of the interfaces connecting to the bus. */
+    class BridgePort : public Port
+    {
+        /** A pointer to the bus to which this port belongs. */
+        Bridge *bridge;
+
+        /** A id to keep track of the intercafe ID this port is connected to. */
+        Bridge::Side side;
+
+      public:
+
+        /** Constructor for the BusPort.*/
+        BridgePort(Bridge *_bridge, Side _side)
+            : bridge(_bridge), side(_side)
+        { }
+
+        int numQueued() { return outbound.size(); }
+
+      protected:
+        /** Data this is waiting to be transmitted. */
+        std::list<std::pair<Packet*, Tick> > outbound;
+
+        void sendPkt(Packet &pkt);
+        void sendPkt(std::pair<Packet*, Tick> p);
+
+        /** When reciving a timing request from the peer port,
+            pass it to the bridge. */
+        virtual bool recvTiming(Packet &pkt)
+        { return bridge->recvTiming(pkt, side); }
+
+        /** When reciving a retry request from the peer port,
+            pass it to the bridge. */
+        virtual Packet* recvRetry();
+
+        /** When reciving a Atomic requestfrom the peer port,
+            pass it to the bridge. */
+        virtual Tick recvAtomic(Packet &pkt)
+        { return bridge->recvAtomic(pkt, side); }
+
+        /** When reciving a Functional request from the peer port,
+            pass it to the bridge. */
+        virtual void recvFunctional(Packet &pkt)
+        { bridge->recvFunctional(pkt, side); }
+
+        /** When reciving a status changefrom the peer port,
+            pass it to the bridge. */
+        virtual void recvStatusChange(Status status)
+        { bridge->recvStatusChange(status, side); }
+
+        /** When reciving a address range request the peer port,
+            pass it to the bridge. */
+        virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
+        { bridge->addressRanges(resp, snoop, side); }
+
+        friend class Bridge;
+    };
+
+    class SendEvent : public Event
+    {
+        Bridge *bridge;
+
+        SendEvent(Bridge *b)
+            : Event(&mainEventQueue), bridge(b) {}
+
+        virtual void process() { bridge->timerEvent(); }
+
+        virtual const char *description() { return "bridge delay event"; }
+        friend class Bridge;
+    };
+
+    SendEvent sendEvent;
+
+    /** Sides of the bus bridges. */
+    BridgePort* sideA;
+    BridgePort* sideB;
+
+    /** inbound queues on both sides. */
+    std::list<std::pair<Packet*, Tick> > inboundA;
+    std::list<std::pair<Packet*, Tick> > inboundB;
+
+    /** The size of the queue for data coming into side a */
+    int queueSizeA;
+    int queueSizeB;
+
+    /* if the side is blocked or not. */
+    bool blockedA;
+    bool blockedB;
+
+    /** Miminum delay though this bridge. */
+    Tick delay;
+
+    /** If this bridge should acknowledge writes. */
+    bool ackWrites;
+
+  public:
+
+    /** A function used to return the port associated with this bus object. */
+    virtual Port *getPort(const std::string &if_name)
+    {
+        if (if_name == "side_a") {
+            if (sideA != NULL)
+                panic("bridge side a already connected to.");
+            sideA = new BridgePort(this, SideA);
+            return sideA;
+        } else if (if_name == "side_b") {
+            if (sideB != NULL)
+                panic("bridge side b already connected to.");
+            sideB = new BridgePort(this, SideB);
+            return sideB;
+        } else
+            return NULL;
+    }
+
+    virtual void init();
+
+    Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack)
+        : MemObject(n), sendEvent(this), sideA(NULL), sideB(NULL),
+          queueSizeA(qsa), queueSizeB(qsb), blockedA(false), blockedB(false),
+          delay(_delay), ackWrites(write_ack)
+          {}
+
+    /** Check if the port should block/unblock after recieving/sending a packet.
+     * */
+    void blockCheck(Side id);
+
+    friend class Bridge::SendEvent;
+
+};
+
+#endif //__MEM_BUS_HH__
index 86e834894f214279dbd1a637d1e9c2891386f6b3..acc9414345cece4655e95431be3f16cee939d81c 100644 (file)
 #include "mem/bus.hh"
 #include "sim/builder.hh"
 
+/** Get the ranges of anyone that we are connected to. */
+void
+Bus::init()
+{
+    std::vector<Port*>::iterator intIter;
+    for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
+        (*intIter)->sendStatusChange(Port::RangeChange);
+}
+
+
 /** Function called by the port when the bus is recieving a Timing
  * transaction.*/
 bool
 Bus::recvTiming(Packet &pkt, int id)
 {
-
-    panic("I need to be implemented, but not right now.");
+    return findPort(pkt.addr, id)->sendTiming(pkt);
 }
 
 Port *
@@ -90,10 +99,13 @@ Bus::recvFunctional(Packet &pkt, int id)
 void
 Bus::recvStatusChange(Port::Status status, int id)
 {
+    DPRINTF(Bus, "Bus %d recieved status change from device id %d\n",
+            busId, id);
     assert(status == Port::RangeChange &&
            "The other statuses need to be implemented.");
 
     assert(id < interfaces.size() && id >= 0);
+    int x;
     Port *port = interfaces[id];
     AddrRangeList ranges;
     AddrRangeList snoops;
@@ -122,12 +134,31 @@ Bus::recvStatusChange(Port::Status status, int id)
         portList.push_back(dm);
     }
     DPRINTF(MMU, "port list has %d entries\n", portList.size());
+
+    // tell all our peers that our address range has changed.
+    // Don't tell the device that caused this change, it already knows
+    for (x = 0; x < interfaces.size(); x++)
+        if (x != id)
+            interfaces[x]->sendStatusChange(Port::RangeChange);
 }
 
 void
-Bus::BusPort::addressRanges(AddrRangeList &resp, AddrRangeList &snoop)
+Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
 {
-    panic("I'm not implemented.\n");
+    std::vector<DevMap>::iterator portIter;
+
+    resp.clear();
+    snoop.clear();
+
+    DPRINTF(Bus, "Bus id %d recieved address range request returning\n",
+            busId);
+    for (portIter = portList.begin(); portIter != portList.end(); portIter++) {
+        if (portIter->portId != id) {
+            resp.push_back(portIter->range);
+            DPRINTF(Bus, "-- %#llX : %#llX\n", portIter->range.start,
+                    portIter->range.end);
+        }
+    }
 }
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)
@@ -137,12 +168,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)
 END_DECLARE_SIM_OBJECT_PARAMS(Bus)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(Bus)
-    INIT_PARAM(bus_id, "junk bus id")
-END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
+    INIT_PARAM(bus_id, "a globally unique bus id")
+END_INIT_SIM_OBJECT_PARAMS(Bus)
 
 CREATE_SIM_OBJECT(Bus)
 {
-    return new Bus(getInstanceName());
+    return new Bus(getInstanceName(), bus_id);
 }
 
 REGISTER_SIM_OBJECT("Bus", Bus)
index fad44aba5f710d90258ae75becc964b17cdfc416..de9259a908a4607f80ccdac3ce86b0a043993062 100644 (file)
@@ -45,6 +45,9 @@
 
 class Bus : public MemObject
 {
+    /** a globally unique id for this bus. */
+    int busId;
+
     struct DevMap {
         int portId;
         Range<Addr> range;
@@ -77,6 +80,14 @@ class Bus : public MemObject
     Port *
     Bus::findPort(Addr addr, int id);
 
+    /** Process address range request.
+     * @param resp addresses that we can respond to
+     * @param snoop addresses that we would like to snoop
+     * @param id ide of the busport that made the request.
+     */
+    void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id);
+
+
     /** Decleration of the buses port type, one will be instantiated for each
         of the interfaces connecting to the bus. */
     class BusPort : public Port
@@ -120,7 +131,8 @@ class Bus : public MemObject
         // downstream from this bus, yes?  That is, the union of all
         // the 'owned' address ranges of all the other interfaces on
         // this bus...
-        virtual void addressRanges(AddrRangeList &resp, AddrRangeList &snoop);
+        virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
+        { bus->addressRanges(resp, snoop, id); }
 
         // Hack to make translating port work without changes
         virtual int deviceBlockSize() { return 32; }
@@ -141,8 +153,11 @@ class Bus : public MemObject
         interfaces.push_back(new BusPort(this, id));
         return interfaces.back();
     }
-    Bus(const std::string &n)
-        : MemObject(n)  {}
+
+    virtual void init();
+
+    Bus(const std::string &n, int bus_id)
+        : MemObject(n), busId(bus_id)  {}
 
 };
 
diff --git a/mem/packet.cc b/mem/packet.cc
new file mode 100644 (file)
index 0000000..590617f
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * Definition of the Packet Class, a packet is a transaction occuring
+ * between a single level of the memory heirarchy (ie L1->L2).
+ */
+#include "mem/packet.hh"
+
+bool fixPacket(Packet &func, Packet &timing)
+{ panic("Need to implement!"); }
index 4329094d58dd3fb8a8d9e5bbc53bf2a6976876ef..a5bd6bc597588c899680f4dfcedd48e2b396a27b 100644 (file)
@@ -142,7 +142,7 @@ struct Packet
 
     Packet()
         :  data(NULL), staticData(false), dynamicData(false), arrayData(false),
-           result(Unknown)
+           time(curTick), result(Unknown)
         {}
 
     ~Packet()
@@ -156,6 +156,7 @@ struct Packet
            deleteData();
            dynamicData = false;
            arrayData = false;
+           time = curTick;
         }
     }
 
@@ -231,6 +232,21 @@ struct Packet
         arrayData = true;
         data = new uint8_t[size];
     }
+
+    /** Do the packet modify the same addresses. */
+    bool intersect(Packet *p) {
+        Addr s1 = addr;
+        Addr e1 = addr + size;
+        Addr s2 = p->addr;
+        Addr e2 = p->addr + p->size;
+
+        if (s1 >= s2 && s1 < e2)
+            return true;
+        if (e1 >= s2 && e1 < e2)
+            return true;
+        return false;
+    }
 };
 
+bool fixPacket(Packet &func, Packet &timing);
 #endif //__MEM_PACKET_HH
index 02a48b22bab94598d46332e2c3320e943095738b..fd304e63b02d2b13d24660ddfaebc667efb3e57a 100644 (file)
@@ -181,7 +181,6 @@ PhysicalMemory::getPort(const std::string &if_name)
 void
 PhysicalMemory::recvStatusChange(Port::Status status)
 {
-    panic("??");
 }
 
 PhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory)
diff --git a/python/m5/objects/Bridge.py b/python/m5/objects/Bridge.py
new file mode 100644 (file)
index 0000000..ada715c
--- /dev/null
@@ -0,0 +1,9 @@
+from m5 import *
+from MemObject import MemObject
+
+class Bridge(MemObject):
+    type = 'Bridge'
+    queue_size_a = Param.Int(16, "The number of requests to buffer")
+    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")